I've re-worked the name registry to be as un-global-y as possible, and would appreciate a sanity check.

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

www.zealforyourhouse.com
dissatisfied with the spiritual status quo
Dr. Adam D. Bradley
[EMAIL PROTECTED]
978-390-1237
The Christian ideal has not been tried and found wanting. It has been found difficult; and left untried. -G.K.Chesterton

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to