legatt 32f4597c4d Base frontend module
- Naming style migrated to camel-case
- P7lib logger sources added
- Vcpkg manifest, CMake presets and build moved to root
- SDL2, Vulkan and RmlUi dependencies added
- Logger LOG macro added
- Logger  configuration
- SDL2 window configuration
- Vulkan configuration
- RmlUi configuration
- SDL event loop
2025-08-08 00:07:32 +03:00

422 lines
12 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// /
// 2012-2020 (c) Baical /
// /
// This library is free software; you can redistribute it and/or /
// modify it under the terms of the GNU Lesser General Public /
// License as published by the Free Software Foundation; either /
// version 3.0 of the License, or (at your option) any later version. /
// /
// This library is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU /
// Lesser General Public License for more details. /
// /
// You should have received a copy of the GNU Lesser General Public /
// License along with this library. /
// /
////////////////////////////////////////////////////////////////////////////////
#pragma once
#define PR_USE_REGEXP
#if defined(PR_USE_REGEXP)
#pragma warning(disable : 4995 )
#include <QRegExp>
#include <QString>
#endif
////////////////////////////////////////////////////////////////////////////////
enum ePr_VType
{
EPR_VTYPE_UNK = -1,
EPR_VTYPE_INT = 0,
EPR_VTYPE_FLOAT ,
EPR_VTYPE_DATE ,
EPR_VTYPE_WTEXT ,
EPR_VTYPE_ENUM //user enumes +1, +2, +3, ... etc
};
////////////////////////////////////////////////////////////////////////////////
enum ePr_Op
{
EPR_OP_UNK = -1, //
EPR_OP_EQUAL = 0, //=
EPR_OP_NOT_EQUAL , //!=
EPR_OP_GREATER , //>
EPR_OP_GREATER_OR_EQUAL , //>=
EPR_OP_LESS , //<
EPR_OP_LESS_OR_EQUAL , //<=
EPR_OP_LEFT_INCLUDE , //<<
EPR_OP_RIGHT_INCLUDE , //>>
EPR_OP_LEFT_NOT_INCLUDE , //<!
EPR_OP_RIGHT_NOT_INCLUDE , //!>
#if defined(PR_USE_REGEXP)
EPR_OP_REG_EXP , //r=
EPR_OP_WILD_CARD //w=
#endif
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_Op_Text
{
const tXCHAR *pText;
tUINT32 dwLen;
ePr_Op eType;
ePr_Op eRevers;
tBOOL bDigit;
};
static const sPr_Op_Text g_pOperators[] =
{
{ TM("<="), 2, EPR_OP_LESS_OR_EQUAL, EPR_OP_GREATER_OR_EQUAL, TRUE },
{ TM("<<"), 2, EPR_OP_LEFT_INCLUDE, EPR_OP_RIGHT_INCLUDE, FALSE},
{ TM(">>"), 2, EPR_OP_RIGHT_INCLUDE, EPR_OP_LEFT_INCLUDE, FALSE},
{ TM("<!"), 2, EPR_OP_LEFT_NOT_INCLUDE, EPR_OP_RIGHT_NOT_INCLUDE, FALSE},
{ TM("!>"), 2, EPR_OP_RIGHT_NOT_INCLUDE,EPR_OP_LEFT_NOT_INCLUDE, FALSE},
{ TM("!="), 2, EPR_OP_NOT_EQUAL, EPR_OP_NOT_EQUAL, TRUE },
{ TM(">="), 2, EPR_OP_GREATER_OR_EQUAL, EPR_OP_LESS_OR_EQUAL, TRUE },
{ TM("="), 1, EPR_OP_EQUAL, EPR_OP_EQUAL, TRUE },
{ TM(">"), 1, EPR_OP_GREATER, EPR_OP_LESS, TRUE },
{ TM("<"), 1, EPR_OP_LESS, EPR_OP_GREATER, TRUE },
#if defined(PR_USE_REGEXP)
{ TM("r="), 2, EPR_OP_REG_EXP, EPR_OP_REG_EXP, FALSE},
{ TM("w="), 2, EPR_OP_WILD_CARD, EPR_OP_WILD_CARD, FALSE},
#endif
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_Var
{
tXCHAR *m_pName;
ePr_VType m_eType;
tUINT32 m_dwLength; //length of the text if it is
tBOOL m_bUsed;
union
{
tXCHAR *m_pValue;
tUINT64 m_qwValue;
double m_dbValue;
};
sPr_Var(tXCHAR *i_pName, ePr_VType i_eType)
: m_pName(NULL)
, m_eType(i_eType)
, m_dwLength(0)
, m_bUsed(FALSE)
, m_qwValue(0) //the largest value in union
{
tUINT32 l_dwLen = (i_pName) ? PStrLen(i_pName) : 0;
if (l_dwLen)
{
m_pName = new tXCHAR[l_dwLen + 1];
if (m_pName)
{
PStrCpy(m_pName, l_dwLen + 1, i_pName);
}
}
}
~sPr_Var()
{
if (m_pName)
{
delete [] m_pName;
m_pName = NULL;
}
}
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_Enum_Item
{
tXCHAR *m_pName;
int m_iValue;
sPr_Enum_Item(tXCHAR *i_pName, int i_iValue)
: m_pName(NULL)
, m_iValue(i_iValue)
{
tUINT32 l_dwLen = (i_pName) ? PStrLen(i_pName) : 0;
if (l_dwLen)
{
m_pName = new tXCHAR[l_dwLen + 1];
if (m_pName)
{
PStrCpy(m_pName, l_dwLen + 1, i_pName);
}
}
}
~sPr_Enum_Item()
{
if (m_pName)
{
delete [] m_pName;
m_pName = NULL;
}
}
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_Enum
{
tUINT32 m_dwID;
CBList<sPr_Enum_Item*> m_cItems;
sPr_Enum(tUINT32 i_dwID) : m_dwID(i_dwID) {}
~sPr_Enum()
{
m_cItems.Clear(TRUE);
}
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_Group;
struct sPr_Node
{
union
{
sPr_Group *m_pGroup;
tXCHAR *m_pValue;
tUINT64 m_qwValue;
double m_dbValue;
};
tBOOL m_bLink; //if TRUE we use m_pGroup, otherwise - values
ePr_Op m_eOperator;
tUINT32 m_dwLength; //length of the text if it is
sPr_Var *m_pVariable;
#if defined(PR_USE_REGEXP)
QRegExp *m_pRE;
#endif
sPr_Node();
~sPr_Node();
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_OrGroup
{
CBList<sPr_Node*> m_cNodes;
~sPr_OrGroup()
{
m_cNodes.Clear(TRUE);
}
};
////////////////////////////////////////////////////////////////////////////////
struct sPr_Group
{
CBList<sPr_OrGroup*> m_cOrGroups;
~sPr_Group()
{
m_cOrGroups.Clear(TRUE);
}
};
////////////////////////////////////////////////////////////////////////////////
//Normal class usage
//1. Create child class with yours structure
//2. Implement abstract function Set_Data()
//3. Set variables list using Set_Variables()
//4. If you are using enums - use Set_Enum()
//5. Set predicate string - Set_Predicate()
//6. Use Compare() to compare you structure using predicate
//
//See usage example at the end of this header file
class CPredicate
{
protected:
tXCHAR *m_pPr;
tUINT32 m_dwPr_Max;
tUINT32 m_dwPr_Len;
CBList<sPr_Var*> m_cVars;
CBList<sPr_Enum*> m_cEnums;
sPr_Group m_cGroup;
tXCHAR m_cError[512];
public:
CPredicate();
virtual ~CPredicate();
////////////////////////////////////////////////////////////////////////////
//Predicate (i_pPr) consist of next part
//Variables - %MyVariable%
//Constants - "0x20" possible values Int, Float, Date, String, Enum. Date
// has simple format "DD.MM.YYYY HH:MM:SS.MS"
//Atoms - atom is working block, you compare variable and constant. It
// is not possible to compare 2 variables, only variable and
// constant, next operators are available: "<=", "<<", ">>", "<!"
// "!>", "!=", ">=", "=", ">", "<". Operators "<<", ">>" used
// only for text ("T1 << T2" - T1 contains T2)
//Grouping - "(" and ")"
//Operators - "&", "|"
//Examples:
//$Var1$ >="0x10" & "Text" >> $Var2$
//$Var1$ >="500" & ("Text" >> $Var2$ | "Text1" >> $Var2$)
virtual tBOOL Set_Predicate(const tXCHAR *i_pPr);
tXCHAR *Get_Error();
////////////////////////////////////////////////////////////////////////////
//Set_Variables()
// i_dwCount - count of the variables, each variable has 2 values
// tXCHAR - name of the variable, allowed any characters
// ePr_VType - type of the variable
// ... - variables (2 value: name & type)
tBOOL Set_Variables(tUINT32 i_dwCount, ...);
////////////////////////////////////////////////////////////////////////////
//Set_Enum()
// i_dwEnum_ID - ID of the enum, EPR_VTYPE_ENUM, EPR_VTYPE_ENUM + 1, ... etc
// i_dwCount - count of the enum values. Each value has 2 fields
// tXCHAR - text value representation
// int - int value representation
// ... - enum values (2 fields: text & int)
tBOOL Set_Enum(tUINT32 i_dwEnum_ID, tUINT32 i_dwCount, ...);
tBOOL Check(const void *i_pData);
protected:
tBOOL Check(sPr_Group *i_pGroup);
tBOOL Build(sPr_Group *i_pGroup, tUINT32 *io_pOffset);
tBOOL Add_Node(CBList<sPr_Node*> *i_pNodes, tUINT32 *io_pOffset);
tBOOL Fill_Node(sPr_Node *i_pNode,
tXCHAR *i_pVariable,
tXCHAR *i_pConst
);
tBOOL Is_True(sPr_Node *i_pNode);
tBOOL Is_Sub(tXCHAR *i_pString,
tUINT32 i_dwLenght,
tXCHAR *i_pSearch,
tUINT32 i_dwSub_Len
);
//re-implement this function, you should get yours input structure and
//every field put to the m_cVars list.
virtual tBOOL Fill_Variables(const void *i_pData) = 0;
};
////////////////////////////////////////////////////////////////////////////////
// Predicate Example
////////////////////////////////////////////////////////////////////////////////
//
//
// enum eTest1
// {
// ETEST1_ENUM0 = 0,
// ETEST1_ENUM1 = 1,
// ETEST1_ENUM2 = 2,
// ETEST1_ENUM3 = 3
// };
//
// struct sTest1
// {
// tUINT32 m_dwInt;
// eTest1 m_eEnum;
// tXCHAR *m_pText;
// };
//
////////////////////////////////////////////////////////////////////////////////
// class CMy_Pred:
// public CPredicate
// {
// public:
// CMy_Pred():
// CPredicate()
// {
// Set_Variables(3,
// TM("Int"), EPR_VTYPE_INT, //Index = 0;
// TM("Enum"), EPR_VTYPE_ENUM + 0, //Index = 1;
// TM("Text"), EPR_VTYPE_WTEXT //Index = 2;
// );
//
// Set_Enum(EPR_VTYPE_ENUM + 0,
// 4,
// TM("ENUM0"), 0, //ETEST1_ENUM0 = 0,
// TM("ENUM1"), 1, //ETEST1_ENUM1 = 1,
// TM("ENUM2"), 2, //ETEST1_ENUM2 = 2,
// TM("ENUM3"), 3 //ETEST1_ENUM3 = 3
// );
// }
//
// protected:
// BOOL Fill_Variables(void *i_pData)
// {
// sPr_Var *l_pVar = m_cVars[0];//Index = 0, first declared variable "Int"
// if (l_pVar->m_bUsed)
// {
// l_pVar->m_qwValue = ((sTest1*)i_pData)->m_dwInt;
// }
//
// l_pVar = m_cVars[1]; //Index = 1, second declared variable "Enum"
// if (l_pVar->m_bUsed)
// {
// l_pVar->m_qwValue = ((sTest1*)i_pData)->m_eEnum;
// }
//
// l_pVar = m_cVars[2]; //Index = 2, third declared variable "Text"
// if (l_pVar->m_bUsed)
// {
// l_pVar->m_pValue = ((sTest1*)i_pData)->m_pText;
//
// //Very important to set Text length !!!!
// if (l_pVar->m_pValue)
// {
// l_pVar->m_dwLength = PStrLen(l_pVar->m_pValue);
// }
// else
// {
// l_pVar->m_dwLength = 0;
// }
// }
// return TRUE;
// }
// };
//
////////////////////////////////////////////////////////////////////////////////
// int wmain(int i_iArgC, tXCHAR* i_pArgV[])
// {
// CMy_Pred l_cPred;
// sTest1 l_sTest = {10, ETEST1_ENUM2, TM("My Name")};
//
// if (FALSE == l_cPred.Set_Predicate(TM("$Enum$ <= \"ENUM2\" & ($Int$ >= \"0x9\" | $Text$ >> \"Andrey is My Name\")")))
// {
// wprintf(l_cPred.Get_Error());
// }
//
// if (l_cPred.Check(&l_sTest))
// {
// wprintf(TM("TRUE\n"));
// }
// else
// {
// wprintf(TM("FALSE\n"));
// }
//
// return 0;
// }