class MyModule: public wxModule
{
public:
- wxDDEModule() { AddDependency(CLASSINFO(wxDDEModule)); }
+ MyModule() { AddDependency(CLASSINFO(wxDDEModule)); }
virtual bool OnInit() { ... code using DDE ... }
virtual void OnExit() { ... }
private:
- DECLARE_DYNAMIC_CLASS(wxDDEModule)
+ DECLARE_DYNAMIC_CLASS(MyModule)
};
+
+ IMPLEMENT_DYNAMIC_CLASS(MyModule, wxModule)
+
+ // Another module which uses DDE in its OnInit()
+ // but uses a named dependency
+ class MyModule2: public wxModule
+ {
+ public:
+ MyModule2() { AddDependency("wxDDEModule"); }
+ virtual bool OnInit() { ... code using DDE ... }
+ virtual void OnExit() { ... }
+
+ private:
+ DECLARE_DYNAMIC_CLASS(MyModule2)
+ };
+
+ IMPLEMENT_DYNAMIC_CLASS(MyModule2, wxModule)
\end{verbatim}
\wxheading{Derived from}
\func{void}{AddDependency}{\param{wxClassInfo * }{dep}}
+\func{void}{AddDependency}{\param{const char * }{classname}}
+
Call this function from the constructor of the derived class. \arg{dep} must be
the \helpref{CLASSINFO}{classinfo} of a wxModule-derived class and the
corresponding module will be loaded \emph{before} and unloaded \emph{after}
this module.
+The second version of this function allows a dependency to be added by
+name without access to the class info. This is useful when a module is
+declared entirely in a source file and there is no header for the declaration
+of the module needed by \helpref{CLASSINFO}{classinfo}, however errors are
+not detected until run-time, instead of compile-time, then.
+
Note that circular dependencies are detected and result in a fatal error.
\wxheading{Parameters}
\docparam{dep}{The class information object for the dependent module.}
+\docparam{classname}{The class name of the dependent module.}
+
\membersection{wxModule::OnExit}\label{wxmoduleonexit}
m_dependencies.Add(dep);
}
+ // same as the version above except it will look up wxClassInfo by name on
+ // its own
+ void AddDependency(const char *className)
+ {
+ m_namedDependencies.Add(className);
+ }
+
+
private:
// initialize module and Append it to initializedModules list recursively
// calling itself to satisfy module dependencies if needed
// could be initialized) and also empty m_modules itself
static void DoCleanUpModules(const wxModuleList& modules);
+ // resolve all named dependencies and add them to the normal m_dependencies
+ bool ResolveNamedDependencies();
+
- // module dependencies: contains
+ // module dependencies: contains wxClassInfo pointers for all modules which
+ // must be initialized before this one
wxArrayClassInfo m_dependencies;
- // used internally while initiliazing/cleaning up modules
+ // and the named dependencies: those will be resolved during run-time and
+ // added to m_dependencies
+ wxArrayString m_namedDependencies;
+
+ // used internally while initializing/cleaning up modules
enum
{
State_Registered, // module registered but not initialized yet
module->m_state = State_Initializing;
+ // translate named dependencies to the normal ones first
+ if ( !module->ResolveNamedDependencies() )
+ return false;
+
const wxArrayClassInfo& dependencies = module->m_dependencies;
// satisfy module dependencies by loading them before the current module
// clear all modules, even the non-initialized ones
WX_CLEAR_LIST(wxModuleList, m_modules);
}
+
+bool wxModule::ResolveNamedDependencies()
+{
+ // first resolve required dependencies
+ for ( size_t i = 0; i < m_namedDependencies.size(); ++i )
+ {
+ wxClassInfo *info = wxClassInfo::FindClass(m_namedDependencies[i]);
+
+ if ( !info )
+ {
+ // required dependency not found
+ return false;
+ }
+
+ // add it even if it is not derived from wxModule because
+ // DoInitializeModule() will make sure a module with the same class
+ // info exists and fail if it doesn't
+ m_dependencies.Add(info);
+ }
+
+ return true;
+}