Avoid having to use 'set' action handler, which parses the value expression on every use, in interface links by implementing use of cdb nodes as targets
--HG-- branch : kaetemi-optimize
This commit is contained in:
parent
19a8b48355
commit
5a9537dfcc
6 changed files with 119 additions and 9 deletions
|
@ -66,6 +66,11 @@ namespace NLGUI
|
|||
*/
|
||||
bool affect(const CInterfaceExprValue &value);
|
||||
};
|
||||
struct CCDBTargetInfo
|
||||
{
|
||||
NLMISC::CRefPtr<NLMISC::CCDBNodeLeaf> Leaf;
|
||||
std::string LeafName;
|
||||
};
|
||||
|
||||
|
||||
/// Updates triggered interface links when triggered by the observed branch
|
||||
|
@ -85,7 +90,7 @@ namespace NLGUI
|
|||
* If there are no target element, the link is permanent (removed at exit)
|
||||
* NB : The target is not updated during this call.
|
||||
*/
|
||||
bool init(const std::vector<CTargetInfo> &targets, const std::string &expr, const std::string &actionHandler, const std::string &ahParams, const std::string &ahCond, CInterfaceGroup *parent);
|
||||
bool init(const std::vector<CTargetInfo> &targets, const std::vector<CCDBTargetInfo> &cdbTargets, const std::string &expr, const std::string &actionHandler, const std::string &ahParams, const std::string &ahCond, CInterfaceGroup *parent);
|
||||
// force all the links that have been created to update their targets. This can be called when the interface has been loaded, and when the databse entries have been retrieved.
|
||||
static void updateAllLinks();
|
||||
// force all trigered links to be updated
|
||||
|
@ -119,6 +124,7 @@ namespace NLGUI
|
|||
* \return true if all targets are valid
|
||||
*/
|
||||
static bool splitLinkTargets(const std::string &targets, CInterfaceGroup *parentGroup, std::vector<CInterfaceLink::CTargetInfo> &targetsVect);
|
||||
static bool splitLinkTargetsExt(const std::string &targets, CInterfaceGroup *parentGroup, std::vector<CInterfaceLink::CTargetInfo> &targetsVect, std::vector<CInterfaceLink::CCDBTargetInfo> &cdbTargetsVect);
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
private:
|
||||
friend struct CRemoveTargetPred;
|
||||
|
@ -135,6 +141,7 @@ namespace NLGUI
|
|||
typedef std::vector<NLMISC::ICDBNode *> TNodeVect;
|
||||
private:
|
||||
std::vector<CTarget> _Targets;
|
||||
std::vector<CCDBTargetInfo> _CDBTargets;
|
||||
TNodeVect _ObservedNodes;
|
||||
std::string _Expr;
|
||||
CInterfaceExprNode *_ParseTree;
|
||||
|
|
|
@ -2325,7 +2325,8 @@ namespace NLGUI
|
|||
_LUAOnDbChange[dbList]= newLink;
|
||||
// Init and attach to list of untargeted links
|
||||
std::vector<CInterfaceLink::CTargetInfo> noTargets;
|
||||
newLink->init(noTargets, NLMISC::toString("depends(%s)", dbList.c_str()), "lua", script, "", this);
|
||||
std::vector<CInterfaceLink::CCDBTargetInfo> noCdbTargets;
|
||||
newLink->init(noTargets, noCdbTargets, NLMISC::toString("depends(%s)", dbList.c_str()), "lua", script, "", this);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -194,7 +194,7 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
//===========================================================
|
||||
bool CInterfaceLink::init(const std::vector<CTargetInfo> &targets, const std::string &expr, const std::string &actionHandler, const std::string &ahParams, const std::string &ahCond, CInterfaceGroup *parentGroup)
|
||||
bool CInterfaceLink::init(const std::vector<CTargetInfo> &targets, const std::vector<CCDBTargetInfo> &cdbTargets, const std::string &expr, const std::string &actionHandler, const std::string &ahParams, const std::string &ahCond, CInterfaceGroup *parentGroup)
|
||||
{
|
||||
CInterfaceExprValue result;
|
||||
// Build the parse tree
|
||||
|
@ -240,6 +240,7 @@ namespace NLGUI
|
|||
// There are no target for this link, so, put in a dedicated list to ensure that the link will be destroyed at exit
|
||||
_LinksWithNoTarget.push_back(TLinkSmartPtr(this));
|
||||
}
|
||||
_CDBTargets = cdbTargets;
|
||||
|
||||
// create observers
|
||||
createObservers(_ObservedNodes);
|
||||
|
@ -365,12 +366,41 @@ namespace NLGUI
|
|||
}
|
||||
}
|
||||
}
|
||||
if (_CDBTargets.size())
|
||||
{
|
||||
CInterfaceExprValue resultCopy = result;
|
||||
if (resultCopy.toInteger())
|
||||
{
|
||||
sint64 resultValue = resultCopy.getInteger();
|
||||
for (uint k = 0; k < _CDBTargets.size(); ++k)
|
||||
{
|
||||
NLMISC::CCDBNodeLeaf *node = _CDBTargets[k].Leaf;
|
||||
if (!node)
|
||||
{
|
||||
node = _CDBTargets[k].Leaf = NLGUI::CDBManager::getInstance()->getDbProp(_CDBTargets[k].LeafName, false);
|
||||
}
|
||||
if (node)
|
||||
{
|
||||
// assuming setvalue64 always works
|
||||
node->setValue64(resultValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("CInterfaceLink::update: Node does not exist: '%s'", _CDBTargets[k].LeafName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("CInterfaceLink::update: Result conversion to db target failed");
|
||||
}
|
||||
}
|
||||
// if there's an action handler, execute it
|
||||
if (!_ActionHandler.empty())
|
||||
{
|
||||
// If there is a condition, test it.
|
||||
bool launch = _AHCond.empty();
|
||||
if (_AHCondParsed)
|
||||
if (_AHCondParsed) // todo: maybe makes more sense to make condition also cover target
|
||||
{
|
||||
CInterfaceExprValue result;
|
||||
_AHCondParsed->eval(result);
|
||||
|
@ -525,6 +555,11 @@ namespace NLGUI
|
|||
continue;
|
||||
}
|
||||
std::string::size_type lastPos = targetNames[k].find_last_not_of(" ");
|
||||
if (startPos >= lastPos)
|
||||
{
|
||||
nlwarning("<splitLinkTargets> empty target encountered");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!splitLinkTarget(targetNames[k].substr(startPos, lastPos - startPos+1), parentGroup, ti.PropertyName, ti.Elem))
|
||||
{
|
||||
|
@ -539,6 +574,70 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
bool CInterfaceLink::splitLinkTargetsExt(const std::string &targets, CInterfaceGroup *parentGroup,std::vector<CInterfaceLink::CTargetInfo> &targetsVect, std::vector<CInterfaceLink::CCDBTargetInfo> &cdbTargetsVect)
|
||||
{
|
||||
std::vector<std::string> targetNames;
|
||||
NLMISC::splitString(targets, ",", targetNames);
|
||||
targetsVect.clear();
|
||||
targetsVect.reserve(targetNames.size());
|
||||
cdbTargetsVect.clear(); // no reserve because less used
|
||||
bool everythingOk = true;
|
||||
for (uint k = 0; k < targetNames.size(); ++k)
|
||||
{
|
||||
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 (startPos >= (lastPos+1))
|
||||
{
|
||||
nlwarning("<splitLinkTargets> empty target encountered");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (targetNames[k][startPos] == '@')
|
||||
{
|
||||
CInterfaceLink::CCDBTargetInfo ti;
|
||||
ti.LeafName = targetNames[k].substr((startPos+1), (lastPos+1) - (startPos+1));
|
||||
// Do not allow Write on SERVER: or LOCAL:
|
||||
static const std::string dbServer= "SERVER:";
|
||||
static const std::string dbLocal= "LOCAL:";
|
||||
static const std::string dbLocalR2= "LOCAL:R2";
|
||||
if( (0==ti.LeafName.compare(0, dbServer.size(), dbServer)) ||
|
||||
(0==ti.LeafName.compare(0, dbLocal.size(), dbLocal))
|
||||
)
|
||||
{
|
||||
if (0!=ti.LeafName.compare(0, dbLocalR2.size(), dbLocalR2))
|
||||
{
|
||||
//nlwarning("You are not allowed to write on 'SERVER:...' or 'LOCAL:...' database");
|
||||
nlstop;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ti.Leaf = NLGUI::CDBManager::getInstance()->getDbProp(ti.LeafName, false);
|
||||
cdbTargetsVect.push_back(ti);
|
||||
}
|
||||
else
|
||||
{
|
||||
CInterfaceLink::CTargetInfo ti;
|
||||
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()
|
||||
{
|
||||
|
|
|
@ -997,6 +997,7 @@ namespace NLGUI
|
|||
|
||||
|
||||
std::vector<CInterfaceLink::CTargetInfo> targets;
|
||||
std::vector<CInterfaceLink::CCDBTargetInfo> cdbTargets;
|
||||
|
||||
ptr = (char*) xmlGetProp (cur, (xmlChar*)"target");
|
||||
std::string target;
|
||||
|
@ -1004,7 +1005,7 @@ namespace NLGUI
|
|||
{
|
||||
target = std::string( (const char*)ptr );
|
||||
if( !editorMode )
|
||||
CInterfaceLink::splitLinkTargets(std::string((const char*)ptr), parentGroup, targets);
|
||||
CInterfaceLink::splitLinkTargetsExt(std::string((const char*)ptr), parentGroup, targets, cdbTargets);
|
||||
}
|
||||
|
||||
// optional action handler
|
||||
|
@ -1022,7 +1023,7 @@ namespace NLGUI
|
|||
if( !editorMode )
|
||||
{
|
||||
CInterfaceLink *il = new CInterfaceLink;
|
||||
il->init(targets, expr, action, params, cond, parentGroup); // init will add 'il' in the list of link present in 'elm'
|
||||
il->init(targets, cdbTargets, expr, action, params, cond, parentGroup); // init will add 'il' in the list of link present in 'elm'
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -425,14 +425,15 @@ class CActionHandlerAddLink : public IActionHandler
|
|||
}
|
||||
|
||||
std::vector<CInterfaceLink::CTargetInfo> targetsVect;
|
||||
bool result = CInterfaceLink::splitLinkTargets(targets, parentGroup, targetsVect);
|
||||
std::vector<CInterfaceLink::CCDBTargetInfo> cdbTargetsVect;
|
||||
bool result = CInterfaceLink::splitLinkTargetsExt(targets, parentGroup, targetsVect, cdbTargetsVect);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("<CActionHandlerAddLink> Couldn't parse all links");
|
||||
}
|
||||
// add the link
|
||||
CInterfaceLink *il = new CInterfaceLink;
|
||||
il->init(targetsVect, expr, ah, ahparam, ahcond, parentGroup);
|
||||
il->init(targetsVect, cdbTargetsVect, expr, ah, ahparam, ahcond, parentGroup);
|
||||
CInterfaceManager *im = CInterfaceManager::getInstance();
|
||||
CWidgetManager::getInstance()->getParser()->addLink(il, id);
|
||||
il->update();
|
||||
|
|
|
@ -558,7 +558,8 @@ void CPeopleInterraction::createTeamList()
|
|||
{
|
||||
CInterfaceLink *il = new CInterfaceLink;
|
||||
vector<CInterfaceLink::CTargetInfo> targets;
|
||||
il->init(targets, sExpr, sAction, sParams, sCond, TeamChat->getContainer());
|
||||
vector<CInterfaceLink::CCDBTargetInfo> cdbTargets;
|
||||
il->init(targets, cdbTargets, sExpr, sAction, sParams, sCond, TeamChat->getContainer());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue