// edm_registry.h #ifndef INCLUDED_EDM_REGISTRY #define INCLUDED_EDM_REGISTRY // PURPOSE // Provide the functionality for registering types and validating any // required run-time type dependencies at start-up. // // CLASSES // edm_RegElem: Protocol class. Support for insulated dynamic casting // and virtual construction. // edm_Registry: Static class providing a central registry of // reconstructor types and their dependencies with // requirements checking. // // DESCRIPTION // The registry has only static functions and is intended to be used at start // up. The main program instantiates the particular reconstructor types that // will be used in the executable and adds them to the registry. The // registry calls each reconstructor's registerDependencies function. The // main program then calls the registry's isValid function, to cross check // all required dependencies, and returns a good or bad status and optionally // writes out logging messages to a specified stream. // // edm_RegElem insulates edm_Registry from any particular chunk type other // than the protocol edm_Chunk. // // NOTE: *IMPORTANT* The registry's cleanup function must be called before the // program exits in order to avoid errorneous memory leak messages from // tools such as Purify. class ostream; class edm_Chunk; class edm_Reconstructor; template class auto_ptr; // ================= // CLASS edm_RegElem // ================= class edm_RegElem { public: // CREATORS virtual ~edm_RegElem(); // ACCESSORS virtual void clone(auto_ptr *handle) const = 0; // Create a dynamically allocated copy of this registry element and // load it in the handle provided. The behavior is undefined if handle // is 0. // // The implementation of this function should look something like: // // void MyRegElem::clone(auto_ptr *handle) const // { // *handle = auto_ptr( new MyRegElem(*this)); // } // // Where MyVia is the name of the concrete via type. virtual void createChunk(auto_ptr *handle) const = 0; // Create a dynamically allocated chunk object and load it in the // handle provided. The behavior is undefined if handle is 0. virtual bool isA(const edm_Chunk& chunk) const = 0; // Return true if the specified chunk is of a particular type // known by this elem. virtual const char* className() const = 0; // Return the name of the class which this registry element points to. // NOTE: This name cannot be used for a persistent identification. The // name is non-portable and can change across program executions. }; // ================== // CLASS edm_Registry // ================== class edm_Registry_i; class edm_Registry { static edm_Registry_i *s_this; public: // MANIPULATORS static void addRecon(const edm_Reconstructor& recon); // Register a reconstuctor if the registry is not closed. This method // should only be called by the main program. static void addInput(const edm_RegElem& elem); // Add a registry element which represents a chunk dependency if the // registry is not closed. This method is intended to be called // by all reconstructor types. static void addOutput(const edm_RegElem& elem); // Add a registry element which represents a chunk type output if the // registry is not closed. This method is intended to be called by all // reconstructor types. static bool isValid(); static bool isValid(ostream& err); // Close the registry and perform a check on whether the required // reconstructors have been registered. Return false if any // reconstructors are missing or if non have been registered; else // return true. Any error messages will be sent to the specified // stream. static void cleanUp(); // Destroy all objects created within the registry. This function // should be called before the program exits. // ACCESSORS static bool isClosed(); // Return true if the registry is closed (i.e. further requests to add // registry elements are ignored); else return false. static void print(ostream& o); // Print out internal registry info; used for debugging only. }; #endif