From d04a9fdfe2fae53a4a633db465eb8b379bbd974d Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sat, 17 Nov 2007 00:12:01 +0000
Subject: [PATCH] add wxModule::AddDependency(name) overload (patch 1790451)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@50012 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/module.tex | 31 +++++++++++++++++++++++++++++--
 include/wx/module.h      | 20 ++++++++++++++++++--
 src/common/module.cpp    | 26 ++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/docs/latex/wx/module.tex b/docs/latex/wx/module.tex
index bce6095112..92a4349df1 100644
--- a/docs/latex/wx/module.tex
+++ b/docs/latex/wx/module.tex
@@ -38,13 +38,30 @@ For example:
   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}
@@ -80,17 +97,27 @@ Destructor.
 
 \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}
 
diff --git a/include/wx/module.h b/include/wx/module.h
index e255fe8bbd..bff799aaa9 100644
--- a/include/wx/module.h
+++ b/include/wx/module.h
@@ -73,6 +73,14 @@ protected:
         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
@@ -84,11 +92,19 @@ private:
     // 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
diff --git a/src/common/module.cpp b/src/common/module.cpp
index 9f867b4c25..230b8aa577 100644
--- a/src/common/module.cpp
+++ b/src/common/module.cpp
@@ -79,6 +79,10 @@ bool wxModule::DoInitializeModule(wxModule *module,
 
     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
@@ -197,3 +201,25 @@ void wxModule::DoCleanUpModules(const wxModuleList& modules)
     // 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;
+}
-- 
2.50.0

