Refactored the static branch observing code into a new class CCDBBranchObservingHandler. The CDB system *should* be fully reusable now!

--HG--
branch : cdb-refactoring
hg/feature/sse2
dfighter1985 13 years ago
parent 46b139fb67
commit 982c57b70f

@ -32,11 +32,20 @@ namespace NLMISC{
class CCDBNodeBranch : public ICDBNode
{
public:
/// Triggered when the branch observers are updated
class IBranchObserverCallFlushObserver : public CRefCount{
class ICDBDBBranchObserverHandle
{
public:
virtual ~IBranchObserverCallFlushObserver(){}
virtual void onObserverCallFlush() = 0;
virtual ~ICDBDBBranchObserverHandle(){}
virtual ICDBNode* owner() = 0;
virtual IPropertyObserver* observer() = 0;
virtual bool observesLeaf( const std::string &leafName ) = 0;
virtual bool inList( uint list ) = 0;
virtual void addToFlushableList() = 0;
virtual void removeFromFlushableList( uint list ) = 0;
virtual void removeFromFlushableList() = 0;
};
// default constructor
@ -194,7 +203,7 @@ public:
* and setting a branch observer on it, except you don't need to change your database paths
* and update large amounts of code!).
*/
void addBranchObserver(IPropertyObserver* observer, const std::vector<std::string>& positiveLeafNameFilter=std::vector<std::string>());
void addBranchObserver( ICDBDBBranchObserverHandle* handle, const std::vector<std::string>& positiveLeafNameFilter=std::vector<std::string>());
/**
* Easy version of addBranchObserver() (see above).
@ -202,7 +211,7 @@ public:
* "" -> this node
* "FOO:BAR" -> sub-branch "BAR" of "FOO" which is a sub-branch of this node
*/
void addBranchObserver(const char *dbPathFromThisNode, ICDBNode::IPropertyObserver& observer, const char **positiveLeafNameFilter=NULL, uint positiveLeafNameFilterSize=0);
void addBranchObserver( ICDBDBBranchObserverHandle *handle, const char *dbPathFromThisNode, const char **positiveLeafNameFilter=NULL, uint positiveLeafNameFilterSize=0);
// Remove observer from all sub-leaves
bool removeBranchObserver(IPropertyObserver* observer);
@ -212,83 +221,14 @@ public:
virtual bool isLeaf() const { return false; }
/** Update all observers of branchs that have been modified
*/
static void flushObserversCalls();
private:
static void triggerFlushObservers();
public:
static void addFlushObserver( IBranchObserverCallFlushObserver *observer );
static void removeFlushObserver( IBranchObserverCallFlushObserver *observer );
// mark this branch and parent branch as 'modified'. This is usually called by sub-leaves
void linkInModifiedNodeList(TStringId modifiedLeafName);
void onLeafChanged( TStringId leafName );
/// Find a subnode at this level
ICDBNode * find (const std::string &nodeName);
// reset all static mappings
static void reset();
protected:
/** Struct identifying an observer of a db branch
* This struct can be linked in a list so that we can update observers only once per pass.
* An observer that watch a whole branch can be updated once and only once after each element of the branch has been modified
*/
class CDBBranchObsInfo
{
public:
CRefPtr<IPropertyObserver> Observer;
// 2 linked list are required : while the observer is notified, it can triger one other observer, so we must link it in another list
bool Touched[2];
CDBBranchObsInfo *PrevNotifiedObserver[2]; // NULL means this is the head
CDBBranchObsInfo *NextNotifiedObserver[2];
ICDBNode *Owner;
// If non-empty, only a leaf whose name is found here will notify something
// This is equivalent to creating a sub-branch containing only the specified leaves
// and setting a branch observer on it, except you don't need to change your database paths
// and update large amounts of code and script!
std::vector<TStringId> PositiveLeafNameFilter;
public:
/// Constructor. See above for usage of positiveLeafNameFilter.
CDBBranchObsInfo(IPropertyObserver *obs = NULL, ICDBNode *owner = NULL, const std::vector<std::string>& positiveLeafNameFilter=std::vector<std::string>())
{
Owner = owner;
Observer = obs;
Touched[0] = Touched[1] = false;
PrevNotifiedObserver[0] = PrevNotifiedObserver[1] = NULL;
NextNotifiedObserver[0] = NextNotifiedObserver[1] = NULL;
for (std::vector<std::string>::const_iterator ipf=positiveLeafNameFilter.begin(); ipf!=positiveLeafNameFilter.end(); ++ipf)
{
PositiveLeafNameFilter.push_back(ICDBNode::getStringId(*ipf)); // the ids are also mapped at database init, we don't need to unmap them in destructor
}
}
~CDBBranchObsInfo()
{
// should have been unlinked
nlassert(Touched[0] == false);
nlassert(Touched[1] == false);
nlassert(PrevNotifiedObserver[0] == NULL);
nlassert(PrevNotifiedObserver[1] == NULL);
nlassert(NextNotifiedObserver[0] == NULL);
nlassert(NextNotifiedObserver[1] == NULL);
}
// Unlink from the given list. This also clear the '_Touched' flag
void unlink(uint list);
void link(uint list, TStringId modifiedLeafName);
};
typedef std::list<CDBBranchObsInfo> TObsList; // must use a list because pointers on CDBObserverInfo instances must remains valids
protected:
typedef std::list< ICDBDBBranchObserverHandle* > TObserverHandleList;
CCDBNodeBranch *_Parent;
@ -303,25 +243,10 @@ protected:
bool _Sorted : 1;
// observers for this node or branch
TObsList _Observers;
friend class CDBBranchObsInfo;
// Global list of modified nodes
static CDBBranchObsInfo *_FirstNotifiedObs[2];
static CDBBranchObsInfo *_LastNotifiedObs[2];
static uint _CurrNotifiedObsList; // 0 or 1 => tell in which list observers of modified values must be added
// current & next observers being notified : if such observer if removed during notification, pointer will be valids
static CDBBranchObsInfo *_CurrNotifiedObs;
static CDBBranchObsInfo *_NextNotifiedObs;
TObserverHandleList observerHandles;
/// called by clear
void removeAllBranchObserver();
void removeBranchInfoIt(TObsList::iterator it);
private:
static std::vector< IBranchObserverCallFlushObserver* > flushObservers;
};
}

@ -0,0 +1,128 @@
// 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 CDB_BRANCH_OBS_HNDLR
#define CDB_BRANCH_OBS_HNDLR
#include "nel/misc/cdb_branch.h"
namespace NLMISC{
/**
@brief Manages the CDB branch observers.
When a leaf's data changes, it notifies the branch, which then marks the observers as notifiable.
The marked observers can then be notified and flushed on request.
*/
class CCDBBranchObservingHandler{
enum{
MAX_OBS_LST = 2
};
public:
CCDBBranchObservingHandler();
~CCDBBranchObservingHandler();
/// Notifies the observers, and flushes the list
void flushObserverCalls();
void reset();
void addBranchObserver( CCDBNodeBranch *branch, ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter );
void addBranchObserver( CCDBNodeBranch *branch, const char *dbPathFromThisNode, ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize );
void removeBranchObserver( CCDBNodeBranch *branch, ICDBNode::IPropertyObserver* observer );
void removeBranchObserver( CCDBNodeBranch *branch, const char *dbPathFromThisNode, ICDBNode::IPropertyObserver &observer );
///Observer for branch observer flush events.
class IBranchObserverCallFlushObserver : public CRefCount{
public:
virtual ~IBranchObserverCallFlushObserver(){}
virtual void onObserverCallFlush() = 0;
};
private:
void triggerFlushObservers();
public:
void addFlushObserver( IBranchObserverCallFlushObserver *observer );
void removeFlushObserver( IBranchObserverCallFlushObserver *observer );
private:
/**
@brief Handle to a branch observer.
The handle stores the owner branch, the observer and remembers if it's marked for notifying the observer.
Also it manages adding/removing itself to/from the marked observer handles list, which is handled by CCDBBranchObservingHandler.
*/
class CCDBDBBranchObserverHandle : public CCDBNodeBranch::ICDBDBBranchObserverHandle{
public:
CCDBDBBranchObserverHandle( ICDBNode::IPropertyObserver *observer, CCDBNodeBranch *owner, CCDBBranchObservingHandler *handler );
~CCDBDBBranchObserverHandle();
ICDBNode* owner(){ return _owner; }
ICDBNode::IPropertyObserver* observer(){ return _observer; }
bool observesLeaf( const std::string &leafName );
bool inList( uint list );
void addToFlushableList();
void removeFromFlushableList( uint list );
void removeFromFlushableList();
private:
bool _inList[ MAX_OBS_LST ];
std::vector< std::string > _observedLeaves;
CCDBNodeBranch *_owner;
NLMISC::CRefPtr< ICDBNode::IPropertyObserver > _observer;
CCDBBranchObservingHandler *_handler;
};
std::list< CCDBNodeBranch::ICDBDBBranchObserverHandle* > flushableObservers[ MAX_OBS_LST ];
CCDBNodeBranch::ICDBDBBranchObserverHandle *currentHandle;
uint currentList;
std::vector< IBranchObserverCallFlushObserver* > flushObservers;
};
}
#endif

@ -59,33 +59,6 @@ using namespace std;
namespace NLMISC{
/////////////
// GLOBALS //
/////////////
CCDBNodeBranch::CDBBranchObsInfo *CCDBNodeBranch::_FirstNotifiedObs[2] = { NULL, NULL };
CCDBNodeBranch::CDBBranchObsInfo *CCDBNodeBranch::_LastNotifiedObs[2] = { NULL, NULL };
CCDBNodeBranch::CDBBranchObsInfo *CCDBNodeBranch::_CurrNotifiedObs = NULL;
CCDBNodeBranch::CDBBranchObsInfo *CCDBNodeBranch::_NextNotifiedObs = NULL;
//
uint CCDBNodeBranch::_CurrNotifiedObsList = 0;
std::vector< CCDBNodeBranch::IBranchObserverCallFlushObserver* > CCDBNodeBranch::flushObservers;
// reset all static data
void CCDBNodeBranch::reset()
{
_FirstNotifiedObs[0] = NULL;
_FirstNotifiedObs[1] = NULL;
_LastNotifiedObs[0] = NULL;
_LastNotifiedObs[1] = NULL;
_CurrNotifiedObsList = 0;
_CurrNotifiedObs = NULL;
_NextNotifiedObs = NULL;
}
//-----------------------------------------------
// init
//
@ -626,155 +599,14 @@ void CCDBNodeBranch::removeNode (const CTextId& id)
delete pNode;
}
//-----------------------------------------------
void CCDBNodeBranch::flushObserversCalls()
{
// nlassert(_CrtCheckMemory());
_CurrNotifiedObs = _FirstNotifiedObs[_CurrNotifiedObsList];
while (_CurrNotifiedObs)
{
// modified node should now store them in other list when they're modified
_CurrNotifiedObsList = 1 - _CurrNotifiedObsList;
// switch list so that modified node are stored in the other list
while (_CurrNotifiedObs)
{
_NextNotifiedObs = _CurrNotifiedObs->NextNotifiedObserver[1 - _CurrNotifiedObsList];
nlassert(_CurrNotifiedObs->Owner);
if (_CurrNotifiedObs->Observer)
_CurrNotifiedObs->Observer->update(_CurrNotifiedObs->Owner);
if (_CurrNotifiedObs) // this may be modified by the call (if current observer is removed)
{
_CurrNotifiedObs->unlink(1 - _CurrNotifiedObsList);
}
_CurrNotifiedObs = _NextNotifiedObs;
}
nlassert(_FirstNotifiedObs[1 - _CurrNotifiedObsList] == NULL);
nlassert(_LastNotifiedObs[1 - _CurrNotifiedObsList] == NULL);
triggerFlushObservers();
// examine other list to see if nodes have been registered
_CurrNotifiedObs = _FirstNotifiedObs[_CurrNotifiedObsList];
}
triggerFlushObservers();
// nlassert(_CrtCheckMemory());
}
void CCDBNodeBranch::triggerFlushObservers()
{
for( std::vector< IBranchObserverCallFlushObserver* >::iterator itr = flushObservers.begin(); itr != flushObservers.end(); itr++ )
{
(*itr)->onObserverCallFlush();
}
}
void CCDBNodeBranch::addFlushObserver( CCDBNodeBranch::IBranchObserverCallFlushObserver *observer )
{
std::vector< IBranchObserverCallFlushObserver* >::iterator itr
= std::find( flushObservers.begin(), flushObservers.end(), observer );
// Already exists
if( itr != flushObservers.end() )
return;
flushObservers.push_back( observer );
}
void CCDBNodeBranch::removeFlushObserver( CCDBNodeBranch::IBranchObserverCallFlushObserver *observer )
void CCDBNodeBranch::onLeafChanged( NLMISC::TStringId leafName )
{
std::vector< IBranchObserverCallFlushObserver* >::iterator itr
= std::find( flushObservers.begin(), flushObservers.end(), observer );
// Isn't in our list
if( itr == flushObservers.end() )
return;
for( TObserverHandleList::iterator itr = observerHandles.begin(); itr != observerHandles.end(); ++itr )
if( (*itr)->observesLeaf( *leafName ) )
(*itr)->addToFlushableList();
flushObservers.erase( itr );
}
//-----------------------------------------------
void CCDBNodeBranch::CDBBranchObsInfo::link(uint list, TStringId modifiedLeafName)
{
// If there a filter set?
if (!PositiveLeafNameFilter.empty())
{
// Don't link if modifiedLeafName is not in the filter
if (std::find(PositiveLeafNameFilter.begin(), PositiveLeafNameFilter.end(), modifiedLeafName) == PositiveLeafNameFilter.end())
return;
}
// nlassert(_CrtCheckMemory());
nlassert(list < 2);
if (Touched[list]) return; // already inserted in list
Touched[list] = true;
nlassert(!PrevNotifiedObserver[list]);
nlassert(!NextNotifiedObserver[list]);
if (!_FirstNotifiedObs[list])
{
_FirstNotifiedObs[list] = _LastNotifiedObs[list] = this;
}
else
{
nlassert(!_LastNotifiedObs[list]->NextNotifiedObserver[list]);
_LastNotifiedObs[list]->NextNotifiedObserver[list] = this;
PrevNotifiedObserver[list] = _LastNotifiedObs[list];
_LastNotifiedObs[list] = this;
}
// nlassert(_CrtCheckMemory());
}
//-----------------------------------------------
void CCDBNodeBranch::CDBBranchObsInfo::unlink(uint list)
{
// nlassert(_CrtCheckMemory());
nlassert(list < 2);
if (!Touched[list])
{
// not linked in this list
nlassert(PrevNotifiedObserver[list] == NULL);
nlassert(NextNotifiedObserver[list] == NULL);
return;
}
if (PrevNotifiedObserver[list])
{
PrevNotifiedObserver[list]->NextNotifiedObserver[list] = NextNotifiedObserver[list];
}
else
{
// this was the first node
_FirstNotifiedObs[list] = NextNotifiedObserver[list];
}
if (NextNotifiedObserver[list])
{
NextNotifiedObserver[list]->PrevNotifiedObserver[list] = PrevNotifiedObserver[list];
}
else
{
// this was the last node
_LastNotifiedObs[list] = PrevNotifiedObserver[list];
}
PrevNotifiedObserver[list] = NULL;
NextNotifiedObserver[list] = NULL;
Touched[list] = false;
// nlassert(_CrtCheckMemory());
}
//-----------------------------------------------
void CCDBNodeBranch::linkInModifiedNodeList(TStringId modifiedLeafName)
{
// nlassert(_CrtCheckMemory());
CCDBNodeBranch *curr = this;
do
{
for(TObsList::iterator it = curr->_Observers.begin(); it != curr->_Observers.end(); ++it)
{
it->link(_CurrNotifiedObsList, modifiedLeafName);
}
curr = curr->getParent();
}
while(curr);
// nlassert(_CrtCheckMemory());
if( _Parent != NULL )
_Parent->onLeafChanged( leafName );
}
@ -847,14 +679,21 @@ bool CCDBNodeBranch::removeObserver(IPropertyObserver* observer, CTextId& id)
//-----------------------------------------------
void CCDBNodeBranch::addBranchObserver(IPropertyObserver* observer, const std::vector<std::string>& positiveLeafNameFilter)
void CCDBNodeBranch::addBranchObserver( ICDBDBBranchObserverHandle *handle, const std::vector<std::string>& positiveLeafNameFilter)
{
CDBBranchObsInfo oi(observer, this, positiveLeafNameFilter);
_Observers.push_front(oi);
CCDBNodeBranch::TObserverHandleList::iterator itr
= std::find( observerHandles.begin(), observerHandles.end(), handle );
if( itr != observerHandles.end() ){
delete handle;
return;
}
observerHandles.push_back( handle );
}
//-----------------------------------------------
void CCDBNodeBranch::addBranchObserver(const char *dbPathFromThisNode, ICDBNode::IPropertyObserver& observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize)
void CCDBNodeBranch::addBranchObserver( ICDBDBBranchObserverHandle *handle, const char *dbPathFromThisNode, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize)
{
CCDBNodeBranch *branchNode;
if (dbPathFromThisNode[0] == '\0') // empty string
@ -871,6 +710,7 @@ void CCDBNodeBranch::addBranchObserver(const char *dbPathFromThisNode, ICDBNode:
msg += " branch missing in DB";
nlerror( msg.c_str() );
delete handle;
return;
}
}
@ -879,7 +719,7 @@ void CCDBNodeBranch::addBranchObserver(const char *dbPathFromThisNode, ICDBNode:
{
leavesToMonitor[i] = string(positiveLeafNameFilter[i]);
}
branchNode->addBranchObserver(&observer, leavesToMonitor);
branchNode->addBranchObserver(handle, leavesToMonitor);
}
//-----------------------------------------------
@ -902,55 +742,38 @@ void CCDBNodeBranch::removeBranchObserver(const char *dbPathFromThisNode, ICDBNo
bool CCDBNodeBranch::removeBranchObserver(IPropertyObserver* observer)
{
bool found = false;
TObsList::iterator it = _Observers.begin();
while (it != _Observers.end())
TObserverHandleList::iterator itr = observerHandles.begin();
while( itr != observerHandles.end() )
{
if (it->Observer == observer)
if( (*itr)->observer() == observer )
{
removeBranchInfoIt(it);
it = _Observers.erase(it);
(*itr)->removeFromFlushableList();
delete *itr;
itr = observerHandles.erase( itr );
found = true;
}
else
{
++it;
++itr;
}
}
return found;
}
//-----------------------------------------------
void CCDBNodeBranch::removeAllBranchObserver()
{
TObsList::iterator it = _Observers.begin();
while (it != _Observers.end())
{
removeBranchInfoIt(it);
++it;
for( TObserverHandleList::iterator itr = observerHandles.begin();
itr != observerHandles.end(); ++itr ){
(*itr)->removeFromFlushableList();
delete *itr;
}
_Observers.clear();
}
//-----------------------------------------------
void CCDBNodeBranch::removeBranchInfoIt(TObsList::iterator it)
{
CDBBranchObsInfo *oi = &(*it);
// if this node is currenlty being notified, update iterators
if (oi == _CurrNotifiedObs)
{
_CurrNotifiedObs = NULL;
}
if (oi == _NextNotifiedObs)
{
nlassert(_CurrNotifiedObsList < 2);
_NextNotifiedObs = _NextNotifiedObs->NextNotifiedObserver[1 - _CurrNotifiedObsList];
}
// unlink observer from both update lists
oi->unlink(0);
oi->unlink(1);
observerHandles.clear();
}
//-----------------------------------------------
// Useful for find
//-----------------------------------------------

@ -0,0 +1,201 @@
// 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_branch_observing_handler.h"
namespace NLMISC{
CCDBBranchObservingHandler::CCDBBranchObservingHandler()
{
reset();
}
CCDBBranchObservingHandler::~CCDBBranchObservingHandler()
{
reset();
}
void CCDBBranchObservingHandler::flushObserverCalls()
{
bool flushed = false;
do
{
flushed = false;
uint oldList = currentList;
currentList = 1 - currentList;
std::list< CCDBNodeBranch::ICDBDBBranchObserverHandle* >::iterator itr
= flushableObservers[ oldList ].begin();
while( itr != flushableObservers[ oldList ].end() )
{
currentHandle = *itr;
++itr;
if( currentHandle->observer() != NULL )
currentHandle->observer()->update( currentHandle->owner() );
// Update might have removed it
if( currentHandle != NULL )
currentHandle->removeFromFlushableList( oldList );
currentHandle = NULL;
flushed = true;
}
triggerFlushObservers();
}while( flushed );
triggerFlushObservers();
}
void CCDBBranchObservingHandler::reset()
{
currentList = 0;
currentHandle = NULL;
for( uint i = 0; i < MAX_OBS_LST; i++ )
flushableObservers[ i ].clear();
}
void CCDBBranchObservingHandler::addBranchObserver( CCDBNodeBranch *branch, ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter )
{
if( branch == NULL )
return;
CCDBDBBranchObserverHandle *handle = new CCDBDBBranchObserverHandle( observer, branch, this );
branch->addBranchObserver( handle, positiveLeafNameFilter );
}
void CCDBBranchObservingHandler::addBranchObserver( CCDBNodeBranch *branch, const char *dbPathFromThisNode, ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize )
{
if( branch == NULL )
return;
CCDBDBBranchObserverHandle *handle = new CCDBDBBranchObserverHandle( &observer, branch, this );
branch->addBranchObserver( handle, dbPathFromThisNode, positiveLeafNameFilter, positiveLeafNameFilterSize );
}
void CCDBBranchObservingHandler::removeBranchObserver( CCDBNodeBranch *branch, ICDBNode::IPropertyObserver* observer )
{
branch->removeBranchObserver( observer );
}
void CCDBBranchObservingHandler::removeBranchObserver( CCDBNodeBranch *branch, const char *dbPathFromThisNode, ICDBNode::IPropertyObserver &observer )
{
branch->removeBranchObserver( dbPathFromThisNode, observer );
}
void CCDBBranchObservingHandler::triggerFlushObservers()
{
for( std::vector< IBranchObserverCallFlushObserver* >::iterator itr = flushObservers.begin();
itr != flushObservers.end(); itr++ )
(*itr)->onObserverCallFlush();
}
void CCDBBranchObservingHandler::addFlushObserver( IBranchObserverCallFlushObserver *observer )
{
std::vector< IBranchObserverCallFlushObserver* >::iterator itr
= std::find( flushObservers.begin(), flushObservers.end(), observer );
if( itr != flushObservers.end() )
return;
flushObservers.push_back( observer );
}
void CCDBBranchObservingHandler::removeFlushObserver( IBranchObserverCallFlushObserver *observer )
{
std::vector< IBranchObserverCallFlushObserver* >::iterator itr
= std::find( flushObservers.begin(), flushObservers.end(), observer );
if( itr == flushObservers.end() )
return;
flushObservers.erase( itr );
}
CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::CCDBDBBranchObserverHandle( NLMISC::ICDBNode::IPropertyObserver *observer, NLMISC::CCDBNodeBranch *owner, CCDBBranchObservingHandler *handler )
{
std::fill( _inList, _inList + MAX_OBS_LST, false );
_observer = observer;
_owner = owner;
_handler = handler;
}
CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::~CCDBDBBranchObserverHandle()
{
_observer = NULL;
}
bool CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::observesLeaf( const std::string &leafName )
{
if( !_observedLeaves.empty() ){
std::vector< std::string >::iterator itr
= std::find( _observedLeaves.begin(), _observedLeaves.end(), leafName );
if( itr == _observedLeaves.end() )
return false;
else
return true;
}
return true;
}
bool CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::inList( uint list )
{
return _inList[ list ];
}
void CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::addToFlushableList()
{
uint list = _handler->currentList;
if( _inList[ list ] )
return;
_handler->flushableObservers[ list ].push_back( this );
_inList[ list ] = true;
}
void CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::removeFromFlushableList( uint list )
{
if( !_inList[ list ] )
return;
std::list< CCDBNodeBranch::ICDBDBBranchObserverHandle* >::iterator itr
= std::find( _handler->flushableObservers[ list ].begin(),
_handler->flushableObservers[ list ].end(), this );
if( itr == _handler->flushableObservers[ list ].end() )
return;
if( _handler->currentHandle == this )
_handler->currentHandle = NULL;
_handler->flushableObservers[ list ].erase( itr );
_inList[ list ] = false;
}
void CCDBBranchObservingHandler::CCDBDBBranchObserverHandle::removeFromFlushableList()
{
for( uint i = 0; i < MAX_OBS_LST; i++ )
removeFromFlushableList( i );
}
}

@ -365,9 +365,7 @@ void CCDBNodeLeaf::notifyObservers()
}
// mark parent branchs
if (_Parent)
{
_Parent->linkInModifiedNodeList(_Name);
}
_Parent->onLeafChanged( _Name );
}

@ -309,7 +309,7 @@ void CCDBSynchronised::clear()
}
// clear CCDBNodeBranch static data
CCDBNodeBranch::reset();
branchObservingHandler.reset();
bankHandler.reset();
}
@ -328,6 +328,89 @@ void CCDBSynchronised::resetBank( uint gc, uint bank ){
_Database->resetNode( gc, bankHandler.getUIDForBank( bank ) );
}
void CCDBSynchronised::addBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _Database->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.addBranchObserver( b, observer, positiveLeafNameFilter );
}
void CCDBSynchronised::addBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter )
{
if( branch == NULL )
return;
branchObservingHandler.addBranchObserver( branch, observer, positiveLeafNameFilter );
}
void CCDBSynchronised::addBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _Database->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.addBranchObserver( b, dbPathFromThisNode, observer, positiveLeafNameFilter, positiveLeafNameFilterSize );
}
void CCDBSynchronised::addBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize )
{
if( branch == NULL )
return;
branchObservingHandler.addBranchObserver( branch, dbPathFromThisNode, observer, positiveLeafNameFilter, positiveLeafNameFilterSize );
}
void CCDBSynchronised::removeBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver* observer )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _Database->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.removeBranchObserver( b, observer );
}
void CCDBSynchronised::removeBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver* observer )
{
if( branch == NULL )
return;
branchObservingHandler.removeBranchObserver( branch, observer );
}
void CCDBSynchronised::removeBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _Database->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.removeBranchObserver( b, dbPathFromThisNode, observer );
}
void CCDBSynchronised::removeBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer )
{
if( branch == NULL )
return;
branchObservingHandler.removeBranchObserver( branch, dbPathFromThisNode, observer );
}
void CCDBSynchronised::addFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer )
{
if( observer == NULL )
return;
branchObservingHandler.addFlushObserver( observer );
}
void CCDBSynchronised::removeFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer )
{
if( observer == NULL )
return;
branchObservingHandler.removeFlushObserver( observer );
}
void CCDBSynchronised::flushObserverCalls()
{
branchObservingHandler.flushObserverCalls();
}
#ifdef TRACE_READ_DELTA
#undef TRACE_READ_DELTA
#endif

@ -23,6 +23,7 @@
#include "nel/misc/cdb.h"
#include "nel/misc/cdb_branch.h"
#include "nel/misc/cdb_bank_handler.h"
#include "nel/misc/cdb_branch_observing_handler.h"
/**
* Class to manage a database of properties
@ -158,6 +159,20 @@ private:
void writeInitInProgressIntoUIDB();
NLMISC::CCDBBankHandler bankHandler;
NLMISC::CCDBBranchObservingHandler branchObservingHandler;
public:
void addBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter = std::vector< std::string >() );
void addBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter = std::vector< std::string >() );
void addBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter = NULL, uint positiveLeafNameFilterSize = 0 );
void addBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize );
void removeBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver* observer );
void removeBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver* observer );
void removeBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer );
void removeBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer );
void addFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer );
void removeFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer );
void flushObserverCalls();
};

@ -390,7 +390,8 @@ bool connection (const string &cookie, const string &fsaddr)
pIM->activateMasterGroup ("ui:outgame", true);
pIM->getDbProp ("UI:CURRENT_SCREEN")->setValue32(ClientCfg.Local ? 6 : -1); // TMP TMP
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Active inputs
Actions.enable(true);
@ -553,7 +554,8 @@ bool reconnection()
pIM->activateMasterGroup ("ui:outgame", true);
pIM->getDbProp ("UI:CURRENT_SCREEN")->setValue32(-1);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Active inputs
Actions.enable(true);
@ -992,7 +994,8 @@ TInterfaceState globalMenu()
pIM->initOutGame();
pIM->activateMasterGroup ("ui:outgame", true);
pIM->getDbProp ("UI:CURRENT_SCREEN")->setValue32(2); // TMP TMP
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
pIM->getElementFromId("ui:outgame:charsel")->setActive(false);
pIM->getElementFromId("ui:outgame:charsel")->setActive(true);
// Active inputs
@ -1030,7 +1033,8 @@ TInterfaceState globalMenu()
}
}
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// check if we can send another dated block
if (NetMngr.getCurrentServerTick() != serverTick)
@ -1056,7 +1060,8 @@ TInterfaceState globalMenu()
// Interface handling & displaying (processes clicks...)
pIM->updateFrameEvents();
pIM->updateFrameViews(NULL);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Movie shooter
globalMenuMovieShooter();
@ -1121,9 +1126,11 @@ TInterfaceState globalMenu()
if (pNL != NULL)
{
pNL->setValue64 (1); // Send impulse to interface observers
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
pNL->setValue64 (0);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
}
}
else
@ -1184,9 +1191,11 @@ TInterfaceState globalMenu()
if (pNL != NULL)
{
pNL->setValue64 (1); // Send impulse to interface observers
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
pNL->setValue64 (0);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
}
}
}

@ -1267,7 +1267,8 @@ void CFarTP::sendReady()
CInputHandlerManager::getInstance()->pumpEventsNoIM();
// Update Network.
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Be nice to the system
nlSleep(100);
}
@ -1405,7 +1406,8 @@ void CFarTP::farTPmainLoop()
// Update Network.
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// TODO: resend in case the last datagram sent was lost?
// // check if we can send another dated block

@ -30,6 +30,7 @@
#include "nel/misc/cdb.h"
#include "nel/misc/cdb_leaf.h"
#include "nel/misc/cdb_branch.h"
#include "nel/misc/cdb_branch_observing_handler.h"
#include "cdb_synchronised.h"

@ -315,7 +315,8 @@ inline void waitForNetworkMessage(bool &var)
CInputHandlerManager::getInstance()->pumpEventsNoIM();
// Update network.
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Send dummy info
NetMngr.send();
// Do not take all the CPU.
@ -1216,7 +1217,8 @@ void initMainLoop()
CInputHandlerManager::getInstance()->pumpEventsNoIM();
// Update Network.
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
}
// Set the LastGameCycle

@ -186,16 +186,16 @@ void CActionPhraseFaber::launchFaberCastWindow(sint32 memoryLine, uint memoryIn
// ensure remove (if setuped before), then add
CCDBNodeBranch *branch;
branch= pIM->getDbBranch("LOCAL:INVENTORY:BAG");
if(branch) branch->removeBranchObserver(&_DBInventoryObs);
if(branch) branch->addBranchObserver(&_DBInventoryObs);
if(branch) pIM->removeBranchObserver( "LOCAL:INVENTORY:BAG",&_DBInventoryObs);
if(branch) pIM->addBranchObserver( "LOCAL:INVENTORY:BAG",&_DBInventoryObs);
// and for all pack animals
uint i;
for(i=0;i<MAX_INVENTORY_ANIMAL;i++)
{
branch= pIM->getDbBranch(toString("LOCAL:INVENTORY:PACK_ANIMAL%d", i));
if(branch) branch->removeBranchObserver(&_DBInventoryObs);
if(branch) branch->addBranchObserver(&_DBInventoryObs);
if(branch) pIM->removeBranchObserver( toString("LOCAL:INVENTORY:PACK_ANIMAL%d", i).c_str(), &_DBInventoryObs);
if(branch) pIM->addBranchObserver( toString("LOCAL:INVENTORY:PACK_ANIMAL%d", i).c_str(), &_DBInventoryObs);
}
// Add observers on animal status, cause inventory may become unavailabe during the process

@ -50,7 +50,7 @@ void CBotChatPageMission::init()
{
CInterfaceManager *im = CInterfaceManager::getInstance();
if (im->getDbBranch("SERVER:CHOOSE_MISSIONS"))
im->getDbBranch("SERVER:CHOOSE_MISSIONS")->addBranchObserver(&_MissionPagesObs);
im->addBranchObserver("SERVER:CHOOSE_MISSIONS", &_MissionPagesObs);
}

@ -161,7 +161,7 @@ void CBotChatPageTrade::init()
CInterfaceManager *im = CInterfaceManager::getInstance();
if (im->getDbBranch("SERVER:TRADING"))
{
im->getDbBranch("SERVER:TRADING")->addBranchObserver(&_TradePagesObs);
im->addBranchObserver( "SERVER:TRADING", &_TradePagesObs);
}
_FamePriceFactorLeaf = im->getDbProp("SERVER:TRADING:FAME_PRICE_FACTOR");
@ -2990,7 +2990,8 @@ NLMISC_COMMAND( testResaleItems, "Temp : test resale", "" )
//
// Force for next page
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
return true;
}

@ -123,7 +123,7 @@ bool CDBGroupListSheet::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
_DbBranch= branch;
_DbBranchName= (const char*)prop;
// add observer
_DbBranch->addBranchObserver(&_DbBranchObs);
pIM->addBranchObserver(branch, &_DbBranchObs);
}
// parse the common ctrl info

@ -107,7 +107,7 @@ bool CDBGroupListSheetText::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
_DbBranch= branch;
_DbBranchName= (const char*)prop;
// add observer
_DbBranch->addBranchObserver(&_DbBranchObs);
pIM->addBranchObserver( branch, &_DbBranchObs );
}
// parse the common ctrl info

@ -672,20 +672,14 @@ void CGuildManager::initDBObservers()
CInterfaceManager *pIM = CInterfaceManager::getInstance();
// add an observer on the whole guild
CCDBNodeBranch *pGuild = pIM->getDbBranch("SERVER:GUILD");
if (pGuild != NULL)
pGuild->addBranchObserver(&_DBObs);
pIM->addBranchObserver( "SERVER:GUILD", &_DBObs );
// add an observer on members only => need to update all
CCDBNodeBranch *pGuildMembers = pIM->getDbBranch("SERVER:GUILD:MEMBERS");
if (pGuildMembers != NULL)
pGuildMembers->addBranchObserver(&_DBObsMembers);
pIM->addBranchObserver("SERVER:GUILD:MEMBERS", &_DBObsMembers);
// observer on ascencors
Ascensors.setListType(CHugeListObs::Ascensor);
CCDBNodeBranch *pAscensor = pIM->getDbBranch("SERVER:ASCENSOR");
if (pAscensor != NULL)
pAscensor->addBranchObserver(&Ascensors);
pIM->addBranchObserver("SERVER:ASCENSOR", &Ascensors);
}
// ***************************************************************************

@ -790,7 +790,8 @@ void CInterfaceDDX::updateRealtime(CCtrlBase *pSB, bool updateOnScrollEnd)
ClientCfg.IsInvalidated = true;
}
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
for (i = 0; i < _Parameters.size(); ++i)
{

@ -132,12 +132,12 @@ static bool affect(const CInterfaceExprValue &value, CInterfaceElement &destElem
CInterfaceLink::CInterfaceLinkUpdater::CInterfaceLinkUpdater()
{
CCDBNodeBranch::addFlushObserver( this );
CInterfaceManager::getInstance()->addFlushObserver( this );
}
CInterfaceLink::CInterfaceLinkUpdater::~CInterfaceLinkUpdater()
{
CCDBNodeBranch::removeFlushObserver( this );
CInterfaceManager::getInstance()->removeFlushObserver( this );
}
void CInterfaceLink::CInterfaceLinkUpdater::onObserverCallFlush()
@ -276,7 +276,7 @@ void CInterfaceLink::createObservers(const TNodeVect &nodes)
else
{
CCDBNodeBranch *br = static_cast<CCDBNodeBranch *>(*it);
br->addBranchObserver(this);
CInterfaceManager::getInstance()->addBranchObserver( br, this );
}
}
}
@ -294,7 +294,7 @@ void CInterfaceLink::removeObservers(const TNodeVect &nodes)
else
{
CCDBNodeBranch *br = static_cast<CCDBNodeBranch *>(*it);
br->removeBranchObserver(this);
CInterfaceManager::getInstance()->removeBranchObserver( br, this );
}
}
}

@ -20,6 +20,7 @@
#define CL_INTERFACE_LINK_H
#include "nel/misc/cdb_branch.h"
#include "nel/misc/cdb_branch_observing_handler.h"
class CInterfaceElement;
class CReflectedProperty;
@ -66,7 +67,7 @@ public:
/// Updates triggered interface links when triggered by the observed branch
class CInterfaceLinkUpdater : public NLMISC::CCDBNodeBranch::IBranchObserverCallFlushObserver
class CInterfaceLinkUpdater : public NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver
{
public:
CInterfaceLinkUpdater();

@ -1236,7 +1236,8 @@ void CInterfaceManager::updateFrameEvents()
CInterfaceAnim *pIA = vTmp[i];
pIA->update();
}
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::flushObserverCalls();
//
// Next : Test if we have to remove anims
for (i = 0; i < (sint)_ActiveAnims.size(); ++i)
@ -1249,7 +1250,8 @@ void CInterfaceManager::updateFrameEvents()
}
}
//
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Handle waiting texts from server
processServerIDString();
@ -1341,7 +1343,8 @@ void CInterfaceManager::updateFrameEvents()
{
(*it)->handleEvent(clockTick);
}
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Update SPhrase manager
CSPhraseManager *pPM= CSPhraseManager::getInstance();
@ -1985,8 +1988,9 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera)
H_AUTO ( RZ_Interface_DrawViews_Setup )
_ViewRenderer.activateWorldSpaceMatrix (false);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// If an element has captured the keyboard, make sure it is alway visible (all parent windows active)
if (_CaptureKeyboard != NULL)
@ -2058,7 +2062,8 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera)
To minimize texture swapping, we first sort per Window, then we sort per layer, then we render per Global Texture.
Computed String are rendered in on big drawQuads at last part of each layer
*/
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
//
for (uint32 nMasterGroup = 0; nMasterGroup < _MasterGroups.size(); nMasterGroup++)
{
@ -2108,8 +2113,9 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera)
{
H_AUTO ( RZ_Interface_DrawViews_After )
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// draw the special over extend text
drawOverExtendViewText();
@ -2157,7 +2163,8 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera)
Driver->setMatrixMode2D11();
// flush obs
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
}
}
@ -2725,7 +2732,8 @@ bool CInterfaceManager::handleEvent (const CEventDescriptor& event)
if(_CaptureKeyboard && _CaptureKeyboard->getRootWindow()==tw)
{
bool result = _CaptureKeyboard->handleEvent(event);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
return result;
}
else
@ -2782,7 +2790,8 @@ bool CInterfaceManager::handleEvent (const CEventDescriptor& event)
if (_CaptureKeyboard != NULL && !handled)
{
bool result = _CaptureKeyboard->handleEvent(event);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
return result;
}
}
@ -3042,7 +3051,8 @@ bool CInterfaceManager::handleEvent (const CEventDescriptor& event)
handled|= _MouseOverWindow;
}
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// event handled?
return handled;
}
@ -6640,4 +6650,87 @@ bool CInterfaceManager::parseTokens(ucstring& ucstr)
ucstr = str;
return true;;
}
}
void CInterfaceManager::addBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _DbRootNode->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.addBranchObserver( b, observer, positiveLeafNameFilter );
}
void CInterfaceManager::addBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter )
{
if( branch == NULL )
return;
branchObservingHandler.addBranchObserver( branch, observer, positiveLeafNameFilter );
}
void CInterfaceManager::addBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _DbRootNode->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.addBranchObserver( b, dbPathFromThisNode, observer, positiveLeafNameFilter, positiveLeafNameFilterSize );
}
void CInterfaceManager::addBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize )
{
if( branch == NULL )
return;
branchObservingHandler.addBranchObserver( branch, dbPathFromThisNode, observer, positiveLeafNameFilter, positiveLeafNameFilterSize );
}
void CInterfaceManager::removeBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver* observer )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _DbRootNode->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.removeBranchObserver( b, observer );
}
void CInterfaceManager::removeBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver* observer )
{
if( branch == NULL )
return;
branchObservingHandler.removeBranchObserver( branch, observer );
}
void CInterfaceManager::removeBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer )
{
CCDBNodeBranch *b = dynamic_cast< CCDBNodeBranch* >( _DbRootNode->getNode( ICDBNode::CTextId( std::string( branchName ) ), false ) );
if( b == NULL )
return;
branchObservingHandler.removeBranchObserver( b, dbPathFromThisNode, observer );
}
void CInterfaceManager::removeBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer )
{
if( branch == NULL )
return;
branchObservingHandler.removeBranchObserver( branch, dbPathFromThisNode, observer );
}
void CInterfaceManager::addFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer )
{
if( observer == NULL )
return;
branchObservingHandler.addFlushObserver( observer );
}
void CInterfaceManager::removeFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer )
{
if( observer == NULL )
return;
branchObservingHandler.removeFlushObserver( observer );
}
void CInterfaceManager::flushObserverCalls()
{
branchObservingHandler.flushObserverCalls();
}

@ -1065,6 +1065,20 @@ private:
void updateTooltipCoords(CCtrlBase *newCtrl);
CInterfaceLink::CInterfaceLinkUpdater *interfaceLinkUpdater;
NLMISC::CCDBBranchObservingHandler branchObservingHandler;
public:
void addBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter = std::vector< std::string >() );
void addBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver *observer, const std::vector< std::string >& positiveLeafNameFilter = std::vector< std::string >() );
void addBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter = NULL, uint positiveLeafNameFilterSize = 0 );
void addBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer, const char **positiveLeafNameFilter, uint positiveLeafNameFilterSize );
void removeBranchObserver( const char *branchName, NLMISC::ICDBNode::IPropertyObserver* observer );
void removeBranchObserver( NLMISC::CCDBNodeBranch *branch, NLMISC::ICDBNode::IPropertyObserver* observer );
void removeBranchObserver( const char *branchName, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer );
void removeBranchObserver( NLMISC::CCDBNodeBranch *branch, const char *dbPathFromThisNode, NLMISC::ICDBNode::IPropertyObserver &observer );
void addFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer );
void removeFlushObserver( NLMISC::CCDBBranchObservingHandler::IBranchObserverCallFlushObserver *observer );
void flushObserverCalls();
};
#endif // NL_INTERFACE_MANAGER_H

@ -1864,7 +1864,8 @@ void CTempInvManager::open(TEMP_INV_MODE::TInventoryMode m)
}
pIM->getDbProp("LOCAL:INVENTORY:TEMP:TYPE")->setValue8((uint8)_Mode);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
if (pGC != NULL)
{

@ -582,12 +582,14 @@ void CModalContainerEditCmd::activateFrom (const std::string &cmdName, const std
pCB = dynamic_cast<CDBGroupComboBox*>(pIM->getElementFromId(WinName+WIN_EDITCMD_COMBO_CATEGORY));
pCB->setSelection(catCBIndex);
onChangeCategory();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
//pIM->runActionHandler("editcmd_change_category",NULL);
pCB = dynamic_cast<CDBGroupComboBox*>(pIM->getElementFromId(WinName+WIN_EDITCMD_COMBO_ACTION));
pCB->setSelection(actCBIndex);
onChangeAction();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
//pIM->runActionHandler("editcmd_change_action",NULL);
// Count number of displayed param

@ -488,7 +488,8 @@ void CMacroCmdManager::updateMacroExecution ()
pIM->runActionHandler(rC.Name, NULL, rC.Params);
// Flush interface links (else bug with Macro "Select ShortCutBar/Run Shortcut"
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
if (bWaitForServer)
{

@ -132,7 +132,7 @@ void CSBrickManager::initInGame()
}
// Add a branch observer on brick family
pIM->getDbBranch("SERVER:BRICK_FAMILY")->addBranchObserver(&_BrickFamilyObs);
pIM->addBranchObserver( "SERVER:BRICK_FAMILY", &_BrickFamilyObs);
}
// ***************************************************************************

@ -158,7 +158,7 @@ void CSkillManager::initInGame()
// Get a node used to inform interface that a skill has changed
_TrackSkillChange= pIM->getDbProp("UI:VARIABLES:TRACK_SKILL_CHANGE", true);
// Add a branch observer on skill value change
pIM->getDbBranch("SERVER:CHARACTER_INFO:SKILLS")->addBranchObserver(&_SkillChangeObs);
pIM->addBranchObserver( "SERVER:CHARACTER_INFO:SKILLS", &_SkillChangeObs );
}

@ -360,7 +360,8 @@ void loginMainLoop()
&& LoginSM.getCurrentState() != CLoginStateMachine::st_ingame)
// while (loginFinished == false)
{
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Update the DT T0 and T1 global variables
updateClientTime();
@ -378,7 +379,8 @@ void loginMainLoop()
// Interface handling & displaying
pIM->updateFrameEvents();
pIM->updateFrameViews(NULL);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
@ -810,7 +812,8 @@ bool login()
loginIntro();
pIM->initLogin();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
bool tmpDI = ClientCfg.DisableDirectInput;
ClientCfg.DisableDirectInput = true;
@ -3031,8 +3034,8 @@ void loginIntro()
const ucstring nmsg("");
ProgressBar.newMessage (nmsg);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
}
}
beginLoading(StartBackground);

@ -1638,7 +1638,8 @@ bool mainLoop()
// flush observers
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
}
@ -1655,7 +1656,8 @@ bool mainLoop()
// NetWork Update.
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// lets some CPU.
NetMngr.send();
nlSleep(100);
@ -1764,7 +1766,8 @@ bool mainLoop()
{
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
bool prevDatabaseInitStatus = IngameDbMngr.initInProgress();
IngameDbMngr.setChangesProcessed();
bool newDatabaseInitStatus = IngameDbMngr.initInProgress();
@ -1834,7 +1837,8 @@ bool mainLoop()
// update bot chat
CBotChatManager::getInstance()->update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// updateItemEdition
CInterfaceItemEdition::getInstance()->update();

@ -150,24 +150,24 @@ void CNPCIconCache::addObservers()
// Mission Journal
static const char *missionStartStopLeavesToMonitor [2] = {"TITLE", "FINISHED"};
IngameDbMngr.getNodePtr()->addBranchObserver("MISSIONS", MissionStartStopObserver, missionStartStopLeavesToMonitor, getArraySize(missionStartStopLeavesToMonitor));
IngameDbMngr.addBranchObserver( IngameDbMngr.getNodePtr(), "MISSIONS", MissionStartStopObserver, missionStartStopLeavesToMonitor, getArraySize(missionStartStopLeavesToMonitor));
static const char *missionNpcAliasLeavesToMonitor [1] = {"NPC_ALIAS"};
IngameDbMngr.getNodePtr()->addBranchObserver("MISSIONS", MissionNpcAliasObserver, missionNpcAliasLeavesToMonitor, getArraySize(missionNpcAliasLeavesToMonitor));
IngameDbMngr.addBranchObserver( IngameDbMngr.getNodePtr(), "MISSIONS", MissionNpcAliasObserver, missionNpcAliasLeavesToMonitor, getArraySize(missionNpcAliasLeavesToMonitor));
// Skills
static const char *skillLeavesToMonitor [2] = {"SKILL", "BaseSKILL"};
IngameDbMngr.getNodePtr()->addBranchObserver("CHARACTER_INFO:SKILLS", MissionPrerequisitEventObserver, skillLeavesToMonitor, getArraySize(skillLeavesToMonitor));
IngameDbMngr.addBranchObserver( IngameDbMngr.getNodePtr(), "CHARACTER_INFO:SKILLS", MissionPrerequisitEventObserver, skillLeavesToMonitor, getArraySize(skillLeavesToMonitor));
// Owned Items
static const char *bagLeavesToMonitor [1] = {"SHEET"}; // just saves 2000 bytes or so (500 * observer pointer entry in vector) compared to one observer per bag slot
IngameDbMngr.getNodePtr()->addBranchObserver("INVENTORY:BAG", MissionPrerequisitEventObserver, bagLeavesToMonitor, getArraySize(bagLeavesToMonitor));
IngameDbMngr.addBranchObserver( IngameDbMngr.getNodePtr(), "INVENTORY:BAG", MissionPrerequisitEventObserver, bagLeavesToMonitor, getArraySize(bagLeavesToMonitor));
// Worn Items
IngameDbMngr.getNodePtr()->addBranchObserver("INVENTORY:HAND", MissionPrerequisitEventObserver);
IngameDbMngr.getNodePtr()->addBranchObserver("INVENTORY:EQUIP", MissionPrerequisitEventObserver);
IngameDbMngr.addBranchObserver( "INVENTORY:HAND", &MissionPrerequisitEventObserver);
IngameDbMngr.addBranchObserver( "INVENTORY:EQUIP", &MissionPrerequisitEventObserver);
// Known Bricks
IngameDbMngr.getNodePtr()->addBranchObserver("BRICK_FAMILY", MissionPrerequisitEventObserver);
IngameDbMngr.addBranchObserver( "BRICK_FAMILY", &MissionPrerequisitEventObserver);
// For other events, search for calls of onEventForMissionAvailabilityForThisChar()
}

@ -27,6 +27,7 @@
#include "weather.h"
#include "weather_manager_client.h"
#include "interface_v3/input_handler_manager.h"
#include "interface_v3/interface_manager.h"
#include "release.h"
#include "net_manager.h"
#include "client_cfg.h"
@ -393,7 +394,8 @@ void CProgress::internalProgress (float value)
// \todo GUIGUI : Remove this when possible.
NetMngr.update();
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// update system dependent progress bar
static uint previousValue = 0;

@ -1724,7 +1724,8 @@ void CEditor::waitScenarioScreen()
}
}
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// check if we can send another dated block
if (NetMngr.getCurrentServerTick() != serverTick)
@ -1769,7 +1770,8 @@ void CEditor::waitScenarioScreen()
if (sysInfo) sysInfo->setActive(false);
getUI().updateFrameViews(NULL);
CCDBNodeBranch::flushObserversCalls();
IngameDbMngr.flushObserverCalls();
CInterfaceManager::getInstance()->flushObserverCalls();
// Movie shooter
globalMenuMovieShooter();

Loading…
Cancel
Save