Basically, any module (plugin, app, etc) that needs event name resolution has to call csEventNameRegistry::Register(object_reg) with a valid iObjectRegistry pointer. After this, they call the (static) method csEventNameRegsitry::GetID("whatever.string") and are routed to the name registry associated with the current object registry (which is also stored using the STATIC_CLASSVAR mechanism).
This is a caricature of the code to show all the salent bits:
In "eventnames.h":
class CS_CRYSTALSPACE_EXPORT csEventNameRegistry : public iBase
{
public:
SCF_DECLARE_IBASE;
CS_DECLARE_STATIC_CLASSVAR(static_name_registry,GetRegistry,csEventNameRegistry*)
/**
* Associate an EventNameRegistry with an iObjectRegistry.
*/
static void Register (iObjectRegistry*);
/**
* Invoke this method to get a csEventID for an event name string
* (e.g., "crystalspace.input.keyboard.down").
*/
CS_CONST_METHOD static csEventID GetID (const char *name);
/**
* Invoke this method to retrieve a string representation of id.
*/
CS_CONST_METHOD static const char* GetString (const csEventID id);
/**
* Get the ID of the parent event name, e.g., the parent of
* "crystalspace.input.joystick" is "crystalspace.input".
*/
CS_CONST_METHOD static csEventID GetParentID (const csEventID id);
/**
* Returns true iff child is the immediate child of parent,
* e.g., "crystalspace.input" is the immediate child of "crystalspace"
* but "crystalspace.input;mouse" is not.
*/
CS_CONST_METHOD static bool IsImmediateChildOf (const csEventID child, const csEventID parent);
/**
* Return true iff child is either parent or a descendent of
* parent, e.g., "crystalspace.input.mouse" is a kind of
* "crystalspace", "crystalspace.input", and "crystalspace.input.mouse",
* but not of "crystalspace.input.mouse.2".
*/
CS_CONST_METHOD static bool IsKindOf (const csEventID child, const csEventID parent);
private:
static iObjectRegistry *object_reg;
csHash<csEventID,csEventID> parentage;
csStringSet names;
csEventNameRegistry();
public:
~csEventNameRegistry();
};
in "eventnames.c":
SCF_IMPLEMENT_IBASE (csEventNameRegistry)
SCF_IMPLEMENT_IBASE_END
CS_IMPLEMENT_STATIC_CLASSVAR (csEventNameRegistry,static_name_registry,GetRegistry,csEventNameRegistry*,(0));
iObjectRegistry *csEventNameRegistry::object_reg = 0;
void csEventNameRegistry::Register (iObjectRegistry *new_object_reg)
{
CS_ASSERT((csEventNameRegistry::object_reg == 0) ||
(csEventNameRegistry::object_reg == new_object_reg));
if (object_reg == 0)
{
object_reg = new_object_reg;
if (object_reg->Get("csEventNameRegistry") == 0) {
csEventNameRegistry *nameRegistry = new csEventNameRegistry();
object_reg->Register(nameRegistry, "csEventNameRegistry");
}
}
*GetRegistry() = (csEventNameRegistry *) object_reg->Get("csEventNameRegistry");
}
csEventNameRegistry::csEventNameRegistry() :
parentage(),
names()
{
SCF_CONSTRUCT_IBASE(0);
}
csEventNameRegistry::~csEventNameRegistry()
{
SCF_DESTRUCT_IBASE();
}
csEventID csEventNameRegistry::GetID (const char *name)
{
csEventNameRegistry *registry = *GetRegistry();
CS_ASSERT(registry != 0);
if (registry->names.Contains(name))
return registry->names.Request(name);
csEventID res = registry->names.Request(name);
char *parent;
if (strrchr(name, '.') != NULL)
{
/* This is a sub-name, populate Parentage table while
ensuring (recursively) for parent registration */
parent = strdup(name);
*strrchr(parent, '.') = '\0';
}
else if (strlen(name)>0)
{
parent = strdup("");
}
else
{
parent = NULL;
}
if (parent)
{
registry->parentage.PutUnique(res, GetID(parent));
free(parent);
}
return res;
}
... etc, following the same idioms as GetID() ...
If this passes muster, then the patch is ready to go in.
Adam
|
signature.asc
Description: This is a digitally signed message part
