/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
#ifndef
#define
#include "nel/misc/types_nl.h"
#include <memory>
#include "nel/misc/hierarchical_timer.h"
#include "nel/misc/string_conversion.h"
#include "nel/net/message.h"
#include "nel/net/module.h"
#include "nel/net/module_builder_parts.h"
#include "nel/net/module_message.h"
#include "nel/net/module_gateway.h"
#include "game_share/callback_adaptor.h"
#include "nel/misc/string_common.h"
#include "server_share/mysql_wrapper.h"
#include "game_share/synchronised_message.h"
#endif
namespace
{
class ;
class Ptr;
}
#include ".h"
namespace
{
}
#include ""
#include <>
#include ""
<?php
require_once('');
?>
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
class Skel
{
public:
/// the interceptor type
typedef NLNET::CInterceptorForwarder < Skel> TInterceptor;
protected:
Skel()
{
// do early run time check for message table
getMessageHandlers();
}
virtual ~Skel()
{
}
void init(NLNET::IModule *module)
{
_Interceptor.init(this, module);
}
public:
// unused interceptors
std::string fwdBuildModuleManifest() const { return std::string(); }
void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) {}
void fwdOnModuleDown(NLNET::IModuleProxy *moduleProxy) {}
void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {}
// process module message interceptor
bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message);
private:
typedef void (Skel::*TMessageHandler)(NLNET::IModuleProxy *sender, const NLNET::CMessage &message);
typedef std::map<std::string, TMessageHandler> TMessageHandlerMap;
const TMessageHandlerMap &getMessageHandlers() const;
void _skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message);
void _skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message);
// declare one interceptor member of the skeleton
TInterceptor _Interceptor;
// declare the interceptor forwarder as friend of this class
friend class NLNET::CInterceptorForwarder < Skel>;
public:
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
virtual void (NLNET::IModuleProxy *sender) =0;
virtual (NLNET::IModuleProxy *sender) =0;
};
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
class Proxy
{
/// Smart pointer on the module proxy
NLNET::TModuleProxyPtr _ModuleProxy;
// Pointer on the local module that implement the interface (if the proxy is for a local module)
NLNET::TModulePtr _LocalModule;
// Direct pointer on the server implementation interface for collocated module
Skel *_LocalModuleSkel;
public:
Proxy(NLNET::IModuleProxy *proxy)
{
nlassert(proxy->getModuleClassName() == );
_ModuleProxy = proxy;
// initialize collocated servant interface
if (proxy->getModuleDistance() == 0)
{
_LocalModule = proxy->getLocalModule();
nlassert(_LocalModule != NULL);
Skel::TInterceptor *interceptor = NULL;
interceptor = static_cast < NLNET::CModuleBase* >(_LocalModule.getPtr())->getInterceptor(interceptor);
nlassert(interceptor != NULL);
_LocalModuleSkel = interceptor->getParent();
nlassert(_LocalModuleSkel != NULL);
}
else
_LocalModuleSkel = 0;
}
virtual ~Proxy()
{
}
NLNET::IModuleProxy *getModuleProxy()
{
return _ModuleProxy;
}
void (NLNET::IModule *sender);
(NLNET::IModule *sender);
// This is the broadcast version of the method.
template < class ProxyIterator >
static void broadcast_(ProxyIterator first, ProxyIterator last, NLNET::IModule *sender)
{
NLNET::CMessage message;
// create the message to send to multiple dest
buildMessageFor_(message , );
for (; first != last; ++first)
{
NLNET::IModuleProxy *proxy = *first;
proxy->sendModuleMessage(sender, message);
}
}
// Message serializer. Return the message received in reference for easier integration
static const NLNET::CMessage &buildMessageFor_(NLNET::CMessage &__message);
};
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
const ::TMessageHandlerMap &::getMessageHandlers() const
{
static TMessageHandlerMap handlers;
static bool init = false;
if (!init)
{
std::pair < TMessageHandlerMap::iterator, bool > res;
res = handlers.insert(std::make_pair(std::string(""), &::_skel));
// if this assert, you have a doubly message name in your interface definition !
nlassert(res.second);
init = true;
}
return handlers;
}
bool Skel::fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &message)
{
const TMessageHandlerMap &mh = getMessageHandlers();
TMessageHandlerMap::const_iterator it(mh.find(message.getName()));
if (it == mh.end())
{
return false;
}
TMessageHandler cmd = it->second;
(this->*cmd)(sender, message);
return true;
}
void ::_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message)
{
H_AUTO(__);
;
(sender, );
}
void ::_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &__message)
{
H_AUTO(__);
;
__ret = (sender, );
// encode the return message
NLNET::CMessage __retMsg;
__retMsg.setType("R_", NLNET::CMessage::Response);
nlWrite(__retMsg, serial, __ret);
// and send back the response
sender->sendModuleMessage(static_cast<NLNET::IModule*>(_Interceptor.getRegistrar()), __retMsg);
}
void ::(NLNET::IModule *sender)
{
if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported())
{
// immediate local synchronous dispatching
_LocalModuleSkel->(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), );
}
else
{
// send the message for remote dispatching and execution or local queing
NLNET::CMessage __message;
buildMessageFor_(__message, );
_ModuleProxy->sendModuleMessage(sender, __message);
}
}
::(NLNET::IModule *sender)
{
if (_LocalModuleSkel && _LocalModule->isImmediateDispatchingSupported())
{
// immediate local synchronous dispatching
return _LocalModuleSkel->(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender), );
}
else
{
// send the message for remote dispatching and execution
NLNET::CMessage __message;
buildMessageFor_(__message, );
NLNET::CMessage __retMsg;
sender->invokeModuleOperation(_ModuleProxy, __message, __retMsg);
// check the return message type
if (__retMsg.getName() != "R_")
throw NLNET::IModule::EInvokeBadReturn();
__ret;
nlRead(__retMsg, serial, __ret);
return __ret;
}
}
// Message serializer. Return the message received in reference for easier integration
const NLNET::CMessage &::buildMessageFor_(NLNET::CMessage &__message)
{
__message.setType("", NLNET::CMessage::Request);
return __message;
}
//
//
,
const std::vector<> &,
const &,
nlWrite(, serial, const_cast < & > ());
nlWrite(, serial, );
nlWrite(, serialCont, );
nlRead(, serial, );
nlRead(, serialCont, );
<?php
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
$arrayCounter = 0;
$__EnumValues[$arrayCounter++] = "";
$__EnumValues[$arrayCounter] = "invalid";
$__InvalidValue = $arrayCounter;
class _
{
var $Value;
function _()
{
global $__InvalidValue;
$this->Value = $__InvalidValue;
}
function toString()
{
global $__EnumValues;
return $__EnumValues[$this->Value];
}
function fromString($strValue)
{
global $__EnumValues;
foreach ($__EnumValues as $k => $v)
{
if ($strValue === $v)
{
$this->Value = $k;
return;
}
}
$this->Value = $__InvalidValue;
}
function toInt()
{
return $this->Value;
}
function fromInt($intValue)
{
global $__InvalidValue;
global $__EnumValues;
if (array_key_exists($intValue, $__EnumValues))
$this->Value = $intValue;
else
$this->Value = $__InvalidValue;
}
}
?>
typedef NLMISC::CEnumBitset < Enum, uint32, Enum::invalid_val, ',', NLMISC::TContainedEnum < Enum, uint32 >, Enum::TValues > ;
ERROR : You can't set a base value AND a value for the first item on enum definition
struct
{
enum TValues
{
=
= ,
/// the highest valid value in the enum
last_enum_item = ,
/// a value equal to the last enum item +1
end_of_enum,
invalid_val,
/// Number of enumerated values
nb_enum_items =
};
/// Index table to convert enum value to linear index table
const std::map<TValues, uint32> &getIndexTable() const
{
static std::map<TValues, uint32> indexTable;
static bool init = false;
if (!init)
{
// fill the index table
indexTable.insert(std::make_pair(, ));
init = true;
}
return indexTable;
}
static const NLMISC::CStringConversion<TValues> &getConversionTable()
{
NL_BEGIN_STRING_CONVERSION_TABLE(TValues)
NL_STRING_CONVERSION_TABLE_ENTRY()
NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val)
};
static NLMISC::CStringConversion<TValues>
conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table)
/ sizeof(TValues_nl_string_conversion_table[0]), invalid_val);
return conversionTable;
}
TValues _Value;
public:
()
: _Value(invalid_val)
{
}
(TValues value)
: _Value(value)
{
}
(const std::string &str)
{
_Value = getConversionTable().fromString(str);
}
void serial(NLMISC::IStream &s)
{
s.serialEnum(_Value);
}
bool operator == (const &other) const
{
return _Value == other._Value;
}
bool operator != (const &other) const
{
return ! (_Value == other._Value);
}
bool operator < (const &other) const
{
return _Value < other._Value;
}
bool operator <= (const &other) const
{
return _Value <= other._Value;
}
bool operator > (const &other) const
{
return !(_Value <= other._Value);
}
bool operator >= (const &other) const
{
return !(_Value < other._Value);
}
const std::string &toString() const
{
return getConversionTable().toString(_Value);
}
static const std::string &toString(TValues value)
{
return getConversionTable().toString(value);
}
TValues getValue() const
{
return _Value;
}
// return true if the actual value of the enum is valid, otherwise false
bool isValid()
{
if (_Value == invalid_val)
return false;
// not invalid, check other enum value
return getConversionTable().isValid(_Value);
}
uint32 asIndex()
{
std::map<TValues, uint32>::const_iterator it(getIndexTable().find(_Value));
nlassert(it != getIndexTable().end());
return it->second;
}
};
//
_;
//
const &get() const
{
return _;
}
&get()
{
return _;
}
void set(const &value)
{
if (_ != value)
{
if (getPersistentState() != NOPE::os_transient)
setPersistentState(NOPE::os_dirty);
Ptr parent = ::loadFromCache(_);
if (parent && getPersistentState() != NOPE::os_transient )
parent->removeChild(this);
_ = value;
Ptr parent = ::loadFromCache(_);
if (parent && getPersistentState() != NOPE::os_transient)
parent->insertChild(this);
}
}
get() const
{
return _;
}
void set( value)
{
if (_ != value)
{
if (getPersistentState() != NOPE::os_transient)
setPersistentState(NOPE::os_dirty);
_ = value;
}
}
/** Return a const reference to the vector of child.
* If you want to modify the element inside, you need to
* use on of the two following methods who return non const pointer
* on contained elements.
*/
const std::vector<Ptr> &get() const;
/** Return the ith element of the child vector
* index must be valid (ie less than size of the vector)
*/
Ptr &getByIndex(uint32 index) const;
/** Return the identified element by looking in the vector
* If no element match the id, NULL pointer is returned
*/
Ptr &getById(uint32 id) const;
/** Return a const reference to the map of child.
* If you want to modify the element inside, you need to
* use on of the two following method who return non const pointer
* on contained elements.
*/
const std::map<uint32, Ptr> &get() const;
/** Return the identified element by looking in the map
* If no element match the id, NULL pointer is returned
*/
Ptr &getById(uint32 id) const;
ERROR : Invalide container, child must be either map or vector for child in class
/** Return the one child object (or null if not) */
Ptr get();
qs += "
,
";
qs += "
,
";
qs += "
,
";
qs += "'"+_.toString()+"'";
qs += "'"+MSW::encodeDate(_)+"'";
qs += "'"+MSW::escapeString(_.toString(), connection)+"'";
qs += "'"+MSW::escapeString(NLMISC::toString(_), connection)+"'";
qs += ", ";
qs += "'"+_.toString()+"'";
qs += "'"+MSW::encodeDate(_)+"'";
qs += "'"+MSW::escapeString(_.toString(), connection)+"'";
qs += "'"+MSW::escapeString(NLMISC::toString(_), connection)+"'";
qs += ", ";
qs += "'"+_.toString()+"'";
qs += "'"+MSW::encodeDate(_)+"'";
qs += "'"+MSW::escapeString(_.toString(), connection)+"'";
qs += "'"+MSW::escapeString(NLMISC::toString(_), connection)+"'";
qs += ", ";
qs += " = '"+_.toString()+"'";
qs += " = '"+MSW::encodeDate(_)+"'";
qs += " = '"+MSW::escapeString(_.toString(), connection)+"'";
qs += " = '"+MSW::escapeString(NLMISC::toString(_), connection)+"'";
qs += ", ";
qs += " = '"+_.toString()+"'";
qs += " = '"+MSW::encodeDate(_)+"'";
qs += " = '"+MSW::escapeString(_.toString(), connection)+"'";
qs += " = '"+MSW::escapeString(NLMISC::toString(_), connection)+"'";
qs += ", ";
qs += " WHERE = '"+NLMISC::toString(_)+"'";
qs += " WHERE = '"+NLMISC::toString()+"'";
ERROR : You must have ONE and ONLY one unique_id property in class '_'
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
class
{
protected:
friend class ;
std::map < uint32, Ptr > *_;
std::vector < Ptr > *_;
ERROR : You must define the cont="" property with either 'vector' or 'map' value in the child_class element for class '' , child '_'
friend class ;
bool _Loaded;
Ptr _;
public:
bool operator == (const &other) const
{
return _ == other._
&& ;
}
// constructor
()
{
// Default initialisation
_ = ;
}
void send(const std::string &serviceName)
{
NLNET::CMessage msg("");
serial(msg);
sendMessageViaMirror( serviceName, msg );
}
void send(NLNET::TServiceId serviceId)
{
NLNET::CMessage msg("");
serial(msg);
sendMessageViaMirror( serviceId, msg );
}
private:
// private constructor, you must use 'createTransient' to get an instance
()
: _PtrList(NULL),
_ObjectState(NOPE::os_transient),
_(NOPE::INVALID_OBJECT_ID)
{
// Default initialisation
_ = ;
_ = NULL;
_Loaded = false;
// register the cache for this class (if not already done)
registerUpdatable();
}
// Destructor, delete any children
~();
/// utility func to remove this object from the released object container
void removeFromReleased();
public:
/// Create a new instance in the transient space
static Ptr createTransient(const char *filename, uint32 lineNum)
{
return Ptr(new (), filename, lineNum);
}
/** Create a new object in the database from the current object data.
* The object MUST be in transient state (i.e, it must be a new
* object created by user and not comming from the databse).
* If identifier is autogenerated, the generated id can be read after
* this call.
*/
bool create(MSW::CConnection &connection);
/** Update the database with the current object state.
* The object MUST be either in clean or dirty state.
* Return true if the object has been effectively stored
* in the database.
* After this call, the object is in 'clean' state.
*/
bool update(MSW::CConnection &connection);
/** Remove the current object from the persistent storage.
* The object must be in clean or dirty state.
* Return true if the object has been correctly
* updated in the database.
* After the call, the object is in 'clean' state.
*/
bool remove(MSW::CConnection &connection);
/** Remove an object from the persistent storage by specifying
* the id to remove.
* Return true if an entry as been effectively removed from
* the database.
* After the call, the object is in 'removed' state and should
* no more be used. A good pratice should be to delete
* the transient object just after the remove call.
*/
static bool removeById(MSW::CConnection &connection, uint32 id);
/** Load an instance from the database.
* This call allocate a new object and load the property value
* from the database.
* Return NULL if the object id is not found.
*/
static Ptr load(MSW::CConnection &connection, uint32 id, const char *filename, uint32 lineNum);
/** Load all objects children of and
* return them by using the specified output iterator.
*/
static bool loadChildrenOf(MSW::CConnection &connection, uint32 parentId, std::vector < Ptr > &children, const char *filename, uint32 lineNum);
static bool loadChildrenOf(MSW::CConnection &connection, uint32 parentId, std::map < uint32, Ptr > &children, const char *filename, uint32 lineNum);
ERROR : parent/child relation support only 'map' or 'vector' cont specification in definition
/** Load the object child of and
* return true if no error, false in case of error (in SQL maybe).
* If no such object is found, fill the child pointer with NULL.
*/
static bool loadChildOf(MSW::CConnection &connection, uint32 parentId, Ptr &childPtr, const char *filename, uint32 lineNum);
/// Load child(ren) object(s).
bool load(MSW::CConnection &connection, const char *filename, uint32 lineNum);
void serial(NLMISC::IStream &s)
{
s.serial(_);
}
private:
/// add a child in the container
void insertChild( &child)
{
nlassert(std::find(_.begin(), _.end(), child) == _.end());
_.push_back(child);
}
// remove a child from the container
void removeXXChild()
{
}
private:
friend class CPersistentCache;
friend class Ptr;
typedef std::map<uint32, *> TObjectCache;
typedef std::set<*> TObjectSet;
typedef std::map<time_t, TObjectSet> TReleasedObject;
/// The complete set of object currently in memory (either active or released) excluding transient instance
static TObjectCache _ObjectCache;
/// The set of object in memory ut released (no pointer on them) and waiting for decommit
static TReleasedObject _ReleasedObject;
/// The current object state
NOPE::TObjectState _ObjectState;
/// For object in released state, this is the release date (used to trigger deletion of the object from memory)
time_t _ReleaseDate;
/// The linked list of pointer on this object
Ptr *_PtrList;
// Try to load the specified object from the memory cache, return NULL if the object is not in the cache
static *loadFromCache(uint32 objectId, bool unrelease);
// Receive and execute command from the cache manager.
static uint32 cacheCmd(NOPE::TCacheCmd cmd);
static void dump();
static void updateCache();
public:
static void clearCache();
private:
void registerUpdatable();
// set the pointer on the first pointer of the pointer list (set to null when there is no more pointer)
void setFirstPtr(Ptr *ptr);
// return the first pointer of the pointer list (can be null)
Ptr *getFirstPtr()
{
return _PtrList;
}
public:
/** Return the object identifier (witch is unique)
* You can only call this method on a persistent instance.
* (because transient instance can have invalid id)
*/
uint32 getObjectId() const
{
nlassert(getPersistentState() != NOPE::os_transient);
return _;
}
/** Set the object unique ID.
* You can only set the object id on a transient object
* having a non autogenerated unique id.
* Furthermore, you MUST set the id before calling create()
* if the id is not autogenerated.
*/
void setObjectId(uint32 objectId)
{
// can only be set when in transient state
nlassert(getPersistentState() == NOPE::os_transient);
// can only be set once
nlassert(_ == NOPE::INVALID_OBJECT_ID);
_ = objectId;
}
/** Return the current persistent state of the object.*/
NOPE::TObjectState getPersistentState() const
{
return _ObjectState;
}
private:
// Set the persistent state of the object and do some house keeping
void setPersistentState(NOPE::TObjectState state);
};
ERROR : You must have ONE and ONLY one unique_id property in class '_'
::TObjectCache ::_ObjectCache;
::TReleasedObject ::_ReleasedObject;
// Destructor, delete any children
::~()
{
// release childs reference
if (_ != NULL)
delete _;
if (_PtrList != NULL)
{
nlwarning("ERROR : someone try to delete this object, but there are still ptr on it !");
Ptr *ptr = _PtrList;
do
{
nlwarning(" Pointer created from '%s', line %u", ptr->_FileName, ptr->_LineNum);
ptr = _PtrList->getNextPtr();
} while(ptr != _PtrList);
nlstop;
}
// remove object from cache map
if (_ != NOPE::INVALID_OBJECT_ID
&& _ObjectState != NOPE::os_removed
&& _ObjectState != NOPE::os_transient)
{
nldebug("NOPE: clearing @%p from cache with id %u", this, static_cast<uint32>(_));
nlverify(_ObjectCache.erase(_) == 1);
}
else if (_ObjectState != NOPE::os_transient)
{
nlassert(_ObjectCache.find(_) == _ObjectCache.end());
}
if (_ObjectState == NOPE::os_released)
{
removeFromReleased();
}
else
{
TReleasedObject::iterator it(_ReleasedObject.find(_ReleaseDate));
if (it != _ReleasedObject.end())
{
nlassert(it->second.find(this) == it->second.end());
}
}
}
void ::removeFromReleased()
{
TReleasedObject::iterator it(_ReleasedObject.find(_ReleaseDate));
nlassert(it != _ReleasedObject.end());
TObjectSet &os = it->second;
nlverify(os.erase(this) == 1);
// nb : _ReleasedObject time entry are removed by the cache update
}
bool ::create(MSW::CConnection &connection)
{
nlassert(getPersistentState() == NOPE::os_transient);
nlassert(_ != 0);
std::string qs;
qs = "INSERT INTO (";
qs += ") VALUES (";
qs += ")";
if (connection.query(qs))
{
uint32 _id_ = connection.getLastGeneratedId();
setObjectId(_id_);
setPersistentState(NOPE::os_clean);
// update the parent class instance in cache if any
if ( != 0)
{
// need to update the parent class child list if it is in the cache
*parent = ::loadFromCache(, false);
if (parent && parent->_ != NULL)
{
nlverify(parent->_->insert(std::make_pair(getObjectId(), Ptr(this, __FILE__, __LINE__))).second);
nlassert(std::find(parent->_->begin(), parent->_->end(), Ptr(this, __FILE__, __LINE__)) == parent->_->end());
parent->_->push_back(Ptr(this, __FILE__, __LINE__));
}
}
if ( != 0)
{
// need to update the parent class child if it is in the cache
*parent = ::loadFromCache(, false);
if (parent && parent->_Loaded)
{
nlassert(parent->_ == NULL);
parent->_ = Ptr(this, __FILE__, __LINE__);
}
}
return true;
}
return false;
}
bool ::update(MSW::CConnection &connection)
{
nlassert(getPersistentState() == NOPE::os_dirty || getPersistentState() == NOPE::os_clean);
if (getPersistentState() == NOPE::os_clean)
// the object is clean, just ignore the save
return true;
std::string qs;
qs = "UPDATE SET ";
if (connection.query(qs))
{
if (connection.getAffectedRows() == 1)
{
setPersistentState(NOPE::os_clean);
return true;
}
}
return false;
}
bool ::remove(MSW::CConnection &connection)
{
nlassert(getPersistentState() == NOPE::os_dirty || getPersistentState() == NOPE::os_clean);
std::string qs;
qs = "DELETE FROM ";
if (connection.query(qs))
{
if (connection.getAffectedRows() == 1)
{
{
// cascading deletion for vector child
nlassert(load(connection, __FILE__, __LINE__));
const std::vector < Ptr > & childs = get();
while (!childs.empty())
{
getByIndex(childs.size()-1)->remove(connection);
}
}
{
// cascading deletion for map child
nlassert(load(connection, __FILE__, __LINE__));
const std::map < uint32, Ptr > & childs = get();
while (!childs.empty())
{
getById(childs.begin()->first)->remove(connection);
}
}
{
// cascading deletion for single child
nlassert(load(connection, __FILE__, __LINE__));
if (get() != NULL)
get()->remove(connection);
}
{
// unreference (and update) for vector child
nlassert(load(connection, __FILE__, __LINE__));
const std::vector < Ptr > & childs = get();
for (uint i=0; i < childs.size(); ++i)
{
getByIndex(i)->set(0);
getByIndex(i)->update(connection);
}
}
{
// unreference (and update) for map child
nlassert(load(connection, __FILE__, __LINE__));
const std::map < uint32, Ptr > & childs = get();
std::map< uint32, Ptr >::const_iterator first(childs.begin()), last(childs.end());
for (; first != last; ++first)
{
getById(it->first)->set(0);
getById(it->first)->update(connection);
}
}
{
// unreference (and update) for single child
nlassert(load(connection, __FILE__, __LINE__));
if (get() != NULL)
{
get()->set(0);
get()->update(connection);
}
}
// change the persistant state to 'removed'.
setPersistentState(NOPE::os_removed);
// need to remove ref from parent class container (if any)
{
ERROR : parent/child relation : can't find parent param with db_col '' in definition
Ptr parent(::loadFromCache(_, true), __FILE__, __LINE__);
if (parent != NULL && parent->_ != NULL)
{
parent->_->erase(getObjectId());
std::vector < Ptr >::iterator it = std::find(parent->_->begin(), parent->_->end(), this);
if (it != parent->_->end())
{
parent->_->erase(it);
}
ERROR : parent/child relation support only 'map' or 'vector' cont specification in definition
}
}
// need to remove ref from parent (if any)
{
Ptr parent(::loadFromCache(_, true), __FILE__, __LINE__);
if (parent != NULL && parent->_Loaded)
{
// assign a new NULL pointer
parent->_.assign(Ptr(), __FILE__, __LINE__);
}
}
return true;
}
}
return false;
}
bool ::removeById(MSW::CConnection &connection, uint32 id)
{
*object = loadFromCache(id, true);
if (object != NULL)
{
return object->remove(connection);
}
// not in cache, run a SQL query
std::string qs;
qs = "DELETE FROM ";
if (connection.query(qs))
{
if (connection.getAffectedRows() == 1)
{
// ok, the row is removed
return true;
}
}
return false;
}
// Try to load the specified object from the memory cache, return NULL if the object is not in the cache
*::loadFromCache(uint32 objectId, bool unrelease)
{
// look in the cache
TObjectCache::iterator it(_ObjectCache.find(objectId));
if (it == _ObjectCache.end())
{
// not found, return null
return NULL;
}
else
{
*object = it->second;
if (object->_ObjectState == NOPE::os_released)
{
if (unrelease)
{
// we need to remove this object from the released object set.
object->removeFromReleased();
object->_ObjectState = NOPE::os_clean;
}
}
return it->second;
}
}
// Receive and execute command from the cache manager.
uint32 ::cacheCmd(NOPE::TCacheCmd cmd)
{
if (cmd == NOPE::cc_update)
{
updateCache();
}
else if (cmd == NOPE::cc_clear)
{
clearCache();
}
else if (cmd == NOPE::cc_dump)
{
dump();
}
else if (cmd == NOPE::cc_instance_count)
{
return _ObjectCache.size();
}
// default return value
return 0;
}
void ::dump()
{
nlinfo(" Cache info for class :");
nlinfo(" There are %u object instances in cache", _ObjectCache.size());
// count the number of object in the released object set
uint32 nbReleased = 0;
TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end());
for (; first != last; ++first)
{
nbReleased += first->second.size();
}
nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased);
}
void ::updateCache()
{
if (_ReleasedObject.empty())
return;
// 30 s hold in cache
const time_t MAX_CACHE_OLD_TIME = 30;
time_t now = NLMISC::CTime::getSecondsSince1970();
// look for object set older than MAX_CACHE_OLD_TIME and delete them
while (!_ReleasedObject.empty() && _ReleasedObject.begin()->first < now-MAX_CACHE_OLD_TIME)
{
TObjectSet &delSet = _ReleasedObject.begin()->second;
// unload this objects
while (!delSet.empty())
{
*object = *delSet.begin();
delete object;
}
_ReleasedObject.erase(_ReleasedObject.begin());
}
}
void ::clearCache()
{
// remove any unreferenced object from the cache
while (!_ReleasedObject.empty())
{
TObjectSet &delSet = _ReleasedObject.begin()->second;
// unload this objects
while (!delSet.empty())
{
*object = *delSet.begin();
delete object;
}
_ReleasedObject.erase(_ReleasedObject.begin());
}
}
void ::registerUpdatable()
{
static bool registered = false;
if (!registered)
{
NOPE::CPersistentCache::getInstance().registerCache(&::cacheCmd);
registered = true;
}
}
// set the pointer on the first pointer of the pointer list (set to null when there is no more pointer)
void ::setFirstPtr(Ptr *ptr)
{
_PtrList = ptr;
if (ptr == NULL)
{
// this is the last pointer !
if (_ObjectState == NOPE::os_transient
|| _ObjectState == NOPE::os_removed)
{
// not a persistent object, or removed object, just delet it
delete this;
}
else if (_ObjectState != NOPE::os_removed)
{
setPersistentState(NOPE::os_released);
}
}
}
// Set the persistent state of the object and do some house keeping
void ::setPersistentState(NOPE::TObjectState state)
{
nlassert(NOPE::AllowedTransition[_ObjectState][state] == true);
if(_ObjectState == NOPE::os_released && state == NOPE::os_removed)
{
// a release object gets removed (e.g. by remove by id)
// delete the object
delete this;
// no more to do
return;
}
if (_ObjectState == NOPE::os_transient && state != NOPE::os_transient)
{
nldebug("NOPE: inserting @%p in cache with id %u", this, static_cast<uint32>(_));
nlverify(_ObjectCache.insert(std::make_pair(_, this)).second);
}
if (_ObjectState != NOPE::os_transient)
nlassert(_ObjectCache.find(_) != _ObjectCache.end());
_ObjectState = state;
if (state == NOPE::os_released)
{
_ReleaseDate = NLMISC::CTime::getSecondsSince1970();
nlverify(_ReleasedObject[_ReleaseDate].insert(this).second);
}
else if (state == NOPE::os_removed)
{
nldebug("NOPE: erasing @%p in cache with id %u", this, static_cast<uint32>(_));
nlverify(_ObjectCache.erase(_) == 1);
}
}
Ptr ::load(MSW::CConnection &connection, uint32 id, const char *filename, uint32 lineNum)
{
*inCache = loadFromCache(id, true);
if (inCache != NULL)
{
return Ptr(inCache, filename, lineNum);
}
std::string qs;
qs = "SELECT ";
qs += " FROM ";
Ptr ret;
if (!connection.query(qs))
{
return ret;
}
MSW::CStoreResult *result = connection.storeResult().release();
nlassert(result->getNumRows() <= 1);
if (result->getNumRows() == 1)
{
ret.assign(new , filename, lineNum);
// ok, we have an object
result->fetchRow();
{
std::string s;
result->getField(, s);
ret->_ = (s);
}
result->getDateField(, ret->_);
result->getMD5Field(, ret->_);
result->getField(, ret->_);
ret->setPersistentState(NOPE::os_clean);
}
delete result;
return ret;
}
bool ::loadChildrenOf(MSW::CConnection &connection, uint32 parentId, std::map < uint32, Ptr > & container, const char *filename, uint32 lineNum)
bool ::loadChildrenOf(MSW::CConnection &connection, uint32 parentId, std::vector < Ptr > & container, const char *filename, uint32 lineNum)
ERROR : parent/child relation support only 'map' or 'vector' cont specification in , parent definition
{
std::string qs;
qs = "SELECT ";
qs += " FROM ";
qs += " WHERE = '"+NLMISC::toString(parentId)+"'";
if (!connection.query(qs))
{
return false;
}
std::auto_ptr<MSW::CStoreResult> result = connection.storeResult();
for (uint i=0; i<result->getNumRows(); ++i)
{
*ret = new ();
// ok, we have an object
result->fetchRow();
{
std::string s;
result->getField(, s);
ret->_ = (s);
}
result->getDateField(, ret->_);
result->getMD5Field(, ret->_);
result->getField(, ret->_);
*inCache = loadFromCache(ret->_, true);
if (inCache != NULL)
{
container.insert(std::make_pair(inCache->getObjectId(), Ptr(inCache, filename, lineNum)));
container.push_back(Ptr(inCache, filename, lineNum));
// no more needed
delete ret;
}
else
{
ret->setPersistentState(NOPE::os_clean);
container.insert(std::make_pair(ret->getObjectId(), Ptr(ret, filename, lineNum)));
container.push_back(Ptr(ret, filename, lineNum));
}
}
return true;
}
bool ::loadChildOf(MSW::CConnection &connection, uint32 parentId, Ptr &childPtr, const char *filename, uint32 lineNum)
{
std::string qs;
qs = "SELECT ";
qs += " FROM ";
qs += " WHERE = '"+NLMISC::toString(parentId)+"'";
Ptr ret;
if (!connection.query(qs))
{
childPtr = Ptr();
return false;
}
std::auto_ptr<MSW::CStoreResult> result = connection.storeResult();
// check that the data description is consistent with database content
nlassert(result->getNumRows() <= 1);
if (result->getNumRows() == 1)
{
*object = new ;
// ok, we have an object
result->fetchRow();
{
std::string s;
result->getField(, s);
object->_ = (s);
}
result->getDateField(, object->_);
result->getMD5Field(, ret->_);
result->getField(, object->_);
*inCache = loadFromCache(object->_, true);
if (inCache != NULL)
{
ret.assign(inCache, filename, lineNum);
// no more needed
delete object;
}
else
{
object->setPersistentState(NOPE::os_clean);
ret.assign(object, filename, lineNum);
}
childPtr = ret;
return true;
}
// no result, but no error
childPtr = Ptr();
return true;
}
bool ::load(MSW::CConnection &connection, const char *filename, uint32 lineNum)
{
bool ret = true;
if (_ != NULL)
{
// the children are already loaded, just return true
return true;
}
// allocate the container
_ = new std::map < uint32, Ptr >;
_ = new std::vector < Ptr >;
// load the childs
ret &= ::loadChildrenOf(connection, getObjectId(), *_, filename, lineNum);
return ret;
}
const std::vector<Ptr> &::get() const
{
nlassert(_ != NULL);
return *_;
}
Ptr &::getByIndex(uint32 index) const
{
nlassert(_ != NULL);
nlassert(index < _->size());
return const_cast< Ptr & >(_->operator[](index));
}
Ptr &::getById(uint32 id) const
{
nlassert(_ != NULL);
std::vector<Ptr >::const_iterator first(_->begin()), last(_->end());
for (; first != last; ++first)
{
const Ptr &child = *first;
if (child->getObjectId() == id)
{
return const_cast< Ptr & >(child);
}
}
// no object with this id, return a null pointer
static Ptr nil;
return nil;
}
const std::map<uint32, Ptr> &::get() const
{
nlassert(_ != NULL);
return *_;
}
Ptr &::getById(uint32 id) const
{
nlassert(_ != NULL);
std::map<uint32, Ptr>::const_iterator it(_->find(id));
if (it == _->end())
{
// no object with this id, return a null pointer
static Ptr nil;
return nil;
}
return const_cast< Ptr & >(it->second);
}
ERROR : Invalide container, child must be either map or vector for child in class
bool ::load(MSW::CConnection &connection, const char *filename, uint32 lineNum)
{
if (_Loaded)
{
// the child is already loaded, just return true
return true;
}
bool ret = ::loadChildOf(connection, getObjectId(), _, filename, lineNum);
_Loaded = true;
return ret;
}
/** Return the one child object (or null if not) */
Ptr ::get()
{
nlassert(_Loaded);
return _;
}
class Itf : public Itf
class Itf
{
protected:
/// the callback server adaptor
std::auto_ptr<ICallbackServerAdaptor> _CallbackServer;
void getCallbakArray(NLNET::TCallbackItem *&arrayPtr, uint32 &arraySize)
{
static NLNET::TCallbackItem callbackArray[] =
{
{ "", Itf::cb_ },
};
arrayPtr = callbackArray;
arraySize = sizeofarray(callbackArray);
}
static void _cbConnection(NLNET::TSockId from, void *arg)
{
H_AUTO(__cbConnection);
Itf *_this = reinterpret_cast<Itf *>(arg);
_this->on__Connection(from);
}
static void _cbDisconnection(NLNET::TSockId from, void *arg)
{
H_AUTO(__cbDisconnection);
Itf *_this = reinterpret_cast<Itf *>(arg);
_this->on__Disconnection(from);
}
public:
/** Constructor, if you specify a replacement adaptor, then the object
* become owner of the adaptor (and it will be released with the
* interface).
*/
Itf(ICallbackServerAdaptor *replacementAdaptor = NULL)
: Itf(replacementAdaptor)
{}
Itf(ICallbackServerAdaptor *replacementAdaptor = NULL)
{
if (replacementAdaptor == NULL)
{
// use default callback server
_CallbackServer = std::auto_ptr<ICallbackServerAdaptor>(new CNelCallbackServerAdaptor(this));
}
else
{
// use the replacement one
_CallbackServer = std::auto_ptr<ICallbackServerAdaptor>(replacementAdaptor);
}
}
virtual ~Itf()
{
}
/// Open the interface socket in the specified port
void openItf(uint16 port)
{
NLNET::TCallbackItem *arrayPtr;
uint32 arraySize;
// add callback array of the base interface class
Itf::getCallbakArray(arrayPtr, arraySize);
_CallbackServer->addCallbackArray(arrayPtr, arraySize);
getCallbakArray(arrayPtr, arraySize);
_CallbackServer->addCallbackArray(arrayPtr, arraySize);
_CallbackServer->setConnectionCallback (_cbConnection, this);
_CallbackServer->setDisconnectionCallback (_cbDisconnection, this);
_CallbackServer->init(port);
}
/** Must be called evenly, update the network subclass to receive message
* and dispatch method invokation.
*/
void update()
{
H_AUTO(_update);
try
{
_CallbackServer->update();
}
catch (...)
{
nlwarning(" : Exception launch in callback server update");
}
}
void (NLNET::TSockId dest)
{
H_AUTO(_);
#ifdef NL_DEBUG
nldebug(":: called");
#endif
NLNET::CMessage message("");
_CallbackServer->send(message, dest);
}
static void cb_ (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase)
{
H_AUTO(_on_);
#ifdef NL_DEBUG
nldebug("::cb_ received from class '%s'", typeid(netbase).name());
#endif
ICallbackServerAdaptor *adaptor = static_cast< ICallbackServerAdaptor *>(netbase.getUserData());
Itf *callback = (Itf *)adaptor->getContainerClass();
if (callback == NULL)
return;
;
std::vector<> ;
#ifdef NL_DEBUG
nldebug("::cb_ : calling on_");
#endif
callback->on_(from, );
retValue;
std::vector<> retValue;
retValue = callback->on_(from, );
NLNET::CMessage retMsg("R_");
nlWrite(retMsg, serial, retValue);
nlWrite(retMsg, serialCont, retValue);
callback->_CallbackServer->send(retMsg, from);
}
/// Connection callback : a new interface client connect
virtual void on__Connection(NLNET::TSockId from) =0;
/// Disconnection callback : one of the interface client disconnect
virtual void on__Disconnection(NLNET::TSockId from) =0;
virtual void on_(NLNET::TSockId from) =0;
virtual on_(NLNET::TSockId from) =0;
virtual std::vector<> on_(NLNET::TSockId from) =0;
};
/** This is the client side of the interface
* Derive from this class to invoke method on the callback server
*/
class ClientItf : public ClientItf
class ClientItf
{
protected:
/// the callback client adaptor
std::auto_ptr < ICallbackClientAdaptor > _CallbackClient;
void getCallbakArray(NLNET::TCallbackItem *&arrayPtr, uint32 &arraySize)
{
arrayPtr = NULL;
arraySize = 0;
static NLNET::TCallbackItem callbackArray[] =
{
{ "", ClientItf::cb_ },
};
arrayPtr = callbackArray;
arraySize = sizeofarray(callbackArray);
}
static void _cbDisconnection(NLNET::TSockId from, void *arg)
{
ClientItf *_this = reinterpret_cast<ClientItf *>(arg);
_this->on_Client_Disconnection(from);
}
public:
/// Retreive the message name for a given callback name
static const std::string &getMessageName(const std::string &methodName)
{
static std::map<std::string, std::string> messageNames;
static bool initialized = false;
if (!initialized)
{
messageNames.insert(std::make_pair(std::string("on_"), std::string("")));
initialized = true;
}
std::map < std::string, std::string>::const_iterator it(messageNames.find(methodName));
if (it != messageNames.end())
return it->second;
// try with the base class
return ClientItf::getMessageName(methodName);
static std::string emptyString;
return emptyString;
}
ClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL)
: ClientItf(adaptorReplacement)
{}
ClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL)
{
if (adaptorReplacement == NULL)
{
// use the default Nel adaptor
_CallbackClient = std::auto_ptr < ICallbackClientAdaptor >(new CNelCallbackClientAdaptor(this));
}
else
{
// use the replacement one
_CallbackClient = std::auto_ptr < ICallbackClientAdaptor >(adaptorReplacement);
}
}
/// Connect the interface client to the callback server at the specified address and port
virtual void connectItf(NLNET::CInetAddress address)
{
NLNET::TCallbackItem *arrayPtr;
uint32 arraySize;
static bool callbackAdded = false;
if (!callbackAdded)
{
// add callback array of the base interface class
ClientItf::getCallbakArray(arrayPtr, arraySize);
_CallbackClient->addCallbackArray(arrayPtr, arraySize);
callbackAdded = true;
// add callback array of this interface
getCallbakArray(arrayPtr, arraySize);
_CallbackClient->addCallbackArray(arrayPtr, arraySize);
}
_CallbackClient->setDisconnectionCallback (_cbDisconnection, this);
_CallbackClient->connect(address);
}
/** Must be called evenly, update the network subclass to receive message
* and dispatch invokation returns.
*/
virtual void update()
{
H_AUTO(_update);
try
{
_CallbackClient->update();
}
catch (...)
{
nlwarning(" : Exception launch in callback client update");
}
}
void ()
{
#ifdef NL_DEBUG
nldebug("Client:: called");
#endif
NLNET::CMessage message("");
_CallbackClient->send(message);
}
static void cb_ (NLNET::CMessage &message, NLNET::TSockId from, NLNET::CCallbackNetBase &netbase)
{
#ifdef NL_DEBUG
nldebug("Client::cb_ received from class '%s'", typeid(netbase).name());
#endif
ICallbackClientAdaptor *adaptor = static_cast< ICallbackClientAdaptor *>(netbase.getUserData());
ClientItf *callback = (ClientItf *)adaptor->getContainerClass();
if (callback == NULL)
return;
;
std::vector<> ;
#ifdef NL_DEBUG
nldebug("Client::cb_ : calling on_");
#endif
callback->on_(from, );
}
/// Disconnection callback : the connection to the server is lost
virtual void on_Client_Disconnection(NLNET::TSockId from) =0;
virtual void on_(NLNET::TSockId from) =0;
};
ERROR : PHP interface only support uint8, uint32, enum and std::string parameter in callback interface '.'
<?php
/////////////////////////////////////////////////////////////////
// WARNING : this is a generated file, don't change it !
/////////////////////////////////////////////////////////////////
require_once('../tools/nel_message.php');
class extends CCallbackClient
{
function ()
{
$msg = new CMessage;
$msg->setName("");
return parent::sendMessage($msg);
$ret = "";
$ret = parent::sendMessage($msg);
if ($ret == false)
{
// error during send
$this->invokeError("", "Error in 'sendMessage'");
return false;
}
$retMsg = parent::waitMessage();
if ($ret == false)
{
// error during send
$this->invokeError("", "Error in 'waitMessage'");
return false;
}
if (!($retMsg->MsgName === "R_"))
{
// error during send
$this->invokeError("", "Invalid response, awaited 'R_', received '".$retMsg->MsgName."'");
return false;
}
// serial the return value
$ = new _;
// return the return value
return $retValue;
}
function waitCallback()
{
$message = parent::waitMessage();
if ($message == false)
return false;
switch($message->MsgName)
{
case "":
$this->_skel($message);
break;
default:
return false;
}
return true;
}
function _skel(&$message)
{
$ = new _;
$this->();
}
/////////////////////////////////////////////////////////////////
// Copy paste this part of code in your derived class
// and implement code to ract to incoming message
/////////////////////////////////////////////////////////////////
function ()
{
}
}
?>
$nbElem = 0;
->serialUInt32($nbElem);
$ = array();
for ($i=0; $i<$nbElem;$i++)
{
->($item);
$[] = $item;
}
->($);
->serialUint32(count($));
foreach($ as $key=>$value)
->($value);
->($);
$,
$,
class
{
friend class ;
const char *_FileName;
uint32 _LineNum;
// linked list of smart ptr
*_NextPtr;
*_PrevPtr;
*_Ptr;
void linkPtr();
void unlinkPtr();
public:
()
: _FileName(NULL),
_LineNum(0),
_Ptr(NULL),
_NextPtr(NULL),
_PrevPtr(NULL)
{
}
(const &other, const char *filename, uint32 lineNum)
: _FileName(filename),
_LineNum(lineNum),
_NextPtr(NULL),
_PrevPtr(NULL)
{
// point the same object
_Ptr = other._Ptr;
// insert the pointer in the list
linkPtr();
}
(const &other)
: _FileName(other._FileName),
_LineNum(other._LineNum),
_NextPtr(NULL),
_PrevPtr(NULL)
{
// point the same object
_Ptr = other._Ptr;
// insert the pointer in the list
linkPtr();
}
( *objectPtr, const char *filename, uint32 lineNum)
: _FileName(filename),
_LineNum(lineNum),
_NextPtr(NULL),
_PrevPtr(NULL)
{
_Ptr = objectPtr;
linkPtr();
}
&assign(const &other, const char *filename, uint32 lineNum)
{
_FileName = filename;
_LineNum = lineNum;
unlinkPtr();
_Ptr = other._Ptr;
linkPtr();
return *this;
}
~()
{
unlinkPtr();
}
&assign( *objectPtr, const char *filename, uint32 lineNum)
{
_FileName = filename;
_LineNum = lineNum;
unlinkPtr();
_Ptr = objectPtr;
linkPtr();
return *this;
}
&operator =(const &other)
{
return assign(other, __FILE__, __LINE__);
}
*operator ->()
{
return _Ptr;
}
const *operator ->() const
{
return _Ptr;
}
bool operator == (const &other) const
{
return _Ptr == other._Ptr;
}
bool operator != (const &other) const
{
return !operator ==(other);
}
bool operator == (const *object) const
{
return _Ptr == object;
}
bool operator != (const *object) const
{
return !operator ==(object);
}
/// Less then comparator : comparison on pointer object address
bool operator < (const &other) const
{
return _Ptr < other._Ptr;
}
/// Used to walk thrue the linked list of pointer
*getNextPtr()
{
return _NextPtr;
}
};
void ::linkPtr()
{
nlassert(_NextPtr == NULL);
nlassert(_PrevPtr == NULL);
if (_Ptr != NULL)
{
_NextPtr = _Ptr->getFirstPtr();
if (_NextPtr != NULL)
{
_PrevPtr = _NextPtr->_PrevPtr;
_PrevPtr->_NextPtr = this;
_NextPtr->_PrevPtr = this;
}
else
{
_NextPtr = this;
_PrevPtr = this;
_Ptr->setFirstPtr(this);
}
}
}
void ::unlinkPtr()
{
if (_NextPtr == NULL)
{
nlassert(_PrevPtr == NULL);
return;
}
if (_Ptr != NULL)
{
if (_NextPtr == this)
{
nlassert(_PrevPtr == this);
// last pointer !
_Ptr->setFirstPtr(NULL);
}
else
{
if (_Ptr->getFirstPtr() == this)
{
// the first ptr is the current one, we need to switch to next one
_Ptr->setFirstPtr(_NextPtr);
}
}
}
if (_NextPtr != this)
{
nlassert(_PrevPtr != this);
_NextPtr->_PrevPtr = _PrevPtr;
_PrevPtr->_NextPtr = _NextPtr;
}
_NextPtr = NULL;
_PrevPtr = NULL;
}