CHANGED: #1471 CInterfaceExpr, CInterfaceExprNode and related classes are now in NELGUI and under NLGUI namespace.
--HG-- branch : gui-refactoring
This commit is contained in:
parent
4284b5f4d5
commit
2db0a5d06e
39 changed files with 1607 additions and 1604 deletions
239
code/nel/include/nel/gui/interface_expr.h
Normal file
239
code/nel/include/nel/gui/interface_expr.h
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef CL_INTERFACE_EXPR_H
|
||||||
|
#define CL_INTERFACE_EXPR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "nel/misc/ucstring.h"
|
||||||
|
#include "nel/misc/rgba.h"
|
||||||
|
|
||||||
|
namespace NLMISC{
|
||||||
|
class ICDBNode;
|
||||||
|
class CCDBNodeLeaf;
|
||||||
|
class CCDBNodeBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CInterfaceExprUserType;
|
||||||
|
class CInterfaceExprNode;
|
||||||
|
|
||||||
|
/** a value that can be returned by a CInterfaceExpr instance
|
||||||
|
* It supports basic type;
|
||||||
|
* It can be extended by user defined types
|
||||||
|
*/
|
||||||
|
class CInterfaceExprValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum TType { Boolean = 0, Integer, Double, String, RGBA, UserType, NoType };
|
||||||
|
public:
|
||||||
|
// default ctor
|
||||||
|
CInterfaceExprValue() : _Type(NoType) {}
|
||||||
|
// copy ctor
|
||||||
|
CInterfaceExprValue(const CInterfaceExprValue &other);
|
||||||
|
// assignment operator
|
||||||
|
CInterfaceExprValue &operator = (const CInterfaceExprValue &other);
|
||||||
|
// dtor
|
||||||
|
~CInterfaceExprValue() { clean(); }
|
||||||
|
|
||||||
|
TType getType() const { return _Type; }
|
||||||
|
// get. Should be used only if the type is valid
|
||||||
|
bool getBool() const;
|
||||||
|
sint64 getInteger() const;
|
||||||
|
double getDouble() const;
|
||||||
|
std::string getString() const;
|
||||||
|
NLMISC::CRGBA getRGBA() const;
|
||||||
|
const ucstring &getUCString() const;
|
||||||
|
CInterfaceExprUserType *getUserType() const;
|
||||||
|
// set
|
||||||
|
void setBool(bool value) { clean(); _Type = Boolean; _BoolValue = value; }
|
||||||
|
void setInteger(sint64 value) { clean(); _Type = Integer; _IntegerValue = value; }
|
||||||
|
void setDouble(double value) { clean(); _Type = Double; _DoubleValue = value; }
|
||||||
|
void setString(const std::string &value) { clean(); _Type = String; _StringValue = value; }
|
||||||
|
void setUCString(const ucstring &value) { clean(); _Type = String; _StringValue = value; }
|
||||||
|
void setRGBA(NLMISC::CRGBA value) { clean(); _Type = RGBA; _RGBAValue = (uint32)(value.R+(value.G<<8)+(value.B<<16)+(value.A<<24)); }
|
||||||
|
void setUserType(CInterfaceExprUserType *value);
|
||||||
|
// reset this object to initial state (no type)
|
||||||
|
void clean();
|
||||||
|
// conversions. They return true if success
|
||||||
|
bool toBool();
|
||||||
|
bool toInteger();
|
||||||
|
bool toDouble();
|
||||||
|
bool toString();
|
||||||
|
bool toType(TType type);
|
||||||
|
bool toRGBA();
|
||||||
|
// test if the value if a bool, double, or integer
|
||||||
|
bool isNumerical() const;
|
||||||
|
/** evaluate a from a string
|
||||||
|
* \param expr : where to start the evaluation
|
||||||
|
* \return the position following the token, or NULL if the parsing failed
|
||||||
|
*/
|
||||||
|
const char *initFromString(const char *expr);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
private:
|
||||||
|
TType _Type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
bool _BoolValue;
|
||||||
|
sint64 _IntegerValue;
|
||||||
|
double _DoubleValue;
|
||||||
|
CInterfaceExprUserType *_UserTypeValue;
|
||||||
|
uint32 _RGBAValue;
|
||||||
|
};
|
||||||
|
ucstring _StringValue; // well, can't fit in union, unless we do some horrible hack..
|
||||||
|
private:
|
||||||
|
const char *evalBoolean(const char *expr);
|
||||||
|
const char *evalNumber(const char *expr);
|
||||||
|
const char *evalString(const char *expr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for user defined types that are use by the 'CInterfaceExprValue' class
|
||||||
|
* Derivers should include the 'clone' method
|
||||||
|
*
|
||||||
|
* CInterfaceExprValue instances have ownership of this object.
|
||||||
|
*
|
||||||
|
* \author Nicolas Vizerie
|
||||||
|
* \author Nevrax France
|
||||||
|
* \date 2003
|
||||||
|
*/
|
||||||
|
struct CInterfaceExprUserType
|
||||||
|
{
|
||||||
|
// cloning method
|
||||||
|
virtual CInterfaceExprUserType *clone() const = 0;
|
||||||
|
// dtor
|
||||||
|
virtual ~CInterfaceExprUserType() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Evaluate expressions used in interface.
|
||||||
|
* It can retrieve values from the database.
|
||||||
|
* It can also build a list of database values it depends of.
|
||||||
|
*
|
||||||
|
* An expression can be :
|
||||||
|
*
|
||||||
|
* - a string : 'toto', 'abcd', 'a\nbcd', 'a\\t', the escape sequences are the one of C
|
||||||
|
* - a integer 1, 2, 3
|
||||||
|
* - a double 1.1, 2.2
|
||||||
|
* - a database entry : @ui:interface:toto:truc. If the address is a leaf, it returns the leaf value and put an observer on it. If not a leaf, it returns 0, but put an observer on it.
|
||||||
|
* - a database indirection @db:value[db:index] is replaced by @db:value0 if db:index == 0 for example
|
||||||
|
* - a user function call : fct(expr0, epxr1, ...).
|
||||||
|
*
|
||||||
|
* NB : The lua language has been integrated since then (2005), and should be more suited
|
||||||
|
* for most of the tasks.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \author Nicolas Vizerie
|
||||||
|
* \author Nevrax France
|
||||||
|
* \date 2002
|
||||||
|
*/
|
||||||
|
class CInterfaceExpr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// list of argument for a function
|
||||||
|
typedef std::vector<CInterfaceExprValue> TArgList;
|
||||||
|
/** prototype of a user callable function
|
||||||
|
* It should return true if the result is meaningful. If not, the rest of the evaluation is stopped
|
||||||
|
*/
|
||||||
|
typedef bool (* TUserFct) (TArgList &args, CInterfaceExprValue &result);
|
||||||
|
public:
|
||||||
|
|
||||||
|
// release memory
|
||||||
|
static void release();
|
||||||
|
|
||||||
|
/** This try to eval the provided expression.
|
||||||
|
* - This returns a result
|
||||||
|
* - This eventually fill a vector with a set of database entries it has dependencies on
|
||||||
|
* \param expr The expression to evaluate
|
||||||
|
* \param result The result value
|
||||||
|
* \param nodes If not NULL, will be filled with the database nodes this expression depends on
|
||||||
|
* Node will only be inserted once, so we end up with a set of node (not ordered)
|
||||||
|
* \param noFctCalls when set to true, the terminal function calls will not be made, so the evaluation is only used to see which database entries the expression depends on.
|
||||||
|
*/
|
||||||
|
static bool eval(const std::string &expr, CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> *nodes = NULL, bool noFctCalls = false);
|
||||||
|
|
||||||
|
/** Build a tree from the given expression so that it can be evaluated quickly.
|
||||||
|
* This is useful for a fixed expression that must be evaluated often
|
||||||
|
*/
|
||||||
|
static CInterfaceExprNode *buildExprTree(const std::string &expr);
|
||||||
|
|
||||||
|
|
||||||
|
/** Register a function that can have several arguments
|
||||||
|
* // NB : this is case sensitive
|
||||||
|
*/
|
||||||
|
static void registerUserFct(const char *name, TUserFct fct);
|
||||||
|
// Simple evaluations
|
||||||
|
static bool evalAsInt(const std::string &expr, sint64 &dest);
|
||||||
|
static bool evalAsDouble(const std::string &expr, double &dest);
|
||||||
|
static bool evalAsBool(const std::string &expr, bool &dest);
|
||||||
|
static bool evalAsString(const std::string &expr, std::string &dest);
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
private:
|
||||||
|
// map of user functions
|
||||||
|
typedef std::map<std::string, TUserFct> TUserFctMap;
|
||||||
|
private:
|
||||||
|
static TUserFctMap *_UserFct;
|
||||||
|
private:
|
||||||
|
/** eval the value of a single expression
|
||||||
|
* \return position to the next valid character
|
||||||
|
*/
|
||||||
|
static const char *evalExpr(const char *expr, CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> *nodes, bool noFctCalls);
|
||||||
|
static const char *evalFct(const char *expr,CInterfaceExprValue &result,std::vector<NLMISC::ICDBNode *> *nodes, bool noFctCalls);
|
||||||
|
static const char *evalDBEntry(const char *expr,CInterfaceExprValue &result,std::vector<NLMISC::ICDBNode *> *nodes);
|
||||||
|
public:
|
||||||
|
static const char *unpackDBentry(const char *expr, std::vector<NLMISC::ICDBNode *> *nodes, std::string &dest, bool *hasIndirections = NULL);
|
||||||
|
|
||||||
|
/** Build tree of a single expression
|
||||||
|
* \return position to the next valid character
|
||||||
|
*/
|
||||||
|
private:
|
||||||
|
static const char *buildExprTree(const char *expr, CInterfaceExprNode *&result);
|
||||||
|
static const char *buildFctNode(const char *expr, CInterfaceExprNode *&result);
|
||||||
|
static const char *buildDBEntryNode(const char *expr,CInterfaceExprNode *&result);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// helper macro to register user functions at startup
|
||||||
|
#define REGISTER_INTERFACE_USER_FCT(name, fct) \
|
||||||
|
const struct __InterUserFctRegister__##fct\
|
||||||
|
{\
|
||||||
|
__InterUserFctRegister__##fct() { CInterfaceExpr::registerUserFct(name, fct); }\
|
||||||
|
} __InterUserFctRegisterInstance__##fct;
|
||||||
|
|
||||||
|
|
||||||
|
// helper macro to declare a user function
|
||||||
|
// the code must follow
|
||||||
|
// arguments are available in 'args', result should be put in 'result'
|
||||||
|
#define DECLARE_INTERFACE_USER_FCT(name) \
|
||||||
|
bool name(CInterfaceExpr::TArgList &args, CInterfaceExprValue &result)
|
||||||
|
|
||||||
|
|
||||||
|
// helper macro to declare a C constant mirroring
|
||||||
|
#define DECLARE_INTERFACE_CONSTANT(_name, _cconst) \
|
||||||
|
static DECLARE_INTERFACE_USER_FCT(_name) \
|
||||||
|
{ \
|
||||||
|
result.setInteger(_cconst); \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
REGISTER_INTERFACE_USER_FCT(#_name, _name)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
118
code/nel/include/nel/gui/interface_expr_node.h
Normal file
118
code/nel/include/nel/gui/interface_expr_node.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CL_INTERFACE_EXPR_NODE_H
|
||||||
|
#define CL_INTERFACE_EXPR_NODE_H
|
||||||
|
|
||||||
|
#include "interface_expr.h"
|
||||||
|
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Base node of an interface expression parse tree
|
||||||
|
* \author Nicolas Vizerie
|
||||||
|
* \author Nevrax France
|
||||||
|
* \date 2003
|
||||||
|
*/
|
||||||
|
class CInterfaceExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~CInterfaceExprNode() {}
|
||||||
|
// eval result of expression, and eventually get the nodes the epression depends on
|
||||||
|
virtual void eval(CInterfaceExprValue &result) = 0;
|
||||||
|
// The same, but get db nodes the expression depends on (appended to vector)
|
||||||
|
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes) = 0;
|
||||||
|
// Get dependencies of the node (appended to vector)
|
||||||
|
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
/** A constant value already parsed by interface (in a interface expr parse tree)
|
||||||
|
*/
|
||||||
|
class CInterfaceExprNodeValue : public CInterfaceExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CInterfaceExprValue Value;
|
||||||
|
public:
|
||||||
|
virtual void eval(CInterfaceExprValue &result);
|
||||||
|
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
/** A fct call (in a interface expr parse tree)
|
||||||
|
*/
|
||||||
|
class CInterfaceExprNodeValueFnCall : public CInterfaceExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CInterfaceExpr::TUserFct Func;
|
||||||
|
// list of parameters
|
||||||
|
std::vector<CInterfaceExprNode *> Params;
|
||||||
|
public:
|
||||||
|
virtual void eval(CInterfaceExprValue &result);
|
||||||
|
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
virtual ~CInterfaceExprNodeValueFnCall();
|
||||||
|
};
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
/** A db leaf read (in a interface expr parse tree)
|
||||||
|
*/
|
||||||
|
class CInterfaceExprNodeDBLeaf : public CInterfaceExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class NLMISC::CCDBNodeLeaf *Leaf;
|
||||||
|
public:
|
||||||
|
virtual void eval(CInterfaceExprValue &result);
|
||||||
|
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
/** A db branch read (in a interface expr parse tree)
|
||||||
|
*/
|
||||||
|
class CInterfaceExprNodeDBBranch : public CInterfaceExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class NLMISC::CCDBNodeBranch *Branch;
|
||||||
|
public:
|
||||||
|
virtual void eval(CInterfaceExprValue &result);
|
||||||
|
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
/** A dependant db read (in a interface expr parse tree)
|
||||||
|
* This is rarely used so no real optim there..
|
||||||
|
*/
|
||||||
|
class CInterfaceExprNodeDependantDBRead : public CInterfaceExprNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string Expr;
|
||||||
|
public:
|
||||||
|
virtual void eval(CInterfaceExprValue &result);
|
||||||
|
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -326,6 +326,8 @@ public:
|
||||||
void buildFromHLS(float h, float l, float s);
|
void buildFromHLS(float h, float l, float s);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
static CRGBA stringToRGBA( const char *ptr );
|
||||||
|
|
||||||
|
|
||||||
/// Swap the B and R components, to simulate a CBRGA
|
/// Swap the B and R components, to simulate a CBRGA
|
||||||
void swapBR()
|
void swapBR()
|
||||||
|
|
939
code/nel/src/gui/interface_expr.cpp
Normal file
939
code/nel/src/gui/interface_expr.cpp
Normal file
|
@ -0,0 +1,939 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "nel/misc/algo.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include "nel/gui/db_manager.h"
|
||||||
|
#include "nel/gui/interface_expr.h"
|
||||||
|
#include "nel/gui/interface_expr_node.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
|
||||||
|
// Yoyo: Act like a singleton, else registerUserFct may crash.
|
||||||
|
CInterfaceExpr::TUserFctMap *CInterfaceExpr::_UserFct= NULL;
|
||||||
|
|
||||||
|
static const std::string ExprLuaId="lua:";
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
// release memory
|
||||||
|
void CInterfaceExpr::release()
|
||||||
|
{
|
||||||
|
delete _UserFct;
|
||||||
|
_UserFct = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
void formatLuaCall(const std::string &expr, std::string &tempStr)
|
||||||
|
{
|
||||||
|
/* Call the LUA interface exp fct, with the script as line, and resolve string definition conflicts:
|
||||||
|
eg: replace
|
||||||
|
lua:getSkillFromName('SM')
|
||||||
|
into
|
||||||
|
lua('getSkillFromName(\"SM\")')
|
||||||
|
*/
|
||||||
|
tempStr= expr.substr(ExprLuaId.size()); // eg: tempStr= getSkillFromName('SM')
|
||||||
|
while(strFindReplace(tempStr, "'", "\\\"")); // eg: tempStr= getSkillFromName(\"SM\")
|
||||||
|
tempStr= string("lua('") + tempStr + "')"; // eg: tempStr= lua('getSkillFromName(\"SM\")')
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExpr::eval(const std::string &expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes, bool noFctCalls /* = false */)
|
||||||
|
{
|
||||||
|
// Yoyo: Special InterfaceExpr Form to execute lua code?
|
||||||
|
if(expr.compare(0, ExprLuaId.size(), ExprLuaId) ==0 )
|
||||||
|
{
|
||||||
|
std::string tempStr;
|
||||||
|
formatLuaCall(expr, tempStr);
|
||||||
|
return evalExpr(tempStr.c_str(), result, nodes, noFctCalls) != NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return evalExpr(expr.c_str(), result, nodes, noFctCalls) != NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
CInterfaceExprNode *CInterfaceExpr::buildExprTree(const std::string &expr)
|
||||||
|
{
|
||||||
|
CInterfaceExprNode *node;
|
||||||
|
|
||||||
|
// Yoyo: Special InterfaceExpr Form to execute lua code?
|
||||||
|
if(expr.compare(0, ExprLuaId.size(), ExprLuaId) ==0 )
|
||||||
|
{
|
||||||
|
std::string tempStr;
|
||||||
|
formatLuaCall(expr, tempStr);
|
||||||
|
if (!buildExprTree(tempStr.c_str(), node)) return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!buildExprTree(expr.c_str(), node)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
void CInterfaceExpr::registerUserFct(const char *name,TUserFct fct)
|
||||||
|
{
|
||||||
|
if(!_UserFct) _UserFct= new TUserFctMap;
|
||||||
|
|
||||||
|
nlassert(fct != NULL);
|
||||||
|
(*_UserFct)[std::string(name)] = fct;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
/** tool fct : skip space, tab and carret-returns
|
||||||
|
*/
|
||||||
|
static const char *skipBlank(const char *start)
|
||||||
|
{
|
||||||
|
nlassert(start);
|
||||||
|
while (*start == ' ' || *start == '\t' || *start == '\r' || *start == '\n') ++start;
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::evalExpr(const char *expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes, bool noFctCalls)
|
||||||
|
{
|
||||||
|
nlassert(expr != NULL);
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (isalpha(*expr)) // alpha character means this is a function name
|
||||||
|
{
|
||||||
|
return evalFct(expr, result, nodes, noFctCalls);
|
||||||
|
}
|
||||||
|
else if (*expr == '@') // is it a database entry ?
|
||||||
|
{
|
||||||
|
++ expr;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
return evalDBEntry(expr, result, nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to parse a literal value
|
||||||
|
const char *newExpr = result.initFromString(expr);
|
||||||
|
if (!newExpr)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalExpr> : syntax error : %s", expr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return newExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::buildExprTree(const char *expr, CInterfaceExprNode *&result)
|
||||||
|
{
|
||||||
|
nlassert(expr != NULL);
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (isalpha(*expr)) // alpha character means this is a function name
|
||||||
|
{
|
||||||
|
return buildFctNode(expr, result);
|
||||||
|
}
|
||||||
|
else if (*expr == '@') // is it a database entry ?
|
||||||
|
{
|
||||||
|
++ expr;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
return buildDBEntryNode(expr, result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CInterfaceExprValue value;
|
||||||
|
// try to parse a literal value
|
||||||
|
const char *newExpr = value.initFromString(expr);
|
||||||
|
if (!newExpr)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::buildExprTree> : syntax error : %s", expr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
CInterfaceExprNodeValue *node = new CInterfaceExprNodeValue;
|
||||||
|
node->Value = value;
|
||||||
|
result = node;
|
||||||
|
return newExpr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::evalFct(const char *expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes, bool noFctCalls)
|
||||||
|
{
|
||||||
|
if(!_UserFct) _UserFct= new TUserFctMap;
|
||||||
|
|
||||||
|
const char *start = expr;
|
||||||
|
while (isalnum(*expr)) ++ expr;
|
||||||
|
std::string fctName(start, expr - start);
|
||||||
|
// find entry in the map
|
||||||
|
TUserFctMap::iterator fctIt = _UserFct->find(fctName);
|
||||||
|
if (fctIt == _UserFct->end())
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalFct> : Unknown function %s", fctName.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nlassert(fctIt->second != NULL);
|
||||||
|
// eval list of arguments
|
||||||
|
TArgList argList;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (*expr != '(')
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalFct> : '(' expected for function %s", fctName.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (*expr != ')')
|
||||||
|
{
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
// parse an argument
|
||||||
|
argList.push_back(CInterfaceExprValue());
|
||||||
|
expr = evalExpr(expr, argList.back(), nodes, noFctCalls);
|
||||||
|
if (expr == NULL) return NULL;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (*expr == ')') break;
|
||||||
|
// if it isn't the end of the expression, then we should find a ',' before next argument
|
||||||
|
if (*expr != ',')
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalFct> : ',' expected in function %s", fctName.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
// call the fct
|
||||||
|
if (!noFctCalls) // should we make terminal function calls ?
|
||||||
|
{
|
||||||
|
if (fctIt->second(argList, result)) return expr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::buildFctNode(const char *expr, CInterfaceExprNode *&result)
|
||||||
|
{
|
||||||
|
if(!_UserFct) _UserFct= new TUserFctMap;
|
||||||
|
|
||||||
|
const char *start = expr;
|
||||||
|
while (isalnum(*expr)) ++ expr;
|
||||||
|
std::string fctName(start, expr - start);
|
||||||
|
// find entry in the map
|
||||||
|
TUserFctMap::iterator fctIt = _UserFct->find(fctName);
|
||||||
|
if (fctIt == _UserFct->end())
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::buildFctNode> : Unknown function %s", fctName.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nlassert(fctIt->second != NULL);
|
||||||
|
// List of parameters
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (*expr != '(')
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::buildFctNode> : '(' expected for function %s", fctName.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
std::vector<CInterfaceExprNode *> Params;
|
||||||
|
if (*expr != ')')
|
||||||
|
{
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
// parse an argument
|
||||||
|
CInterfaceExprNode *node = NULL;
|
||||||
|
expr = buildExprTree(expr, node);
|
||||||
|
if (expr == NULL)
|
||||||
|
{
|
||||||
|
for(uint k = 0; k < Params.size(); ++k)
|
||||||
|
{
|
||||||
|
delete Params[k];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Params.push_back(node);
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (*expr == ')') break;
|
||||||
|
// if it isn't the end of the expression, then we should find a ',' before next argument
|
||||||
|
if (*expr != ',')
|
||||||
|
{
|
||||||
|
for(uint k = 0; k < Params.size(); ++k)
|
||||||
|
{
|
||||||
|
delete Params[k];
|
||||||
|
}
|
||||||
|
nlwarning("CInterfaceExpr::evalFct : ',' expected in function %s", fctName.c_str());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
CInterfaceExprNodeValueFnCall *node = new CInterfaceExprNodeValueFnCall;
|
||||||
|
node->Params.swap(Params);
|
||||||
|
node->Func = fctIt->second;
|
||||||
|
result = node;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::evalDBEntry(const char *expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes)
|
||||||
|
{
|
||||||
|
std::string dbEntry;
|
||||||
|
expr = unpackDBentry(expr, nodes, dbEntry);
|
||||||
|
if (!expr) return NULL;
|
||||||
|
// TestYoyo
|
||||||
|
//nlassert(NLGUI::CDBManager::getInstance()->getDbProp(dbEntry, false) || CInterfaceManager::getInstance()->getDbBranch(dbEntry));
|
||||||
|
// get the db value
|
||||||
|
CCDBNodeLeaf *nl = NLGUI::CDBManager::getInstance()->getDbProp(dbEntry);
|
||||||
|
if (nl)
|
||||||
|
{
|
||||||
|
if (nodes)
|
||||||
|
{
|
||||||
|
// insert node if not already present
|
||||||
|
if (std::find(nodes->begin(), nodes->end(), nl) == nodes->end())
|
||||||
|
{
|
||||||
|
nodes->push_back(nl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.setInteger(nl->getValue64());
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCDBNodeBranch *nb = NLGUI::CDBManager::getInstance()->getDbBranch(dbEntry);
|
||||||
|
if (nodes && nb)
|
||||||
|
{
|
||||||
|
if (std::find(nodes->begin(), nodes->end(), nb) == nodes->end())
|
||||||
|
{
|
||||||
|
nodes->push_back(nb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!nb) return NULL;
|
||||||
|
result.setInteger(0);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::buildDBEntryNode(const char *expr, CInterfaceExprNode *&result)
|
||||||
|
{
|
||||||
|
std::string dbEntry;
|
||||||
|
bool indirection;
|
||||||
|
const char *startChar = expr;
|
||||||
|
expr = unpackDBentry(expr, NULL, dbEntry, &indirection);
|
||||||
|
if (!expr) return NULL;
|
||||||
|
if (indirection)
|
||||||
|
{
|
||||||
|
// special node with no optimisation
|
||||||
|
CInterfaceExprNodeDependantDBRead *node = new CInterfaceExprNodeDependantDBRead;
|
||||||
|
node->Expr.resize(expr - startChar + 1);
|
||||||
|
std::copy(startChar, expr, node->Expr.begin() + 1);
|
||||||
|
node->Expr[0] = '@';
|
||||||
|
result = node;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TestYoyo
|
||||||
|
//nlassert(NLGUI::CDBManager::getInstance()->getDbProp(dbEntry, false) || CInterfaceManager::getInstance()->getDbBranch(dbEntry));
|
||||||
|
CCDBNodeLeaf *nl = NLGUI::CDBManager::getInstance()->getDbProp(dbEntry);
|
||||||
|
if (nl)
|
||||||
|
{
|
||||||
|
CInterfaceExprNodeDBLeaf *node = new CInterfaceExprNodeDBLeaf;
|
||||||
|
node->Leaf = nl;
|
||||||
|
result = node;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCDBNodeBranch *nb = NLGUI::CDBManager::getInstance()->getDbBranch(dbEntry);
|
||||||
|
if (nb)
|
||||||
|
{
|
||||||
|
CInterfaceExprNodeDBBranch *node = new CInterfaceExprNodeDBBranch;
|
||||||
|
node->Branch = nb;
|
||||||
|
result = node;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExpr::unpackDBentry(const char *expr, std::vector<ICDBNode *> *nodes, std::string &dest, bool *hasIndirections /* = NULL*/)
|
||||||
|
{
|
||||||
|
std::string entryName;
|
||||||
|
bool indirection = false;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (*expr == '[')
|
||||||
|
{
|
||||||
|
indirection = true;
|
||||||
|
++ expr;
|
||||||
|
std::string subEntry;
|
||||||
|
expr = unpackDBentry(expr, nodes, subEntry);
|
||||||
|
if (!expr) return NULL;
|
||||||
|
// Read DB Index Offset.
|
||||||
|
sint32 indirectionOffset= 0;
|
||||||
|
if (*expr == '-' || *expr =='+' )
|
||||||
|
{
|
||||||
|
bool negative= *expr == '-';
|
||||||
|
std::string offsetString;
|
||||||
|
++ expr;
|
||||||
|
while(*expr!=0 && isdigit(*expr))
|
||||||
|
{
|
||||||
|
offsetString.push_back(*expr);
|
||||||
|
++ expr;
|
||||||
|
}
|
||||||
|
// get offset
|
||||||
|
fromString(offsetString, indirectionOffset);
|
||||||
|
if(negative)
|
||||||
|
indirectionOffset= -indirectionOffset;
|
||||||
|
}
|
||||||
|
// Test end of indirection
|
||||||
|
if (*expr != ']')
|
||||||
|
{
|
||||||
|
nlwarning("CInterfaceExpr::unpackDBentry: ']' expected");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
// get the db value at sub entry
|
||||||
|
// TestYoyo
|
||||||
|
//nlassert(NLGUI::CDBManager::getInstance()->getDbProp(subEntry, false) || CInterfaceManager::getInstance()->getDbBranch(subEntry));
|
||||||
|
CCDBNodeLeaf *nl = NLGUI::CDBManager::getInstance()->getDbProp(subEntry);
|
||||||
|
if (nodes)
|
||||||
|
{
|
||||||
|
if (std::find(nodes->begin(), nodes->end(), nl) == nodes->end())
|
||||||
|
{
|
||||||
|
nodes->push_back(nl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// compute indirection, (clamp).
|
||||||
|
sint32 indirectionValue= nl->getValue32() + indirectionOffset;
|
||||||
|
indirectionValue= std::max((sint32)0, indirectionValue);
|
||||||
|
|
||||||
|
// Append to entry name.
|
||||||
|
entryName += NLMISC::toString(indirectionValue);
|
||||||
|
}
|
||||||
|
else if (isalnum(*expr) || *expr == '_' || *expr == ':')
|
||||||
|
{
|
||||||
|
entryName += *expr;
|
||||||
|
++ expr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasIndirections)
|
||||||
|
{
|
||||||
|
*hasIndirections = indirection;
|
||||||
|
}
|
||||||
|
dest = entryName;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExpr::evalAsInt(const std::string &expr, sint64 &dest)
|
||||||
|
{
|
||||||
|
CInterfaceExprValue result;
|
||||||
|
if (!eval(expr, result)) return false;
|
||||||
|
if (!result.toInteger())
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalAsInt> Can't convert value to an integer, expr = %s", expr.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest = result.getInteger();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExpr::evalAsDouble(const std::string &expr, double &dest)
|
||||||
|
{
|
||||||
|
CInterfaceExprValue result;
|
||||||
|
if (!eval(expr, result)) return false;
|
||||||
|
if (!result.toDouble())
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalAsDouble> Can't convert value to a double, expr = %s", expr.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest = result.getDouble();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExpr::evalAsBool(const std::string &expr, bool &dest)
|
||||||
|
{
|
||||||
|
CInterfaceExprValue result;
|
||||||
|
if (!eval(expr, result)) return false;
|
||||||
|
if (!result.toBool())
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalAsBool> Can't convert value to a boolean, expr = %s", expr.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest = result.getBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExpr::evalAsString(const std::string &expr, std::string &dest)
|
||||||
|
{
|
||||||
|
CInterfaceExprValue result;
|
||||||
|
if (!eval(expr, result)) return false;
|
||||||
|
if (!result.toString())
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExpr::evalAsString> Can't convert value to a string, expr = %s", expr.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest = result.getString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
//==================================================================
|
||||||
|
//==================================================================
|
||||||
|
//==================================================================
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::toBool()
|
||||||
|
{
|
||||||
|
switch(_Type)
|
||||||
|
{
|
||||||
|
case Boolean: return true;
|
||||||
|
case Integer: setBool(_IntegerValue != 0); return true;
|
||||||
|
case Double: setBool(_DoubleValue != 0); return true;
|
||||||
|
case String: return evalBoolean(_StringValue.toString().c_str()) != NULL;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::toInteger()
|
||||||
|
{
|
||||||
|
switch(_Type)
|
||||||
|
{
|
||||||
|
case Boolean: setInteger(_BoolValue ? 1 : 0); return true;
|
||||||
|
case Integer: return true;
|
||||||
|
case Double: setInteger((sint64) _DoubleValue); return true;
|
||||||
|
case String:
|
||||||
|
if (evalNumber(_StringValue.toString().c_str())) return toInteger();
|
||||||
|
return false;
|
||||||
|
case RGBA: setInteger((sint64) _RGBAValue); return true;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::toDouble()
|
||||||
|
{
|
||||||
|
switch(_Type)
|
||||||
|
{
|
||||||
|
case Boolean: setDouble(_BoolValue ? 1 : 0); return true;
|
||||||
|
case Integer: setDouble((double) _IntegerValue); return true;
|
||||||
|
case Double: return true;
|
||||||
|
case String:
|
||||||
|
if (evalNumber(_StringValue.toString().c_str())) return toBool();
|
||||||
|
return false;
|
||||||
|
case RGBA: setDouble((double) _RGBAValue); return true;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::toString()
|
||||||
|
{
|
||||||
|
switch(_Type)
|
||||||
|
{
|
||||||
|
case Boolean: setString(_BoolValue ? "true" : "false"); return true;
|
||||||
|
case Integer: setString(NLMISC::toString(_IntegerValue)); return true;
|
||||||
|
case Double: setString(NLMISC::toString("%.2f", _DoubleValue)); return true;
|
||||||
|
case String: return true;
|
||||||
|
case RGBA:
|
||||||
|
{
|
||||||
|
uint r,g,b,a;
|
||||||
|
r= (_RGBAValue&0xff);
|
||||||
|
g= ((_RGBAValue>>8)&0xff);
|
||||||
|
b= ((_RGBAValue>>16)&0xff);
|
||||||
|
a= ((_RGBAValue>>24)&0xff);
|
||||||
|
setString(NLMISC::toString("%d %d %d %d", r, g, b, a));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::toRGBA()
|
||||||
|
{
|
||||||
|
switch(_Type)
|
||||||
|
{
|
||||||
|
case RGBA:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Integer:
|
||||||
|
setRGBA(NLMISC::CRGBA((uint8)(_IntegerValue&0xff), (uint8)((_IntegerValue>>8)&0xff),
|
||||||
|
(uint8)((_IntegerValue>>16)&0xff), (uint8)((_IntegerValue>>24)&0xff)));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case String:
|
||||||
|
setRGBA( NLMISC::CRGBA::stringToRGBA(_StringValue.toString().c_str()));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::isNumerical() const
|
||||||
|
{
|
||||||
|
return _Type == Boolean || _Type == Integer || _Type == Double;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExprValue::initFromString(const char *expr)
|
||||||
|
{
|
||||||
|
nlassert(expr);
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (isdigit(*expr) || *expr == '.' || *expr == '-') return evalNumber(expr);
|
||||||
|
switch(*expr)
|
||||||
|
{
|
||||||
|
case 't':
|
||||||
|
case 'T':
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
return evalBoolean(expr);
|
||||||
|
case '\'':
|
||||||
|
return evalString(expr);
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExprValue::evalBoolean(const char *expr)
|
||||||
|
{
|
||||||
|
nlassert(expr);
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (toupper(expr[0]) == 'T' &&
|
||||||
|
toupper(expr[1]) == 'R' &&
|
||||||
|
toupper(expr[2]) == 'U' &&
|
||||||
|
toupper(expr[3]) == 'E')
|
||||||
|
{
|
||||||
|
setBool(true);
|
||||||
|
return expr + 4;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (toupper(expr[0]) == 'F' &&
|
||||||
|
toupper(expr[1]) == 'A' &&
|
||||||
|
toupper(expr[2]) == 'L' &&
|
||||||
|
toupper(expr[3]) == 'S' &&
|
||||||
|
toupper(expr[4]) == 'E')
|
||||||
|
{
|
||||||
|
setBool(false);
|
||||||
|
return expr + 5;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExprValue::evalNumber(const char *expr)
|
||||||
|
{
|
||||||
|
bool negative;
|
||||||
|
bool hasPoint = false;
|
||||||
|
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
|
||||||
|
if (*expr == '-')
|
||||||
|
{
|
||||||
|
negative = true;
|
||||||
|
++ expr;
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
negative = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *start = expr;
|
||||||
|
while (*expr == '.' || isdigit(*expr))
|
||||||
|
{
|
||||||
|
if (*expr == '.') hasPoint = true;
|
||||||
|
++ expr;
|
||||||
|
}
|
||||||
|
if (start == expr) return NULL;
|
||||||
|
if (!hasPoint)
|
||||||
|
{
|
||||||
|
sint64 value = 0;
|
||||||
|
// this is an integer
|
||||||
|
for (const char *nbPtr = start; nbPtr < expr; ++ nbPtr)
|
||||||
|
{
|
||||||
|
value *= 10;
|
||||||
|
value += (sint64) (*nbPtr - '0');
|
||||||
|
}
|
||||||
|
setInteger(negative ? - value : value);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
else // floating point value : use scanf
|
||||||
|
{
|
||||||
|
// well, for now, we only parse a float
|
||||||
|
float value;
|
||||||
|
std::string floatValue(start, expr - start);
|
||||||
|
if (fromString(floatValue, value))
|
||||||
|
{
|
||||||
|
setDouble(negative ? - value : value);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const char *CInterfaceExprValue::evalString(const char *expr)
|
||||||
|
{
|
||||||
|
expr = skipBlank(expr);
|
||||||
|
if (*expr != '\'') return NULL;
|
||||||
|
++expr;
|
||||||
|
std::string str;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (expr == '\0')
|
||||||
|
{
|
||||||
|
nlwarning("CInterfaceExprValue::evalString : end of buffer encountered in a string");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (*expr == '\'')
|
||||||
|
{
|
||||||
|
++ expr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*expr == '\\') // special char
|
||||||
|
{
|
||||||
|
++ expr;
|
||||||
|
switch (*expr)
|
||||||
|
{
|
||||||
|
case 't': str += '\t'; break;
|
||||||
|
case 'r': str += '\r'; break;
|
||||||
|
case 'n': str += '\n'; break;
|
||||||
|
case '\'': str += '\''; break;
|
||||||
|
case '"': str += '"'; break;
|
||||||
|
case '\\': str += '\\'; break;
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
// string continue on next line, so do nothing
|
||||||
|
break;
|
||||||
|
case '\0': continue;
|
||||||
|
default:
|
||||||
|
nlwarning("CInterfaceExprValue::evalString : unknown escape sequence : \\%c", *expr);
|
||||||
|
if (*expr) str += *expr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*expr == '\n' || *expr == '\r')
|
||||||
|
{
|
||||||
|
nlwarning("CInterfaceExprValue::evalString : line break encountered in a string");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str += *expr;
|
||||||
|
}
|
||||||
|
++ expr;
|
||||||
|
}
|
||||||
|
setString(str);
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::toType(TType type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case Boolean: return toBool();
|
||||||
|
case Integer: return toInteger();
|
||||||
|
case Double: return toDouble();
|
||||||
|
case String: return toString();
|
||||||
|
case RGBA: return toRGBA();
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
void CInterfaceExprValue::clean()
|
||||||
|
{
|
||||||
|
switch (_Type)
|
||||||
|
{
|
||||||
|
case String: _StringValue.clear(); break;
|
||||||
|
case UserType: delete _UserTypeValue; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
void CInterfaceExprValue::setUserType(CInterfaceExprUserType *value)
|
||||||
|
{
|
||||||
|
if (_Type == UserType && value == _UserTypeValue) return;
|
||||||
|
clean();
|
||||||
|
_Type = UserType;
|
||||||
|
_UserTypeValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
bool CInterfaceExprValue::getBool() const
|
||||||
|
{
|
||||||
|
if (_Type != Boolean)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getBool> bad type!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _BoolValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
sint64 CInterfaceExprValue::getInteger() const
|
||||||
|
{
|
||||||
|
if (_Type != Integer)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getInteger> bad type!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return _IntegerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
double CInterfaceExprValue::getDouble() const
|
||||||
|
{
|
||||||
|
if (_Type != Double)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getDouble> bad type!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return _DoubleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
std::string CInterfaceExprValue::getString() const
|
||||||
|
{
|
||||||
|
if (_Type != String)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getString> bad type!");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return _StringValue.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
NLMISC::CRGBA CInterfaceExprValue::getRGBA() const
|
||||||
|
{
|
||||||
|
if (_Type != RGBA)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getRGBA> bad type!");
|
||||||
|
return CRGBA::White;
|
||||||
|
}
|
||||||
|
NLMISC::CRGBA col;
|
||||||
|
col.R = (uint8)(_RGBAValue&0xff);
|
||||||
|
col.G = (uint8)((_RGBAValue>>8)&0xff);
|
||||||
|
col.B = (uint8)((_RGBAValue>>16)&0xff);
|
||||||
|
col.A = (uint8)((_RGBAValue>>24)&0xff);
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
const ucstring &CInterfaceExprValue::getUCString() const
|
||||||
|
{
|
||||||
|
if (_Type != String)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getString> bad type!");
|
||||||
|
static ucstring emptyString;
|
||||||
|
return emptyString;
|
||||||
|
}
|
||||||
|
return _StringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
CInterfaceExprUserType *CInterfaceExprValue::getUserType() const
|
||||||
|
{
|
||||||
|
if (_Type != UserType)
|
||||||
|
{
|
||||||
|
nlwarning("<CInterfaceExprValue::getUserType> bad type!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return _UserTypeValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
CInterfaceExprValue::CInterfaceExprValue(const CInterfaceExprValue &other) : _Type(NoType)
|
||||||
|
{
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================
|
||||||
|
CInterfaceExprValue &CInterfaceExprValue::operator = (const CInterfaceExprValue &other)
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
clean();
|
||||||
|
switch(other._Type)
|
||||||
|
{
|
||||||
|
case Boolean: _BoolValue = other._BoolValue; break;
|
||||||
|
case Integer: _IntegerValue = other._IntegerValue; break;
|
||||||
|
case Double: _DoubleValue = other._DoubleValue; break;
|
||||||
|
case String: _StringValue = other._StringValue; break;
|
||||||
|
case RGBA: _RGBAValue = other._RGBAValue; break;
|
||||||
|
case UserType:
|
||||||
|
if (other._UserTypeValue != NULL)
|
||||||
|
{
|
||||||
|
_UserTypeValue = other._UserTypeValue->clone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_UserTypeValue = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NoType: break;
|
||||||
|
default:
|
||||||
|
nlwarning("<CInterfaceExprValue::operator=> bad source type") ;
|
||||||
|
return *this;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_Type = other._Type;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
161
code/nel/src/gui/interface_expr_node.cpp
Normal file
161
code/nel/src/gui/interface_expr_node.cpp
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#include "nel/misc/cdb_leaf.h"
|
||||||
|
#include "nel/misc/cdb_branch.h"
|
||||||
|
#include "nel/gui/interface_expr_node.h"
|
||||||
|
|
||||||
|
using NLMISC::ICDBNode;
|
||||||
|
using NLMISC::CCDBNodeBranch;
|
||||||
|
using NLMISC::CCDBNodeLeaf;
|
||||||
|
|
||||||
|
namespace NLGUI
|
||||||
|
{
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
void CInterfaceExprNodeValue::eval(CInterfaceExprValue &result)
|
||||||
|
{
|
||||||
|
result = Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeValue::evalWithDepends(CInterfaceExprValue &result, std::vector<ICDBNode *> &/* nodes */)
|
||||||
|
{
|
||||||
|
result = Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeValue::getDepends(std::vector<ICDBNode *> &/* nodes */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
void CInterfaceExprNodeValueFnCall::eval(CInterfaceExprValue &result)
|
||||||
|
{
|
||||||
|
nlassert(Func);
|
||||||
|
uint numParams = (uint)Params.size();
|
||||||
|
std::vector<CInterfaceExprValue> params(numParams);
|
||||||
|
for(uint k = 0; k < numParams; ++k)
|
||||||
|
{
|
||||||
|
Params[k]->eval(params[k]);
|
||||||
|
}
|
||||||
|
Func(params, result); // do actual call
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeValueFnCall::evalWithDepends(CInterfaceExprValue &result, std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
nlassert(Func);
|
||||||
|
uint numParams = (uint)Params.size();
|
||||||
|
std::vector<CInterfaceExprValue> params(numParams);
|
||||||
|
for(uint k = 0; k < numParams; ++k)
|
||||||
|
{
|
||||||
|
Params[k]->evalWithDepends(params[k], nodes);
|
||||||
|
}
|
||||||
|
Func(params, result); // do actual call
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeValueFnCall::getDepends(std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
uint numParams = (uint)Params.size();
|
||||||
|
for(uint k = 0; k < numParams; ++k)
|
||||||
|
{
|
||||||
|
Params[k]->getDepends(nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CInterfaceExprNodeValueFnCall::~CInterfaceExprNodeValueFnCall()
|
||||||
|
{
|
||||||
|
for(uint k = 0; k < Params.size(); ++k)
|
||||||
|
{
|
||||||
|
delete Params[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
void CInterfaceExprNodeDBLeaf::eval(CInterfaceExprValue &result)
|
||||||
|
{
|
||||||
|
nlassert(Leaf);
|
||||||
|
result.setInteger(Leaf->getValue64());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeDBLeaf::evalWithDepends(CInterfaceExprValue &result,std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
nlassert(Leaf);
|
||||||
|
result.setInteger(Leaf->getValue64());
|
||||||
|
if (std::find(nodes.begin(), nodes.end(), Leaf) == nodes.end())
|
||||||
|
{
|
||||||
|
nodes.push_back(Leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeDBLeaf::getDepends(std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
nlassert(Leaf);
|
||||||
|
if (std::find(nodes.begin(), nodes.end(), Leaf) == nodes.end())
|
||||||
|
{
|
||||||
|
nodes.push_back(Leaf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
void CInterfaceExprNodeDBBranch::eval(CInterfaceExprValue &result)
|
||||||
|
{
|
||||||
|
nlassert(Branch);
|
||||||
|
result.setInteger(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeDBBranch::evalWithDepends(CInterfaceExprValue &result,std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
nlassert(Branch);
|
||||||
|
result.setInteger(0);
|
||||||
|
if (std::find(nodes.begin(), nodes.end(), Branch) == nodes.end())
|
||||||
|
{
|
||||||
|
nodes.push_back(Branch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeDBBranch::getDepends(std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
nlassert(Branch);
|
||||||
|
if (std::find(nodes.begin(), nodes.end(), Branch) == nodes.end())
|
||||||
|
{
|
||||||
|
nodes.push_back(Branch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *******************************************************************************************************
|
||||||
|
void CInterfaceExprNodeDependantDBRead::eval(CInterfaceExprValue &result)
|
||||||
|
{
|
||||||
|
// no gain there, but barely used
|
||||||
|
CInterfaceExpr::eval(Expr, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeDependantDBRead::evalWithDepends(CInterfaceExprValue &result, std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
CInterfaceExpr::eval(Expr, result, &nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInterfaceExprNodeDependantDBRead::getDepends(std::vector<ICDBNode *> &nodes)
|
||||||
|
{
|
||||||
|
CInterfaceExprValue dummyResult;
|
||||||
|
CInterfaceExpr::eval(Expr, dummyResult, &nodes, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -728,6 +728,21 @@ void CRGBA::buildFromHLS(float h, float l, float s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CRGBA CRGBA::stringToRGBA( const char *ptr )
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return NLMISC::CRGBA::White;
|
||||||
|
|
||||||
|
int r = 255, g = 255, b = 255, a = 255;
|
||||||
|
sscanf( ptr, "%d %d %d %d", &r, &g, &b, &a );
|
||||||
|
clamp( r, 0, 255 );
|
||||||
|
clamp( g, 0, 255 );
|
||||||
|
clamp( b, 0, 255 );
|
||||||
|
clamp( a, 0, 255 );
|
||||||
|
|
||||||
|
return CRGBA( r,g,b,a );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
|
@ -1374,7 +1374,7 @@ void CClientConfig::setValues()
|
||||||
SPrintfCommand pcom;
|
SPrintfCommand pcom;
|
||||||
pcom.X = pc->asInt(i);
|
pcom.X = pc->asInt(i);
|
||||||
pcom.Y = pc->asInt(i+1);
|
pcom.Y = pc->asInt(i+1);
|
||||||
pcom.Color = stringToRGBA( pc->asString(i+2).c_str() );
|
pcom.Color = CRGBA::stringToRGBA( pc->asString(i+2).c_str() );
|
||||||
pcom.FontSize = pc->asInt(i+3);
|
pcom.FontSize = pc->asInt(i+3);
|
||||||
pcom.Text = pc->asString(i+4);
|
pcom.Text = pc->asString(i+4);
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
#include "interface_v3/ctrl_button.h"
|
#include "interface_v3/ctrl_button.h"
|
||||||
#include "interface_v3/input_handler_manager.h"
|
#include "interface_v3/input_handler_manager.h"
|
||||||
#include "interface_v3/group_editbox.h"
|
#include "interface_v3/group_editbox.h"
|
||||||
#include "interface_v3/interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "init_main_loop.h"
|
#include "init_main_loop.h"
|
||||||
#include "continent_manager.h"
|
#include "continent_manager.h"
|
||||||
#include "interface_v3/group_quick_help.h"
|
#include "interface_v3/group_quick_help.h"
|
||||||
|
@ -1338,7 +1338,7 @@ void setTarget(CCtrlBase *ctrl, const string &targetName, ucstring &value)
|
||||||
CInterfaceExprValue exprValue;
|
CInterfaceExprValue exprValue;
|
||||||
exprValue.setUCString(value);
|
exprValue.setUCString(value);
|
||||||
|
|
||||||
CInterfaceParser::splitLinkTargets(targetName, ig, targets);
|
CInterfaceLink::splitLinkTargets(targetName, ig, targets);
|
||||||
for(uint k = 0; k < targets.size(); ++k)
|
for(uint k = 0; k < targets.size(); ++k)
|
||||||
{
|
{
|
||||||
if (targets[k].Elem) targets[k].affect(exprValue);
|
if (targets[k].Elem) targets[k].affect(exprValue);
|
||||||
|
@ -1364,7 +1364,7 @@ void setTarget(CCtrlBase *ctrl, const string &targetName, uint32 value)
|
||||||
CInterfaceExprValue exprValue;
|
CInterfaceExprValue exprValue;
|
||||||
exprValue.setInteger(value);
|
exprValue.setInteger(value);
|
||||||
|
|
||||||
CInterfaceParser::splitLinkTargets(targetName, ig, targets);
|
CInterfaceLink::splitLinkTargets(targetName, ig, targets);
|
||||||
for(uint k = 0; k < targets.size(); ++k)
|
for(uint k = 0; k < targets.size(); ++k)
|
||||||
{
|
{
|
||||||
if (targets[k].Elem) targets[k].affect(exprValue);
|
if (targets[k].Elem) targets[k].affect(exprValue);
|
||||||
|
@ -1813,7 +1813,7 @@ string getTarget(CCtrlBase * /* ctrl */, const string &targetName)
|
||||||
{
|
{
|
||||||
string sTmp = targetName;
|
string sTmp = targetName;
|
||||||
std::vector<CInterfaceLink::CTargetInfo> targetsVector;
|
std::vector<CInterfaceLink::CTargetInfo> targetsVector;
|
||||||
CInterfaceParser::splitLinkTargets(sTmp, NULL, targetsVector);
|
CInterfaceLink::splitLinkTargets(sTmp, NULL, targetsVector);
|
||||||
|
|
||||||
CInterfaceLink::CTargetInfo &rTI = targetsVector[0];
|
CInterfaceLink::CTargetInfo &rTI = targetsVector[0];
|
||||||
|
|
||||||
|
@ -1835,7 +1835,7 @@ ucstring getUCTarget(CCtrlBase * /* ctrl */, const string &targetName)
|
||||||
{
|
{
|
||||||
string sTmp = targetName;
|
string sTmp = targetName;
|
||||||
std::vector<CInterfaceLink::CTargetInfo> targetsVector;
|
std::vector<CInterfaceLink::CTargetInfo> targetsVector;
|
||||||
CInterfaceParser::splitLinkTargets(sTmp, NULL, targetsVector);
|
CInterfaceLink::splitLinkTargets(sTmp, NULL, targetsVector);
|
||||||
|
|
||||||
CInterfaceLink::CTargetInfo &rTI = targetsVector[0];
|
CInterfaceLink::CTargetInfo &rTI = targetsVector[0];
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "action_handler.h"
|
#include "action_handler.h"
|
||||||
#include "action_handler_misc.h"
|
#include "action_handler_misc.h"
|
||||||
|
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
|
|
||||||
#include "group_container.h"
|
#include "group_container.h"
|
||||||
|
@ -298,7 +298,7 @@ public:
|
||||||
|
|
||||||
if (ig != NULL)
|
if (ig != NULL)
|
||||||
{
|
{
|
||||||
CInterfaceParser::splitLinkTargets(property, ig, targets);
|
CInterfaceLink::splitLinkTargets(property, ig, targets);
|
||||||
for(uint k = 0; k < targets.size(); ++k)
|
for(uint k = 0; k < targets.size(); ++k)
|
||||||
{
|
{
|
||||||
if (targets[k].Elem) targets[k].affect(value);
|
if (targets[k].Elem) targets[k].affect(value);
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "bot_chat_page_ring_sessions.h"
|
#include "bot_chat_page_ring_sessions.h"
|
||||||
#include "dbctrl_sheet.h"
|
#include "dbctrl_sheet.h"
|
||||||
#include "ctrl_sheet_selection.h"
|
#include "ctrl_sheet_selection.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "group_menu.h"
|
#include "group_menu.h"
|
||||||
#include "group_container.h"
|
#include "group_container.h"
|
||||||
#include "group_editbox.h"
|
#include "group_editbox.h"
|
||||||
|
@ -3902,7 +3902,7 @@ public:
|
||||||
uint entity;
|
uint entity;
|
||||||
fromString(getParam(sParams, "entity"), entity);
|
fromString(getParam(sParams, "entity"), entity);
|
||||||
|
|
||||||
CRGBA color = stringToRGBA(getParam(sParams, "color").c_str());
|
CRGBA color = CRGBA::stringToRGBA(getParam(sParams, "color").c_str());
|
||||||
if (entity < 256)
|
if (entity < 256)
|
||||||
EntitiesMngr.entity (entity)->addHPOutput (CI18N::get (text), color);
|
EntitiesMngr.entity (entity)->addHPOutput (CI18N::get (text), color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "../sheet_manager.h"
|
#include "../sheet_manager.h"
|
||||||
#include "skill_manager.h"
|
#include "skill_manager.h"
|
||||||
#include "dbctrl_sheet.h"
|
#include "dbctrl_sheet.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "group_container.h"
|
#include "group_container.h"
|
||||||
#include "group_editbox.h"
|
#include "group_editbox.h"
|
||||||
#include "group_quick_help.h"
|
#include "group_quick_help.h"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "dbctrl_sheet.h"
|
#include "dbctrl_sheet.h"
|
||||||
#include "dbgroup_list_sheet.h"
|
#include "dbgroup_list_sheet.h"
|
||||||
#include "group_editbox.h"
|
#include "group_editbox.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "player_trade.h"
|
#include "player_trade.h"
|
||||||
#include "../user_entity.h"
|
#include "../user_entity.h"
|
||||||
#include "../net_manager.h"
|
#include "../net_manager.h"
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "group_editbox.h"
|
#include "group_editbox.h"
|
||||||
#include "people_interraction.h"
|
#include "people_interraction.h"
|
||||||
#include "nel/misc/algo.h"
|
#include "nel/misc/algo.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "interface_link.h"
|
#include "interface_link.h"
|
||||||
#include "../client_chat_manager.h"
|
#include "../client_chat_manager.h"
|
||||||
#include "../motion/user_controls.h"
|
#include "../motion/user_controls.h"
|
||||||
|
@ -427,7 +427,7 @@ class CActionHandlerAddLink : public IActionHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CInterfaceLink::CTargetInfo> targetsVect;
|
std::vector<CInterfaceLink::CTargetInfo> targetsVect;
|
||||||
bool result = CInterfaceParser::splitLinkTargets(targets, parentGroup, targetsVect);
|
bool result = CInterfaceLink::splitLinkTargets(targets, parentGroup, targetsVect);
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
nlwarning("<CActionHandlerAddLink> Couldn't parse all links");
|
nlwarning("<CActionHandlerAddLink> Couldn't parse all links");
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "action_handler.h"
|
#include "action_handler.h"
|
||||||
#include "action_handler_tools.h"
|
#include "action_handler_tools.h"
|
||||||
#include "game_share/outpost.h"
|
#include "game_share/outpost.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "group_map.h"
|
#include "group_map.h"
|
||||||
#include "../sheet_manager.h"
|
#include "../sheet_manager.h"
|
||||||
#include "../net_manager.h"
|
#include "../net_manager.h"
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "bar_manager.h"
|
#include "bar_manager.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "../time_client.h"
|
#include "../time_client.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -554,7 +554,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
|
||||||
|
|
||||||
// on a new message, change the Tab color
|
// on a new message, change the Tab color
|
||||||
CInterfaceManager *pIM= CInterfaceManager::getInstance();
|
CInterfaceManager *pIM= CInterfaceManager::getInstance();
|
||||||
CRGBA newMsgColor= stringToRGBA(pIM->getDefine("chat_group_tab_color_newmsg").c_str());
|
CRGBA newMsgColor= CRGBA::stringToRGBA(pIM->getDefine("chat_group_tab_color_newmsg").c_str());
|
||||||
|
|
||||||
ucstring newmsg = msg;
|
ucstring newmsg = msg;
|
||||||
ucstring prefix;
|
ucstring prefix;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
// client
|
// client
|
||||||
#include "nel/gui/reflect.h"
|
#include "nel/gui/reflect.h"
|
||||||
#include "ctrl_base.h"
|
#include "ctrl_base.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "action_handler.h"
|
#include "action_handler.h"
|
||||||
#include "sphrase_manager.h"
|
#include "sphrase_manager.h"
|
||||||
// game share
|
// game share
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "group_menu.h"
|
#include "group_menu.h"
|
||||||
#include "nel/misc/xml_auto_ptr.h"
|
#include "nel/misc/xml_auto_ptr.h"
|
||||||
#include "view_bitmap.h"
|
#include "view_bitmap.h"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "group_phrase_skill_filter.h"
|
#include "group_phrase_skill_filter.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
|
|
||||||
#include "view_text.h"
|
#include "view_text.h"
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "group_skills.h"
|
#include "group_skills.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
|
|
||||||
#include "view_text.h"
|
#include "view_text.h"
|
||||||
#include "view_bitmap.h"
|
#include "view_bitmap.h"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include "interface_anim.h"
|
#include "interface_anim.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "nel/misc/xml_auto_ptr.h"
|
#include "nel/misc/xml_auto_ptr.h"
|
||||||
#include "action_handler.h"
|
#include "action_handler.h"
|
||||||
#include "../time_client.h"
|
#include "../time_client.h"
|
||||||
|
@ -75,7 +75,7 @@ bool CInterfaceTrack::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
if (!CInterfaceParser::splitLinkTargets (ptr, parentGroup, _Targets))
|
if (!CInterfaceLink::splitLinkTargets (ptr, parentGroup, _Targets))
|
||||||
{
|
{
|
||||||
nlwarning ("no target for track");
|
nlwarning ("no target for track");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -761,7 +761,7 @@ void CInterfaceElement::convertHotSpotCouple (const char *ptr, THotSpot &parent
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
NLMISC::CRGBA CInterfaceElement::convertColor (const char *ptr)
|
NLMISC::CRGBA CInterfaceElement::convertColor (const char *ptr)
|
||||||
{
|
{
|
||||||
return stringToRGBA(ptr);
|
return NLMISC::CRGBA::stringToRGBA(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,930 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program 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 Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "stdpch.h"
|
|
||||||
#include "interface_expr.h"
|
|
||||||
#include "interface_manager.h"
|
|
||||||
#include "interface_expr_node.h"
|
|
||||||
#include "../misc.h"
|
|
||||||
#include "nel/misc/algo.h"
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace NLMISC;
|
|
||||||
|
|
||||||
// Yoyo: Act like a singleton, else registerUserFct may crash.
|
|
||||||
CInterfaceExpr::TUserFctMap *CInterfaceExpr::_UserFct= NULL;
|
|
||||||
|
|
||||||
static const std::string ExprLuaId="lua:";
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
// release memory
|
|
||||||
void CInterfaceExpr::release()
|
|
||||||
{
|
|
||||||
delete _UserFct;
|
|
||||||
_UserFct = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
void formatLuaCall(const std::string &expr, std::string &tempStr)
|
|
||||||
{
|
|
||||||
/* Call the LUA interface exp fct, with the script as line, and resolve string definition conflicts:
|
|
||||||
eg: replace
|
|
||||||
lua:getSkillFromName('SM')
|
|
||||||
into
|
|
||||||
lua('getSkillFromName(\"SM\")')
|
|
||||||
*/
|
|
||||||
tempStr= expr.substr(ExprLuaId.size()); // eg: tempStr= getSkillFromName('SM')
|
|
||||||
while(strFindReplace(tempStr, "'", "\\\"")); // eg: tempStr= getSkillFromName(\"SM\")
|
|
||||||
tempStr= string("lua('") + tempStr + "')"; // eg: tempStr= lua('getSkillFromName(\"SM\")')
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExpr::eval(const std::string &expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes, bool noFctCalls /* = false */)
|
|
||||||
{
|
|
||||||
// Yoyo: Special InterfaceExpr Form to execute lua code?
|
|
||||||
if(expr.compare(0, ExprLuaId.size(), ExprLuaId) ==0 )
|
|
||||||
{
|
|
||||||
std::string tempStr;
|
|
||||||
formatLuaCall(expr, tempStr);
|
|
||||||
return evalExpr(tempStr.c_str(), result, nodes, noFctCalls) != NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return evalExpr(expr.c_str(), result, nodes, noFctCalls) != NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
CInterfaceExprNode *CInterfaceExpr::buildExprTree(const std::string &expr)
|
|
||||||
{
|
|
||||||
CInterfaceExprNode *node;
|
|
||||||
|
|
||||||
// Yoyo: Special InterfaceExpr Form to execute lua code?
|
|
||||||
if(expr.compare(0, ExprLuaId.size(), ExprLuaId) ==0 )
|
|
||||||
{
|
|
||||||
std::string tempStr;
|
|
||||||
formatLuaCall(expr, tempStr);
|
|
||||||
if (!buildExprTree(tempStr.c_str(), node)) return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!buildExprTree(expr.c_str(), node)) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
void CInterfaceExpr::registerUserFct(const char *name,TUserFct fct)
|
|
||||||
{
|
|
||||||
if(!_UserFct) _UserFct= new TUserFctMap;
|
|
||||||
|
|
||||||
nlassert(fct != NULL);
|
|
||||||
(*_UserFct)[std::string(name)] = fct;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
/** tool fct : skip space, tab and carret-returns
|
|
||||||
*/
|
|
||||||
static const char *skipBlank(const char *start)
|
|
||||||
{
|
|
||||||
nlassert(start);
|
|
||||||
while (*start == ' ' || *start == '\t' || *start == '\r' || *start == '\n') ++start;
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::evalExpr(const char *expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes, bool noFctCalls)
|
|
||||||
{
|
|
||||||
nlassert(expr != NULL);
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (isalpha(*expr)) // alpha character means this is a function name
|
|
||||||
{
|
|
||||||
return evalFct(expr, result, nodes, noFctCalls);
|
|
||||||
}
|
|
||||||
else if (*expr == '@') // is it a database entry ?
|
|
||||||
{
|
|
||||||
++ expr;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
return evalDBEntry(expr, result, nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to parse a literal value
|
|
||||||
const char *newExpr = result.initFromString(expr);
|
|
||||||
if (!newExpr)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalExpr> : syntax error : %s", expr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return newExpr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::buildExprTree(const char *expr, CInterfaceExprNode *&result)
|
|
||||||
{
|
|
||||||
nlassert(expr != NULL);
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (isalpha(*expr)) // alpha character means this is a function name
|
|
||||||
{
|
|
||||||
return buildFctNode(expr, result);
|
|
||||||
}
|
|
||||||
else if (*expr == '@') // is it a database entry ?
|
|
||||||
{
|
|
||||||
++ expr;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
return buildDBEntryNode(expr, result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CInterfaceExprValue value;
|
|
||||||
// try to parse a literal value
|
|
||||||
const char *newExpr = value.initFromString(expr);
|
|
||||||
if (!newExpr)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::buildExprTree> : syntax error : %s", expr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
CInterfaceExprNodeValue *node = new CInterfaceExprNodeValue;
|
|
||||||
node->Value = value;
|
|
||||||
result = node;
|
|
||||||
return newExpr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::evalFct(const char *expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes, bool noFctCalls)
|
|
||||||
{
|
|
||||||
if(!_UserFct) _UserFct= new TUserFctMap;
|
|
||||||
|
|
||||||
const char *start = expr;
|
|
||||||
while (isalnum(*expr)) ++ expr;
|
|
||||||
std::string fctName(start, expr - start);
|
|
||||||
// find entry in the map
|
|
||||||
TUserFctMap::iterator fctIt = _UserFct->find(fctName);
|
|
||||||
if (fctIt == _UserFct->end())
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalFct> : Unknown function %s", fctName.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nlassert(fctIt->second != NULL);
|
|
||||||
// eval list of arguments
|
|
||||||
TArgList argList;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (*expr != '(')
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalFct> : '(' expected for function %s", fctName.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (*expr != ')')
|
|
||||||
{
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
// parse an argument
|
|
||||||
argList.push_back(CInterfaceExprValue());
|
|
||||||
expr = evalExpr(expr, argList.back(), nodes, noFctCalls);
|
|
||||||
if (expr == NULL) return NULL;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (*expr == ')') break;
|
|
||||||
// if it isn't the end of the expression, then we should find a ',' before next argument
|
|
||||||
if (*expr != ',')
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalFct> : ',' expected in function %s", fctName.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
// call the fct
|
|
||||||
if (!noFctCalls) // should we make terminal function calls ?
|
|
||||||
{
|
|
||||||
if (fctIt->second(argList, result)) return expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::buildFctNode(const char *expr, CInterfaceExprNode *&result)
|
|
||||||
{
|
|
||||||
if(!_UserFct) _UserFct= new TUserFctMap;
|
|
||||||
|
|
||||||
const char *start = expr;
|
|
||||||
while (isalnum(*expr)) ++ expr;
|
|
||||||
std::string fctName(start, expr - start);
|
|
||||||
// find entry in the map
|
|
||||||
TUserFctMap::iterator fctIt = _UserFct->find(fctName);
|
|
||||||
if (fctIt == _UserFct->end())
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::buildFctNode> : Unknown function %s", fctName.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nlassert(fctIt->second != NULL);
|
|
||||||
// List of parameters
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (*expr != '(')
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::buildFctNode> : '(' expected for function %s", fctName.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
std::vector<CInterfaceExprNode *> Params;
|
|
||||||
if (*expr != ')')
|
|
||||||
{
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
// parse an argument
|
|
||||||
CInterfaceExprNode *node = NULL;
|
|
||||||
expr = buildExprTree(expr, node);
|
|
||||||
if (expr == NULL)
|
|
||||||
{
|
|
||||||
for(uint k = 0; k < Params.size(); ++k)
|
|
||||||
{
|
|
||||||
delete Params[k];
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Params.push_back(node);
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (*expr == ')') break;
|
|
||||||
// if it isn't the end of the expression, then we should find a ',' before next argument
|
|
||||||
if (*expr != ',')
|
|
||||||
{
|
|
||||||
for(uint k = 0; k < Params.size(); ++k)
|
|
||||||
{
|
|
||||||
delete Params[k];
|
|
||||||
}
|
|
||||||
nlwarning("CInterfaceExpr::evalFct : ',' expected in function %s", fctName.c_str());
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
CInterfaceExprNodeValueFnCall *node = new CInterfaceExprNodeValueFnCall;
|
|
||||||
node->Params.swap(Params);
|
|
||||||
node->Func = fctIt->second;
|
|
||||||
result = node;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::evalDBEntry(const char *expr, CInterfaceExprValue &result, std::vector<ICDBNode *> *nodes)
|
|
||||||
{
|
|
||||||
std::string dbEntry;
|
|
||||||
expr = unpackDBentry(expr, nodes, dbEntry);
|
|
||||||
if (!expr) return NULL;
|
|
||||||
// TestYoyo
|
|
||||||
//nlassert(NLGUI::CDBManager::getInstance()->getDbProp(dbEntry, false) || CInterfaceManager::getInstance()->getDbBranch(dbEntry));
|
|
||||||
// get the db value
|
|
||||||
CCDBNodeLeaf *nl = NLGUI::CDBManager::getInstance()->getDbProp(dbEntry);
|
|
||||||
if (nl)
|
|
||||||
{
|
|
||||||
if (nodes)
|
|
||||||
{
|
|
||||||
// insert node if not already present
|
|
||||||
if (std::find(nodes->begin(), nodes->end(), nl) == nodes->end())
|
|
||||||
{
|
|
||||||
nodes->push_back(nl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.setInteger(nl->getValue64());
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CCDBNodeBranch *nb = NLGUI::CDBManager::getInstance()->getDbBranch(dbEntry);
|
|
||||||
if (nodes && nb)
|
|
||||||
{
|
|
||||||
if (std::find(nodes->begin(), nodes->end(), nb) == nodes->end())
|
|
||||||
{
|
|
||||||
nodes->push_back(nb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!nb) return NULL;
|
|
||||||
result.setInteger(0);
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::buildDBEntryNode(const char *expr, CInterfaceExprNode *&result)
|
|
||||||
{
|
|
||||||
std::string dbEntry;
|
|
||||||
bool indirection;
|
|
||||||
const char *startChar = expr;
|
|
||||||
expr = unpackDBentry(expr, NULL, dbEntry, &indirection);
|
|
||||||
if (!expr) return NULL;
|
|
||||||
if (indirection)
|
|
||||||
{
|
|
||||||
// special node with no optimisation
|
|
||||||
CInterfaceExprNodeDependantDBRead *node = new CInterfaceExprNodeDependantDBRead;
|
|
||||||
node->Expr.resize(expr - startChar + 1);
|
|
||||||
std::copy(startChar, expr, node->Expr.begin() + 1);
|
|
||||||
node->Expr[0] = '@';
|
|
||||||
result = node;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TestYoyo
|
|
||||||
//nlassert(NLGUI::CDBManager::getInstance()->getDbProp(dbEntry, false) || CInterfaceManager::getInstance()->getDbBranch(dbEntry));
|
|
||||||
CCDBNodeLeaf *nl = NLGUI::CDBManager::getInstance()->getDbProp(dbEntry);
|
|
||||||
if (nl)
|
|
||||||
{
|
|
||||||
CInterfaceExprNodeDBLeaf *node = new CInterfaceExprNodeDBLeaf;
|
|
||||||
node->Leaf = nl;
|
|
||||||
result = node;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CCDBNodeBranch *nb = NLGUI::CDBManager::getInstance()->getDbBranch(dbEntry);
|
|
||||||
if (nb)
|
|
||||||
{
|
|
||||||
CInterfaceExprNodeDBBranch *node = new CInterfaceExprNodeDBBranch;
|
|
||||||
node->Branch = nb;
|
|
||||||
result = node;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExpr::unpackDBentry(const char *expr, std::vector<ICDBNode *> *nodes, std::string &dest, bool *hasIndirections /* = NULL*/)
|
|
||||||
{
|
|
||||||
std::string entryName;
|
|
||||||
bool indirection = false;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (*expr == '[')
|
|
||||||
{
|
|
||||||
indirection = true;
|
|
||||||
++ expr;
|
|
||||||
std::string subEntry;
|
|
||||||
expr = unpackDBentry(expr, nodes, subEntry);
|
|
||||||
if (!expr) return NULL;
|
|
||||||
// Read DB Index Offset.
|
|
||||||
sint32 indirectionOffset= 0;
|
|
||||||
if (*expr == '-' || *expr =='+' )
|
|
||||||
{
|
|
||||||
bool negative= *expr == '-';
|
|
||||||
std::string offsetString;
|
|
||||||
++ expr;
|
|
||||||
while(*expr!=0 && isdigit(*expr))
|
|
||||||
{
|
|
||||||
offsetString.push_back(*expr);
|
|
||||||
++ expr;
|
|
||||||
}
|
|
||||||
// get offset
|
|
||||||
fromString(offsetString, indirectionOffset);
|
|
||||||
if(negative)
|
|
||||||
indirectionOffset= -indirectionOffset;
|
|
||||||
}
|
|
||||||
// Test end of indirection
|
|
||||||
if (*expr != ']')
|
|
||||||
{
|
|
||||||
nlwarning("CInterfaceExpr::unpackDBentry: ']' expected");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
// get the db value at sub entry
|
|
||||||
// TestYoyo
|
|
||||||
//nlassert(NLGUI::CDBManager::getInstance()->getDbProp(subEntry, false) || CInterfaceManager::getInstance()->getDbBranch(subEntry));
|
|
||||||
CCDBNodeLeaf *nl = NLGUI::CDBManager::getInstance()->getDbProp(subEntry);
|
|
||||||
if (nodes)
|
|
||||||
{
|
|
||||||
if (std::find(nodes->begin(), nodes->end(), nl) == nodes->end())
|
|
||||||
{
|
|
||||||
nodes->push_back(nl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// compute indirection, (clamp).
|
|
||||||
sint32 indirectionValue= nl->getValue32() + indirectionOffset;
|
|
||||||
indirectionValue= std::max((sint32)0, indirectionValue);
|
|
||||||
|
|
||||||
// Append to entry name.
|
|
||||||
entryName += NLMISC::toString(indirectionValue);
|
|
||||||
}
|
|
||||||
else if (isalnum(*expr) || *expr == '_' || *expr == ':')
|
|
||||||
{
|
|
||||||
entryName += *expr;
|
|
||||||
++ expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasIndirections)
|
|
||||||
{
|
|
||||||
*hasIndirections = indirection;
|
|
||||||
}
|
|
||||||
dest = entryName;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExpr::evalAsInt(const std::string &expr, sint64 &dest)
|
|
||||||
{
|
|
||||||
CInterfaceExprValue result;
|
|
||||||
if (!eval(expr, result)) return false;
|
|
||||||
if (!result.toInteger())
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalAsInt> Can't convert value to an integer, expr = %s", expr.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dest = result.getInteger();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExpr::evalAsDouble(const std::string &expr, double &dest)
|
|
||||||
{
|
|
||||||
CInterfaceExprValue result;
|
|
||||||
if (!eval(expr, result)) return false;
|
|
||||||
if (!result.toDouble())
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalAsDouble> Can't convert value to a double, expr = %s", expr.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dest = result.getDouble();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExpr::evalAsBool(const std::string &expr, bool &dest)
|
|
||||||
{
|
|
||||||
CInterfaceExprValue result;
|
|
||||||
if (!eval(expr, result)) return false;
|
|
||||||
if (!result.toBool())
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalAsBool> Can't convert value to a boolean, expr = %s", expr.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dest = result.getBool();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExpr::evalAsString(const std::string &expr, std::string &dest)
|
|
||||||
{
|
|
||||||
CInterfaceExprValue result;
|
|
||||||
if (!eval(expr, result)) return false;
|
|
||||||
if (!result.toString())
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExpr::evalAsString> Can't convert value to a string, expr = %s", expr.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dest = result.getString();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
//==================================================================
|
|
||||||
//==================================================================
|
|
||||||
//==================================================================
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::toBool()
|
|
||||||
{
|
|
||||||
switch(_Type)
|
|
||||||
{
|
|
||||||
case Boolean: return true;
|
|
||||||
case Integer: setBool(_IntegerValue != 0); return true;
|
|
||||||
case Double: setBool(_DoubleValue != 0); return true;
|
|
||||||
case String: return evalBoolean(_StringValue.toString().c_str()) != NULL;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::toInteger()
|
|
||||||
{
|
|
||||||
switch(_Type)
|
|
||||||
{
|
|
||||||
case Boolean: setInteger(_BoolValue ? 1 : 0); return true;
|
|
||||||
case Integer: return true;
|
|
||||||
case Double: setInteger((sint64) _DoubleValue); return true;
|
|
||||||
case String:
|
|
||||||
if (evalNumber(_StringValue.toString().c_str())) return toInteger();
|
|
||||||
return false;
|
|
||||||
case RGBA: setInteger((sint64) _RGBAValue); return true;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::toDouble()
|
|
||||||
{
|
|
||||||
switch(_Type)
|
|
||||||
{
|
|
||||||
case Boolean: setDouble(_BoolValue ? 1 : 0); return true;
|
|
||||||
case Integer: setDouble((double) _IntegerValue); return true;
|
|
||||||
case Double: return true;
|
|
||||||
case String:
|
|
||||||
if (evalNumber(_StringValue.toString().c_str())) return toBool();
|
|
||||||
return false;
|
|
||||||
case RGBA: setDouble((double) _RGBAValue); return true;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::toString()
|
|
||||||
{
|
|
||||||
switch(_Type)
|
|
||||||
{
|
|
||||||
case Boolean: setString(_BoolValue ? "true" : "false"); return true;
|
|
||||||
case Integer: setString(NLMISC::toString(_IntegerValue)); return true;
|
|
||||||
case Double: setString(NLMISC::toString("%.2f", _DoubleValue)); return true;
|
|
||||||
case String: return true;
|
|
||||||
case RGBA:
|
|
||||||
{
|
|
||||||
uint r,g,b,a;
|
|
||||||
r= (_RGBAValue&0xff);
|
|
||||||
g= ((_RGBAValue>>8)&0xff);
|
|
||||||
b= ((_RGBAValue>>16)&0xff);
|
|
||||||
a= ((_RGBAValue>>24)&0xff);
|
|
||||||
setString(NLMISC::toString("%d %d %d %d", r, g, b, a));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::toRGBA()
|
|
||||||
{
|
|
||||||
switch(_Type)
|
|
||||||
{
|
|
||||||
case RGBA: return true;
|
|
||||||
case Integer: setRGBA(NLMISC::CRGBA((uint8)(_IntegerValue&0xff), (uint8)((_IntegerValue>>8)&0xff),
|
|
||||||
(uint8)((_IntegerValue>>16)&0xff), (uint8)((_IntegerValue>>24)&0xff))); return true;
|
|
||||||
case String:
|
|
||||||
setRGBA(stringToRGBA(_StringValue.toString().c_str())); return true;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::isNumerical() const
|
|
||||||
{
|
|
||||||
return _Type == Boolean || _Type == Integer || _Type == Double;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExprValue::initFromString(const char *expr)
|
|
||||||
{
|
|
||||||
nlassert(expr);
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (isdigit(*expr) || *expr == '.' || *expr == '-') return evalNumber(expr);
|
|
||||||
switch(*expr)
|
|
||||||
{
|
|
||||||
case 't':
|
|
||||||
case 'T':
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
return evalBoolean(expr);
|
|
||||||
case '\'':
|
|
||||||
return evalString(expr);
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExprValue::evalBoolean(const char *expr)
|
|
||||||
{
|
|
||||||
nlassert(expr);
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (toupper(expr[0]) == 'T' &&
|
|
||||||
toupper(expr[1]) == 'R' &&
|
|
||||||
toupper(expr[2]) == 'U' &&
|
|
||||||
toupper(expr[3]) == 'E')
|
|
||||||
{
|
|
||||||
setBool(true);
|
|
||||||
return expr + 4;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (toupper(expr[0]) == 'F' &&
|
|
||||||
toupper(expr[1]) == 'A' &&
|
|
||||||
toupper(expr[2]) == 'L' &&
|
|
||||||
toupper(expr[3]) == 'S' &&
|
|
||||||
toupper(expr[4]) == 'E')
|
|
||||||
{
|
|
||||||
setBool(false);
|
|
||||||
return expr + 5;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExprValue::evalNumber(const char *expr)
|
|
||||||
{
|
|
||||||
bool negative;
|
|
||||||
bool hasPoint = false;
|
|
||||||
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
|
|
||||||
if (*expr == '-')
|
|
||||||
{
|
|
||||||
negative = true;
|
|
||||||
++ expr;
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
negative = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *start = expr;
|
|
||||||
while (*expr == '.' || isdigit(*expr))
|
|
||||||
{
|
|
||||||
if (*expr == '.') hasPoint = true;
|
|
||||||
++ expr;
|
|
||||||
}
|
|
||||||
if (start == expr) return NULL;
|
|
||||||
if (!hasPoint)
|
|
||||||
{
|
|
||||||
sint64 value = 0;
|
|
||||||
// this is an integer
|
|
||||||
for (const char *nbPtr = start; nbPtr < expr; ++ nbPtr)
|
|
||||||
{
|
|
||||||
value *= 10;
|
|
||||||
value += (sint64) (*nbPtr - '0');
|
|
||||||
}
|
|
||||||
setInteger(negative ? - value : value);
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
else // floating point value : use scanf
|
|
||||||
{
|
|
||||||
// well, for now, we only parse a float
|
|
||||||
float value;
|
|
||||||
std::string floatValue(start, expr - start);
|
|
||||||
if (fromString(floatValue, value))
|
|
||||||
{
|
|
||||||
setDouble(negative ? - value : value);
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const char *CInterfaceExprValue::evalString(const char *expr)
|
|
||||||
{
|
|
||||||
expr = skipBlank(expr);
|
|
||||||
if (*expr != '\'') return NULL;
|
|
||||||
++expr;
|
|
||||||
std::string str;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (expr == '\0')
|
|
||||||
{
|
|
||||||
nlwarning("CInterfaceExprValue::evalString : end of buffer encountered in a string");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (*expr == '\'')
|
|
||||||
{
|
|
||||||
++ expr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*expr == '\\') // special char
|
|
||||||
{
|
|
||||||
++ expr;
|
|
||||||
switch (*expr)
|
|
||||||
{
|
|
||||||
case 't': str += '\t'; break;
|
|
||||||
case 'r': str += '\r'; break;
|
|
||||||
case 'n': str += '\n'; break;
|
|
||||||
case '\'': str += '\''; break;
|
|
||||||
case '"': str += '"'; break;
|
|
||||||
case '\\': str += '\\'; break;
|
|
||||||
case '\n':
|
|
||||||
case '\r':
|
|
||||||
// string continue on next line, so do nothing
|
|
||||||
break;
|
|
||||||
case '\0': continue;
|
|
||||||
default:
|
|
||||||
nlwarning("CInterfaceExprValue::evalString : unknown escape sequence : \\%c", *expr);
|
|
||||||
if (*expr) str += *expr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*expr == '\n' || *expr == '\r')
|
|
||||||
{
|
|
||||||
nlwarning("CInterfaceExprValue::evalString : line break encountered in a string");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
str += *expr;
|
|
||||||
}
|
|
||||||
++ expr;
|
|
||||||
}
|
|
||||||
setString(str);
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::toType(TType type)
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case Boolean: return toBool();
|
|
||||||
case Integer: return toInteger();
|
|
||||||
case Double: return toDouble();
|
|
||||||
case String: return toString();
|
|
||||||
case RGBA: return toRGBA();
|
|
||||||
default: return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
void CInterfaceExprValue::clean()
|
|
||||||
{
|
|
||||||
switch (_Type)
|
|
||||||
{
|
|
||||||
case String: _StringValue.clear(); break;
|
|
||||||
case UserType: delete _UserTypeValue; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
void CInterfaceExprValue::setUserType(CInterfaceExprUserType *value)
|
|
||||||
{
|
|
||||||
if (_Type == UserType && value == _UserTypeValue) return;
|
|
||||||
clean();
|
|
||||||
_Type = UserType;
|
|
||||||
_UserTypeValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
bool CInterfaceExprValue::getBool() const
|
|
||||||
{
|
|
||||||
if (_Type != Boolean)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getBool> bad type!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return _BoolValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
sint64 CInterfaceExprValue::getInteger() const
|
|
||||||
{
|
|
||||||
if (_Type != Integer)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getInteger> bad type!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return _IntegerValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
double CInterfaceExprValue::getDouble() const
|
|
||||||
{
|
|
||||||
if (_Type != Double)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getDouble> bad type!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return _DoubleValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
std::string CInterfaceExprValue::getString() const
|
|
||||||
{
|
|
||||||
if (_Type != String)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getString> bad type!");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return _StringValue.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
NLMISC::CRGBA CInterfaceExprValue::getRGBA() const
|
|
||||||
{
|
|
||||||
if (_Type != RGBA)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getRGBA> bad type!");
|
|
||||||
return CRGBA::White;
|
|
||||||
}
|
|
||||||
NLMISC::CRGBA col;
|
|
||||||
col.R = (uint8)(_RGBAValue&0xff);
|
|
||||||
col.G = (uint8)((_RGBAValue>>8)&0xff);
|
|
||||||
col.B = (uint8)((_RGBAValue>>16)&0xff);
|
|
||||||
col.A = (uint8)((_RGBAValue>>24)&0xff);
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
const ucstring &CInterfaceExprValue::getUCString() const
|
|
||||||
{
|
|
||||||
if (_Type != String)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getString> bad type!");
|
|
||||||
static ucstring emptyString;
|
|
||||||
return emptyString;
|
|
||||||
}
|
|
||||||
return _StringValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
CInterfaceExprUserType *CInterfaceExprValue::getUserType() const
|
|
||||||
{
|
|
||||||
if (_Type != UserType)
|
|
||||||
{
|
|
||||||
nlwarning("<CInterfaceExprValue::getUserType> bad type!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return _UserTypeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
CInterfaceExprValue::CInterfaceExprValue(const CInterfaceExprValue &other) : _Type(NoType)
|
|
||||||
{
|
|
||||||
*this = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==================================================================
|
|
||||||
CInterfaceExprValue &CInterfaceExprValue::operator = (const CInterfaceExprValue &other)
|
|
||||||
{
|
|
||||||
if (this != &other)
|
|
||||||
{
|
|
||||||
clean();
|
|
||||||
switch(other._Type)
|
|
||||||
{
|
|
||||||
case Boolean: _BoolValue = other._BoolValue; break;
|
|
||||||
case Integer: _IntegerValue = other._IntegerValue; break;
|
|
||||||
case Double: _DoubleValue = other._DoubleValue; break;
|
|
||||||
case String: _StringValue = other._StringValue; break;
|
|
||||||
case RGBA: _RGBAValue = other._RGBAValue; break;
|
|
||||||
case UserType:
|
|
||||||
if (other._UserTypeValue != NULL)
|
|
||||||
{
|
|
||||||
_UserTypeValue = other._UserTypeValue->clone();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_UserTypeValue = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NoType: break;
|
|
||||||
default:
|
|
||||||
nlwarning("<CInterfaceExprValue::operator=> bad source type") ;
|
|
||||||
return *this;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_Type = other._Type;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,242 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program 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 Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CL_INTERFACE_EXPR_H
|
|
||||||
#define CL_INTERFACE_EXPR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "nel/misc/ucstring.h"
|
|
||||||
#include "nel/misc/rgba.h"
|
|
||||||
|
|
||||||
namespace NLMISC{
|
|
||||||
class ICDBNode;
|
|
||||||
class CCDBNodeLeaf;
|
|
||||||
class CCDBNodeBranch;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct CInterfaceExprUserType;
|
|
||||||
class CInterfaceExprNode;
|
|
||||||
|
|
||||||
/** a value that can be returned by a CInterfaceExpr instance
|
|
||||||
* It supports basic type;
|
|
||||||
* It can be extended by user defined types
|
|
||||||
*/
|
|
||||||
class CInterfaceExprValue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum TType { Boolean = 0, Integer, Double, String, RGBA, UserType, NoType };
|
|
||||||
public:
|
|
||||||
// default ctor
|
|
||||||
CInterfaceExprValue() : _Type(NoType) {}
|
|
||||||
// copy ctor
|
|
||||||
CInterfaceExprValue(const CInterfaceExprValue &other);
|
|
||||||
// assignment operator
|
|
||||||
CInterfaceExprValue &operator = (const CInterfaceExprValue &other);
|
|
||||||
// dtor
|
|
||||||
~CInterfaceExprValue() { clean(); }
|
|
||||||
|
|
||||||
TType getType() const { return _Type; }
|
|
||||||
// get. Should be used only if the type is valid
|
|
||||||
bool getBool() const;
|
|
||||||
sint64 getInteger() const;
|
|
||||||
double getDouble() const;
|
|
||||||
std::string getString() const;
|
|
||||||
NLMISC::CRGBA getRGBA() const;
|
|
||||||
const ucstring &getUCString() const;
|
|
||||||
CInterfaceExprUserType *getUserType() const;
|
|
||||||
// set
|
|
||||||
void setBool(bool value) { clean(); _Type = Boolean; _BoolValue = value; }
|
|
||||||
void setInteger(sint64 value) { clean(); _Type = Integer; _IntegerValue = value; }
|
|
||||||
void setDouble(double value) { clean(); _Type = Double; _DoubleValue = value; }
|
|
||||||
void setString(const std::string &value) { clean(); _Type = String; _StringValue = value; }
|
|
||||||
void setUCString(const ucstring &value) { clean(); _Type = String; _StringValue = value; }
|
|
||||||
void setRGBA(NLMISC::CRGBA value) { clean(); _Type = RGBA; _RGBAValue = (uint32)(value.R+(value.G<<8)+(value.B<<16)+(value.A<<24)); }
|
|
||||||
void setUserType(CInterfaceExprUserType *value);
|
|
||||||
// reset this object to initial state (no type)
|
|
||||||
void clean();
|
|
||||||
// conversions. They return true if success
|
|
||||||
bool toBool();
|
|
||||||
bool toInteger();
|
|
||||||
bool toDouble();
|
|
||||||
bool toString();
|
|
||||||
bool toType(TType type);
|
|
||||||
bool toRGBA();
|
|
||||||
// test if the value if a bool, double, or integer
|
|
||||||
bool isNumerical() const;
|
|
||||||
/** evaluate a from a string
|
|
||||||
* \param expr : where to start the evaluation
|
|
||||||
* \return the position following the token, or NULL if the parsing failed
|
|
||||||
*/
|
|
||||||
const char *initFromString(const char *expr);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
private:
|
|
||||||
TType _Type;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
bool _BoolValue;
|
|
||||||
sint64 _IntegerValue;
|
|
||||||
double _DoubleValue;
|
|
||||||
CInterfaceExprUserType *_UserTypeValue;
|
|
||||||
uint32 _RGBAValue;
|
|
||||||
};
|
|
||||||
ucstring _StringValue; // well, can't fit in union, unless we do some horrible hack..
|
|
||||||
private:
|
|
||||||
const char *evalBoolean(const char *expr);
|
|
||||||
const char *evalNumber(const char *expr);
|
|
||||||
const char *evalString(const char *expr);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for user defined types that are use by the 'CInterfaceExprValue' class
|
|
||||||
* Derivers should include the 'clone' method
|
|
||||||
*
|
|
||||||
* CInterfaceExprValue instances have ownership of this object.
|
|
||||||
*
|
|
||||||
* \author Nicolas Vizerie
|
|
||||||
* \author Nevrax France
|
|
||||||
* \date 2003
|
|
||||||
*/
|
|
||||||
struct CInterfaceExprUserType
|
|
||||||
{
|
|
||||||
// cloning method
|
|
||||||
virtual CInterfaceExprUserType *clone() const = 0;
|
|
||||||
// dtor
|
|
||||||
virtual ~CInterfaceExprUserType() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** Evaluate expressions used in interface.
|
|
||||||
* It can retrieve values from the database.
|
|
||||||
* It can also build a list of database values it depends of.
|
|
||||||
*
|
|
||||||
* An expression can be :
|
|
||||||
*
|
|
||||||
* - a string : 'toto', 'abcd', 'a\nbcd', 'a\\t', the escape sequences are the one of C
|
|
||||||
* - a integer 1, 2, 3
|
|
||||||
* - a double 1.1, 2.2
|
|
||||||
* - a database entry : @ui:interface:toto:truc. If the address is a leaf, it returns the leaf value and put an observer on it. If not a leaf, it returns 0, but put an observer on it.
|
|
||||||
* - a database indirection @db:value[db:index] is replaced by @db:value0 if db:index == 0 for example
|
|
||||||
* - a user function call : fct(expr0, epxr1, ...).
|
|
||||||
*
|
|
||||||
* NB : The lua language has been integrated since then (2005), and should be more suited
|
|
||||||
* for most of the tasks.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* \author Nicolas Vizerie
|
|
||||||
* \author Nevrax France
|
|
||||||
* \date 2002
|
|
||||||
*/
|
|
||||||
class CInterfaceExpr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// list of argument for a function
|
|
||||||
typedef std::vector<CInterfaceExprValue> TArgList;
|
|
||||||
/** prototype of a user callable function
|
|
||||||
* It should return true if the result is meaningful. If not, the rest of the evaluation is stopped
|
|
||||||
*/
|
|
||||||
typedef bool (* TUserFct) (TArgList &args, CInterfaceExprValue &result);
|
|
||||||
public:
|
|
||||||
|
|
||||||
// release memory
|
|
||||||
static void release();
|
|
||||||
|
|
||||||
/** This try to eval the provided expression.
|
|
||||||
* - This returns a result
|
|
||||||
* - This eventually fill a vector with a set of database entries it has dependencies on
|
|
||||||
* \param expr The expression to evaluate
|
|
||||||
* \param result The result value
|
|
||||||
* \param nodes If not NULL, will be filled with the database nodes this expression depends on
|
|
||||||
* Node will only be inserted once, so we end up with a set of node (not ordered)
|
|
||||||
* \param noFctCalls when set to true, the terminal function calls will not be made, so the evaluation is only used to see which database entries the expression depends on.
|
|
||||||
*/
|
|
||||||
static bool eval(const std::string &expr, CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> *nodes = NULL, bool noFctCalls = false);
|
|
||||||
|
|
||||||
/** Build a tree from the given expression so that it can be evaluated quickly.
|
|
||||||
* This is useful for a fixed expression that must be evaluated often
|
|
||||||
*/
|
|
||||||
static CInterfaceExprNode *buildExprTree(const std::string &expr);
|
|
||||||
|
|
||||||
|
|
||||||
/** Register a function that can have several arguments
|
|
||||||
* // NB : this is case sensitive
|
|
||||||
*/
|
|
||||||
static void registerUserFct(const char *name, TUserFct fct);
|
|
||||||
// Simple evaluations
|
|
||||||
static bool evalAsInt(const std::string &expr, sint64 &dest);
|
|
||||||
static bool evalAsDouble(const std::string &expr, double &dest);
|
|
||||||
static bool evalAsBool(const std::string &expr, bool &dest);
|
|
||||||
static bool evalAsString(const std::string &expr, std::string &dest);
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
private:
|
|
||||||
// map of user functions
|
|
||||||
typedef std::map<std::string, TUserFct> TUserFctMap;
|
|
||||||
private:
|
|
||||||
static TUserFctMap *_UserFct;
|
|
||||||
private:
|
|
||||||
/** eval the value of a single expression
|
|
||||||
* \return position to the next valid character
|
|
||||||
*/
|
|
||||||
static const char *evalExpr(const char *expr, CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> *nodes, bool noFctCalls);
|
|
||||||
static const char *evalFct(const char *expr,CInterfaceExprValue &result,std::vector<NLMISC::ICDBNode *> *nodes, bool noFctCalls);
|
|
||||||
static const char *evalDBEntry(const char *expr,CInterfaceExprValue &result,std::vector<NLMISC::ICDBNode *> *nodes);
|
|
||||||
public:
|
|
||||||
static const char *unpackDBentry(const char *expr, std::vector<NLMISC::ICDBNode *> *nodes, std::string &dest, bool *hasIndirections = NULL);
|
|
||||||
|
|
||||||
/** Build tree of a single expression
|
|
||||||
* \return position to the next valid character
|
|
||||||
*/
|
|
||||||
private:
|
|
||||||
static const char *buildExprTree(const char *expr, CInterfaceExprNode *&result);
|
|
||||||
static const char *buildFctNode(const char *expr, CInterfaceExprNode *&result);
|
|
||||||
static const char *buildDBEntryNode(const char *expr,CInterfaceExprNode *&result);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// helper macro to register user functions at startup
|
|
||||||
#define REGISTER_INTERFACE_USER_FCT(name, fct) \
|
|
||||||
const struct __InterUserFctRegister__##fct\
|
|
||||||
{\
|
|
||||||
__InterUserFctRegister__##fct() { CInterfaceExpr::registerUserFct(name, fct); }\
|
|
||||||
} __InterUserFctRegisterInstance__##fct;
|
|
||||||
|
|
||||||
|
|
||||||
// helper macro to declare a user function
|
|
||||||
// the code must follow
|
|
||||||
// arguments are available in 'args', result should be put in 'result'
|
|
||||||
#define DECLARE_INTERFACE_USER_FCT(name) \
|
|
||||||
bool name(CInterfaceExpr::TArgList &args, CInterfaceExprValue &result)
|
|
||||||
|
|
||||||
|
|
||||||
// helper macro to declare a C constant mirroring
|
|
||||||
#define DECLARE_INTERFACE_CONSTANT(_name, _cconst) \
|
|
||||||
static DECLARE_INTERFACE_USER_FCT(_name) \
|
|
||||||
{ \
|
|
||||||
result.setInteger(_cconst); \
|
|
||||||
return true; \
|
|
||||||
} \
|
|
||||||
REGISTER_INTERFACE_USER_FCT(#_name, _name)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program 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 Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "stdpch.h"
|
|
||||||
#include "interface_expr_node.h"
|
|
||||||
#include "nel/misc/cdb_leaf.h"
|
|
||||||
#include "nel/misc/cdb_branch.h"
|
|
||||||
|
|
||||||
using NLMISC::ICDBNode;
|
|
||||||
using NLMISC::CCDBNodeBranch;
|
|
||||||
using NLMISC::CCDBNodeLeaf;
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
void CInterfaceExprNodeValue::eval(CInterfaceExprValue &result)
|
|
||||||
{
|
|
||||||
result = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeValue::evalWithDepends(CInterfaceExprValue &result, std::vector<ICDBNode *> &/* nodes */)
|
|
||||||
{
|
|
||||||
result = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeValue::getDepends(std::vector<ICDBNode *> &/* nodes */)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
void CInterfaceExprNodeValueFnCall::eval(CInterfaceExprValue &result)
|
|
||||||
{
|
|
||||||
nlassert(Func);
|
|
||||||
uint numParams = (uint)Params.size();
|
|
||||||
std::vector<CInterfaceExprValue> params(numParams);
|
|
||||||
for(uint k = 0; k < numParams; ++k)
|
|
||||||
{
|
|
||||||
Params[k]->eval(params[k]);
|
|
||||||
}
|
|
||||||
Func(params, result); // do actual call
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeValueFnCall::evalWithDepends(CInterfaceExprValue &result, std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
nlassert(Func);
|
|
||||||
uint numParams = (uint)Params.size();
|
|
||||||
std::vector<CInterfaceExprValue> params(numParams);
|
|
||||||
for(uint k = 0; k < numParams; ++k)
|
|
||||||
{
|
|
||||||
Params[k]->evalWithDepends(params[k], nodes);
|
|
||||||
}
|
|
||||||
Func(params, result); // do actual call
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeValueFnCall::getDepends(std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
uint numParams = (uint)Params.size();
|
|
||||||
for(uint k = 0; k < numParams; ++k)
|
|
||||||
{
|
|
||||||
Params[k]->getDepends(nodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CInterfaceExprNodeValueFnCall::~CInterfaceExprNodeValueFnCall()
|
|
||||||
{
|
|
||||||
for(uint k = 0; k < Params.size(); ++k)
|
|
||||||
{
|
|
||||||
delete Params[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
void CInterfaceExprNodeDBLeaf::eval(CInterfaceExprValue &result)
|
|
||||||
{
|
|
||||||
nlassert(Leaf);
|
|
||||||
result.setInteger(Leaf->getValue64());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeDBLeaf::evalWithDepends(CInterfaceExprValue &result,std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
nlassert(Leaf);
|
|
||||||
result.setInteger(Leaf->getValue64());
|
|
||||||
if (std::find(nodes.begin(), nodes.end(), Leaf) == nodes.end())
|
|
||||||
{
|
|
||||||
nodes.push_back(Leaf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeDBLeaf::getDepends(std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
nlassert(Leaf);
|
|
||||||
if (std::find(nodes.begin(), nodes.end(), Leaf) == nodes.end())
|
|
||||||
{
|
|
||||||
nodes.push_back(Leaf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
void CInterfaceExprNodeDBBranch::eval(CInterfaceExprValue &result)
|
|
||||||
{
|
|
||||||
nlassert(Branch);
|
|
||||||
result.setInteger(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeDBBranch::evalWithDepends(CInterfaceExprValue &result,std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
nlassert(Branch);
|
|
||||||
result.setInteger(0);
|
|
||||||
if (std::find(nodes.begin(), nodes.end(), Branch) == nodes.end())
|
|
||||||
{
|
|
||||||
nodes.push_back(Branch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeDBBranch::getDepends(std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
nlassert(Branch);
|
|
||||||
if (std::find(nodes.begin(), nodes.end(), Branch) == nodes.end())
|
|
||||||
{
|
|
||||||
nodes.push_back(Branch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
void CInterfaceExprNodeDependantDBRead::eval(CInterfaceExprValue &result)
|
|
||||||
{
|
|
||||||
// no gain there, but barely used
|
|
||||||
CInterfaceExpr::eval(Expr, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeDependantDBRead::evalWithDepends(CInterfaceExprValue &result, std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
CInterfaceExpr::eval(Expr, result, &nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInterfaceExprNodeDependantDBRead::getDepends(std::vector<ICDBNode *> &nodes)
|
|
||||||
{
|
|
||||||
CInterfaceExprValue dummyResult;
|
|
||||||
CInterfaceExpr::eval(Expr, dummyResult, &nodes, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program 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 Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CL_INTERFACE_EXPR_NODE_H
|
|
||||||
#define CL_INTERFACE_EXPR_NODE_H
|
|
||||||
|
|
||||||
#include "interface_expr.h"
|
|
||||||
|
|
||||||
/** Base node of an interface expression parse tree
|
|
||||||
* \author Nicolas Vizerie
|
|
||||||
* \author Nevrax France
|
|
||||||
* \date 2003
|
|
||||||
*/
|
|
||||||
class CInterfaceExprNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~CInterfaceExprNode() {}
|
|
||||||
// eval result of expression, and eventually get the nodes the epression depends on
|
|
||||||
virtual void eval(CInterfaceExprValue &result) = 0;
|
|
||||||
// The same, but get db nodes the expression depends on (appended to vector)
|
|
||||||
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes) = 0;
|
|
||||||
// Get dependencies of the node (appended to vector)
|
|
||||||
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
/** A constant value already parsed by interface (in a interface expr parse tree)
|
|
||||||
*/
|
|
||||||
class CInterfaceExprNodeValue : public CInterfaceExprNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CInterfaceExprValue Value;
|
|
||||||
public:
|
|
||||||
virtual void eval(CInterfaceExprValue &result);
|
|
||||||
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
};
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
/** A fct call (in a interface expr parse tree)
|
|
||||||
*/
|
|
||||||
class CInterfaceExprNodeValueFnCall : public CInterfaceExprNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CInterfaceExpr::TUserFct Func;
|
|
||||||
// list of parameters
|
|
||||||
std::vector<CInterfaceExprNode *> Params;
|
|
||||||
public:
|
|
||||||
virtual void eval(CInterfaceExprValue &result);
|
|
||||||
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
virtual ~CInterfaceExprNodeValueFnCall();
|
|
||||||
};
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
/** A db leaf read (in a interface expr parse tree)
|
|
||||||
*/
|
|
||||||
class CInterfaceExprNodeDBLeaf : public CInterfaceExprNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class NLMISC::CCDBNodeLeaf *Leaf;
|
|
||||||
public:
|
|
||||||
virtual void eval(CInterfaceExprValue &result);
|
|
||||||
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
};
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
/** A db branch read (in a interface expr parse tree)
|
|
||||||
*/
|
|
||||||
class CInterfaceExprNodeDBBranch : public CInterfaceExprNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class NLMISC::CCDBNodeBranch *Branch;
|
|
||||||
public:
|
|
||||||
virtual void eval(CInterfaceExprValue &result);
|
|
||||||
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
};
|
|
||||||
|
|
||||||
// *******************************************************************************************************
|
|
||||||
/** A dependant db read (in a interface expr parse tree)
|
|
||||||
* This is rarely used so no real optim there..
|
|
||||||
*/
|
|
||||||
class CInterfaceExprNodeDependantDBRead : public CInterfaceExprNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::string Expr;
|
|
||||||
public:
|
|
||||||
virtual void eval(CInterfaceExprValue &result);
|
|
||||||
virtual void evalWithDepends(CInterfaceExprValue &result, std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
virtual void getDepends(std::vector<NLMISC::ICDBNode *> &nodes);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
|
|
||||||
// client
|
// client
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "ctrl_sheet_selection.h"
|
#include "ctrl_sheet_selection.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
// game_share
|
// game_share
|
||||||
|
@ -519,7 +519,7 @@ static DECLARE_INTERFACE_USER_FCT(userFctGetProp)
|
||||||
|
|
||||||
string sTmp = args[0].getString();
|
string sTmp = args[0].getString();
|
||||||
std::vector<CInterfaceLink::CTargetInfo> targetsVector;
|
std::vector<CInterfaceLink::CTargetInfo> targetsVector;
|
||||||
CInterfaceParser::splitLinkTargets(sTmp, NULL, targetsVector);
|
CInterfaceLink::splitLinkTargets(sTmp, NULL, targetsVector);
|
||||||
|
|
||||||
if (targetsVector.empty())
|
if (targetsVector.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
// Interface
|
// Interface
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_element.h"
|
#include "interface_element.h"
|
||||||
#include "chat_window.h"
|
#include "chat_window.h"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
// client
|
// client
|
||||||
#include "../sheet_manager.h"
|
#include "../sheet_manager.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "dbctrl_sheet.h"
|
#include "dbctrl_sheet.h"
|
||||||
#include "ctrl_sheet_selection.h"
|
#include "ctrl_sheet_selection.h"
|
||||||
#include "dbgroup_list_sheet.h"
|
#include "dbgroup_list_sheet.h"
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
|
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
#include "interface_link.h"
|
#include "interface_link.h"
|
||||||
#include "interface_expr.h"
|
|
||||||
#include "interface_element.h"
|
#include "interface_element.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "interface_expr_node.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
|
#include "nel/gui/interface_expr_node.h"
|
||||||
#include "nel/gui/reflect.h"
|
#include "nel/gui/reflect.h"
|
||||||
#include "nel/gui/db_manager.h"
|
#include "nel/gui/db_manager.h"
|
||||||
#include "nel/misc/cdb_branch.h"
|
#include "nel/misc/cdb_branch.h"
|
||||||
|
@ -444,6 +444,88 @@ void CInterfaceLink::removeAllLinks()
|
||||||
nlassert(_LinkList.empty());
|
nlassert(_LinkList.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
bool CInterfaceLink::splitLinkTarget(const std::string &target, CInterfaceGroup *parentGroup, std::string &propertyName, CInterfaceElement *&targetElm)
|
||||||
|
{
|
||||||
|
// the last token of the target gives the name of the property
|
||||||
|
std::string::size_type lastPos = target.find_last_of(':');
|
||||||
|
if (lastPos == (target.length() - 1))
|
||||||
|
{
|
||||||
|
// todo hulud interface syntax error
|
||||||
|
nlwarning("The target should at least contains a path and a property as follow 'path:property'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string elmPath;
|
||||||
|
std::string elmProp;
|
||||||
|
CInterfaceElement *elm = NULL;
|
||||||
|
if (parentGroup)
|
||||||
|
{
|
||||||
|
if (lastPos == std::string::npos)
|
||||||
|
{
|
||||||
|
elmProp = target;
|
||||||
|
elm = parentGroup;
|
||||||
|
elmPath = "current";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elmProp = target.substr(lastPos + 1);
|
||||||
|
elmPath = parentGroup->getId() + ":" + target.substr(0, lastPos);
|
||||||
|
elm = parentGroup->getElement(elmPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!elm)
|
||||||
|
{
|
||||||
|
// try the absolute adress of the element
|
||||||
|
elmPath = target.substr(0, lastPos);
|
||||||
|
elm = CInterfaceManager::getInstance()->getElementFromId(elmPath);
|
||||||
|
elmProp = target.substr(lastPos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!elm)
|
||||||
|
{
|
||||||
|
// todo hulud interface syntax error
|
||||||
|
nlwarning("<splitLinkTarget> can't find target link %s", elmPath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
targetElm = elm;
|
||||||
|
propertyName = elmProp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
bool CInterfaceLink::splitLinkTargets(const std::string &targets, CInterfaceGroup *parentGroup,std::vector<CInterfaceLink::CTargetInfo> &targetsVect)
|
||||||
|
{
|
||||||
|
std::vector<std::string> targetNames;
|
||||||
|
NLMISC::splitString(targets, ",", targetNames);
|
||||||
|
targetsVect.clear();
|
||||||
|
targetsVect.reserve(targetNames.size());
|
||||||
|
bool everythingOk = true;
|
||||||
|
for (uint k = 0; k < targetNames.size(); ++k)
|
||||||
|
{
|
||||||
|
CInterfaceLink::CTargetInfo ti;
|
||||||
|
std::string::size_type startPos = targetNames[k].find_first_not_of(" ");
|
||||||
|
if(startPos == std::string::npos)
|
||||||
|
{
|
||||||
|
// todo hulud interface syntax error
|
||||||
|
nlwarning("<splitLinkTargets> empty target encountered");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string::size_type lastPos = targetNames[k].find_last_not_of(" ");
|
||||||
|
|
||||||
|
if (!splitLinkTarget(targetNames[k].substr(startPos, lastPos - startPos+1), parentGroup, ti.PropertyName, ti.Elem))
|
||||||
|
{
|
||||||
|
// todo hulud interface syntax error
|
||||||
|
nlwarning("<splitLinkTargets> Can't get link target");
|
||||||
|
everythingOk = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
targetsVect.push_back(ti);
|
||||||
|
}
|
||||||
|
return everythingOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================
|
//===========================================================
|
||||||
void CInterfaceLink::checkNbRefs()
|
void CInterfaceLink::checkNbRefs()
|
||||||
{
|
{
|
||||||
|
@ -470,7 +552,7 @@ void CInterfaceLink::setTargetProperty (const std::string &Target, const CInt
|
||||||
if (pIG != NULL)
|
if (pIG != NULL)
|
||||||
{
|
{
|
||||||
std::vector<CTargetInfo> vTargets;
|
std::vector<CTargetInfo> vTargets;
|
||||||
CInterfaceParser::splitLinkTargets(Target, pIG, vTargets);
|
splitLinkTargets(Target, pIG, vTargets);
|
||||||
if ((vTargets.size() > 0) && (vTargets[0].Elem))
|
if ((vTargets.size() > 0) && (vTargets[0].Elem))
|
||||||
{
|
{
|
||||||
vTargets[0].affect(val);
|
vTargets[0].affect(val);
|
||||||
|
|
|
@ -25,13 +25,14 @@
|
||||||
namespace NLGUI
|
namespace NLGUI
|
||||||
{
|
{
|
||||||
class CReflectedProperty;
|
class CReflectedProperty;
|
||||||
|
class CInterfaceExprValue;
|
||||||
|
class CInterfaceExprNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CInterfaceElement;
|
class CInterfaceElement;
|
||||||
class CInterfaceExprValue;
|
|
||||||
class CInterfaceGroup;
|
class CInterfaceGroup;
|
||||||
class CInterfaceExprNode;
|
|
||||||
|
|
||||||
using namespace NLGUI;
|
using namespace NLGUI;
|
||||||
|
|
||||||
|
@ -115,6 +116,16 @@ public:
|
||||||
static void setTargetProperty (const std::string & Target, const CInterfaceExprValue &val);
|
static void setTargetProperty (const std::string & Target, const CInterfaceExprValue &val);
|
||||||
|
|
||||||
static bool isUpdatingAllLinks() { return _UpdateAllLinks; }
|
static bool isUpdatingAllLinks() { return _UpdateAllLinks; }
|
||||||
|
|
||||||
|
/** From a target name of a link, retrieve the target element and its target target property
|
||||||
|
* \return true if the target is valid
|
||||||
|
*/
|
||||||
|
static bool splitLinkTarget(const std::string &target, CInterfaceGroup *parentGroup, std::string &propertyName, CInterfaceElement *&targetElm);
|
||||||
|
|
||||||
|
/** From several target names of a link (seprated by ','), retrieve the target elements and their target properties
|
||||||
|
* \return true if all targets are valid
|
||||||
|
*/
|
||||||
|
static bool splitLinkTargets(const std::string &targets, CInterfaceGroup *parentGroup, std::vector<CInterfaceLink::CTargetInfo> &targetsVect);
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
private:
|
private:
|
||||||
friend struct CRemoveTargetPred;
|
friend struct CRemoveTargetPred;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "../client_cfg.h"
|
#include "../client_cfg.h"
|
||||||
#include "encyclopedia_manager.h"
|
#include "encyclopedia_manager.h"
|
||||||
// Expr
|
// Expr
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "register_interface_elements.h"
|
#include "register_interface_elements.h"
|
||||||
// Action / Observers
|
// Action / Observers
|
||||||
#include "action_handler.h"
|
#include "action_handler.h"
|
||||||
|
|
|
@ -1403,7 +1403,7 @@ bool CInterfaceParser::parseLink(xmlNodePtr cur, CInterfaceGroup * parentGroup)
|
||||||
ptr = (char*) xmlGetProp (cur, (xmlChar*)"target");
|
ptr = (char*) xmlGetProp (cur, (xmlChar*)"target");
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
splitLinkTargets(std::string((const char*)ptr), parentGroup, targets);
|
CInterfaceLink::splitLinkTargets(std::string((const char*)ptr), parentGroup, targets);
|
||||||
}
|
}
|
||||||
// optional action handler
|
// optional action handler
|
||||||
std::string action;
|
std::string action;
|
||||||
|
@ -2925,88 +2925,6 @@ bool CInterfaceParser::parseSheetSelection(xmlNodePtr cur)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
bool CInterfaceParser::splitLinkTarget(const std::string &target, CInterfaceGroup *parentGroup, std::string &propertyName, CInterfaceElement *&targetElm)
|
|
||||||
{
|
|
||||||
// the last token of the target gives the name of the property
|
|
||||||
std::string::size_type lastPos = target.find_last_of(':');
|
|
||||||
if (lastPos == (target.length() - 1))
|
|
||||||
{
|
|
||||||
// todo hulud interface syntax error
|
|
||||||
nlwarning("The target should at least contains a path and a property as follow 'path:property'");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string elmPath;
|
|
||||||
std::string elmProp;
|
|
||||||
CInterfaceElement *elm = NULL;
|
|
||||||
if (parentGroup)
|
|
||||||
{
|
|
||||||
if (lastPos == std::string::npos)
|
|
||||||
{
|
|
||||||
elmProp = target;
|
|
||||||
elm = parentGroup;
|
|
||||||
elmPath = "current";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
elmProp = target.substr(lastPos + 1);
|
|
||||||
elmPath = parentGroup->getId() + ":" + target.substr(0, lastPos);
|
|
||||||
elm = parentGroup->getElement(elmPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!elm)
|
|
||||||
{
|
|
||||||
// try the absolute adress of the element
|
|
||||||
elmPath = target.substr(0, lastPos);
|
|
||||||
elm = CInterfaceManager::getInstance()->getElementFromId(elmPath);
|
|
||||||
elmProp = target.substr(lastPos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!elm)
|
|
||||||
{
|
|
||||||
// todo hulud interface syntax error
|
|
||||||
nlwarning("<CInterfaceParser::splitLinkTarget> can't find target link %s", elmPath.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
targetElm = elm;
|
|
||||||
propertyName = elmProp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
bool CInterfaceParser::splitLinkTargets(const std::string &targets, CInterfaceGroup *parentGroup,std::vector<CInterfaceLink::CTargetInfo> &targetsVect)
|
|
||||||
{
|
|
||||||
std::vector<std::string> targetNames;
|
|
||||||
NLMISC::splitString(targets, ",", targetNames);
|
|
||||||
targetsVect.clear();
|
|
||||||
targetsVect.reserve(targetNames.size());
|
|
||||||
bool everythingOk = true;
|
|
||||||
for (uint k = 0; k < targetNames.size(); ++k)
|
|
||||||
{
|
|
||||||
CInterfaceLink::CTargetInfo ti;
|
|
||||||
std::string::size_type startPos = targetNames[k].find_first_not_of(" ");
|
|
||||||
if(startPos == std::string::npos)
|
|
||||||
{
|
|
||||||
// todo hulud interface syntax error
|
|
||||||
nlwarning("<CInterfaceParser::splitLinkTargets> empty target encountered");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::string::size_type lastPos = targetNames[k].find_last_not_of(" ");
|
|
||||||
|
|
||||||
if (!splitLinkTarget(targetNames[k].substr(startPos, lastPos - startPos+1), parentGroup, ti.PropertyName, ti.Elem))
|
|
||||||
{
|
|
||||||
// todo hulud interface syntax error
|
|
||||||
nlwarning("<CInterfaceParser::splitLinkTargets> Can't get link target");
|
|
||||||
everythingOk = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
targetsVect.push_back(ti);
|
|
||||||
}
|
|
||||||
return everythingOk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
bool CInterfaceParser::addLink(CInterfaceLink *link, const std::string &id)
|
bool CInterfaceParser::addLink(CInterfaceLink *link, const std::string &id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -214,16 +214,6 @@ public:
|
||||||
void setDefine(const std::string &id, const std::string &value);
|
void setDefine(const std::string &id, const std::string &value);
|
||||||
// @}
|
// @}
|
||||||
|
|
||||||
/** From a target name of a link, retrieve the target element and its target target property
|
|
||||||
* \return true if the target is valid
|
|
||||||
*/
|
|
||||||
static bool splitLinkTarget(const std::string &target, CInterfaceGroup *parentGroup, std::string &propertyName, CInterfaceElement *&targetElm);
|
|
||||||
|
|
||||||
/** From several target names of a link (seprated by ','), retrieve the target elements and their target properties
|
|
||||||
* \return true if all targets are valid
|
|
||||||
*/
|
|
||||||
static bool splitLinkTargets(const std::string &targets, CInterfaceGroup *parentGroup, std::vector<CInterfaceLink::CTargetInfo> &targetsVect);
|
|
||||||
|
|
||||||
/// \name Dynamic links mgt
|
/// \name Dynamic links mgt
|
||||||
// @{
|
// @{
|
||||||
/** Associate the given dynamic link with an ID
|
/** Associate the given dynamic link with an ID
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
#include "game_share/people_pd.h"
|
#include "game_share/people_pd.h"
|
||||||
#include "group_tree.h"
|
#include "group_tree.h"
|
||||||
#include "interface_link.h"
|
#include "interface_link.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "people_interraction.h"
|
#include "people_interraction.h"
|
||||||
#include "nel/misc/algo.h"
|
#include "nel/misc/algo.h"
|
||||||
#include "nel/misc/file.h"
|
#include "nel/misc/file.h"
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "dbgroup_combo_box.h"
|
#include "dbgroup_combo_box.h"
|
||||||
#include "group_container.h"
|
#include "group_container.h"
|
||||||
#include "group_modal_get_key.h"
|
#include "group_modal_get_key.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
|
|
||||||
// tmp
|
// tmp
|
||||||
#include "../r2/editor.h"
|
#include "../r2/editor.h"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
// client
|
// client
|
||||||
#include "../string_manager_client.h"
|
#include "../string_manager_client.h"
|
||||||
#include "people_interraction.h"
|
#include "people_interraction.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "action_handler.h"
|
#include "action_handler.h"
|
||||||
#include "action_handler_misc.h"
|
#include "action_handler_misc.h"
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
#include "group_menu.h"
|
#include "group_menu.h"
|
||||||
#include "../client_chat_manager.h"
|
#include "../client_chat_manager.h"
|
||||||
#include "../string_manager_client.h"
|
#include "../string_manager_client.h"
|
||||||
#include "interface_expr.h"
|
#include "nel/gui/interface_expr.h"
|
||||||
#include "ctrl_button.h"
|
#include "ctrl_button.h"
|
||||||
#include "ctrl_text_button.h"
|
#include "ctrl_text_button.h"
|
||||||
#include "filtered_chat_summary.h"
|
#include "filtered_chat_summary.h"
|
||||||
|
@ -1027,7 +1027,7 @@ class CHandlerChatGroupFilter : public IActionHandler
|
||||||
CCtrlTabButton *pTabButton= dynamic_cast<CCtrlTabButton*>(pCaller);
|
CCtrlTabButton *pTabButton= dynamic_cast<CCtrlTabButton*>(pCaller);
|
||||||
if(pTabButton)
|
if(pTabButton)
|
||||||
{
|
{
|
||||||
CRGBA stdColor= stringToRGBA(pIM->getDefine("chat_group_tab_color_normal").c_str());
|
CRGBA stdColor= CRGBA::stringToRGBA(pIM->getDefine("chat_group_tab_color_normal").c_str());
|
||||||
pTabButton->setTextColorNormal(stdColor);
|
pTabButton->setTextColorNormal(stdColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -976,21 +976,6 @@ std::string getStringCategoryIfAny(const ucstring &src, ucstring &dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NLMISC::CRGBA stringToRGBA(const char *ptr)
|
|
||||||
{
|
|
||||||
if (!ptr) return NLMISC::CRGBA::White;
|
|
||||||
int r = 255, g = 255, b = 255, a = 255;
|
|
||||||
sscanf (ptr, "%d %d %d %d", &r, &g, &b, &a);
|
|
||||||
NLMISC::clamp (r, 0, 255);
|
|
||||||
NLMISC::clamp (g, 0, 255);
|
|
||||||
NLMISC::clamp (b, 0, 255);
|
|
||||||
NLMISC::clamp (a, 0, 255);
|
|
||||||
return CRGBA(r,g,b,a);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
inline bool isSeparator (ucchar c)
|
inline bool isSeparator (ucchar c)
|
||||||
|
|
|
@ -166,9 +166,6 @@ std::string getStringCategory(const ucstring &src, ucstring &dest, bool alwaysAd
|
||||||
// Get the category from the string (src="&SYS&Who are you?" and dest="Who are you?" and return "SYS"), if no category, return ""
|
// Get the category from the string (src="&SYS&Who are you?" and dest="Who are you?" and return "SYS"), if no category, return ""
|
||||||
std::string getStringCategoryIfAny(const ucstring &src, ucstring &dest);
|
std::string getStringCategoryIfAny(const ucstring &src, ucstring &dest);
|
||||||
|
|
||||||
NLMISC::CRGBA stringToRGBA(const char *ptr);
|
|
||||||
|
|
||||||
|
|
||||||
// Number of shortcut
|
// Number of shortcut
|
||||||
#define RYZOM_MAX_SHORTCUT 20
|
#define RYZOM_MAX_SHORTCUT 20
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue