I am currently trying to create a system in which I want to be able to assign unique family ID’s to classes at runtime. Essentially I want to be able to distinguish between classes based on a integer-value after having them registered at runtime.
The use-case for this is that this system will be used as the bureaucrazy for a component system. All classes are descendant (not necessarily direct) from a class Component; and are registered at runtime.
I want to be able to do this for several reasons:
- Eaze and safety of extension: People will not have to modify a gigantic list in the base component system to add Components.
- Efficiency: Lookup internally is done using this integer value so can be O(1) instead of a search lookup. As these components will makeup the bulk of the system, I prefer not to make it an instance variable. I cannot ignore this aspect as testcases have already shown that I cannot afford > O(1) removal and insertion. (A first implementation used map lookup tables)
I am looking for a compile-time checked implementation; not a contract based solution.
A contract based solution in Java would be:
interface Component {
// Should return the value of a static variable
int getFamilyID();
int setFamilyID(int id);
}
class Foo implements Component {
static int familyID = 0;
int getFamilyID(){ return familyID; }
int setFamilyID(int id){ familyID = id; }
}
class System { // Singleton
static int registeredComponents = 0;
void register(Component c){ c.setFamilyID(registeredComponents++); }
}
This obviously doesn’t work for two reasons:
- I can’t specify A.getFamilyID() unless I make the variable public; usecase: c.getFamilyID() == Foo.getFamilyID(); (instead of instanceof)
- Redundant code all over the place; each implementation of Component would need to have the copy-pasted implementation.
I thought that I could solve the issue in C++ with a template that specified a static variable, but this becomes unusable when the class is not a direct descendant of Component.
I can also not use enums within Java as they are language-specific and the amount of components would make the code for a single file humongous. (also; they would all have to be specified in a single place again)
Any help in this matter or insight in why I’m trying to “do the wrong thing”(TM) would be quite helpfull 🙂
Edit: To clarify, I want some way to ensure at compile-time the code convention of a static integer which can be set in the component class.
In C++ you can use the curiously recurring template pattern in order to avoid code repetition.
Having set this up, you can easily create new classes in your Component class hierarchy.
The
assert(...)will automatically check at run-time, if you correctly derived from the template. So you will uncover bugs likeat run-time. This derived class would otherwise use the same interface implementation as the direct base and use the same static variable, which would be a bug.
You might have noticed that you don’t need to register any classes by hand. This is done via dynamic initialization of static variables before the main() function starts. So you don’t need to do anything about that. In this way you can easily implement your classes in one spot, without changing other files and without lots of code repetition – open/closed principle par excellence.