summaryrefslogtreecommitdiff
path: root/project2/common/scriptLoader.h
diff options
context:
space:
mode:
Diffstat (limited to 'project2/common/scriptLoader.h')
-rw-r--r--project2/common/scriptLoader.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/project2/common/scriptLoader.h b/project2/common/scriptLoader.h
new file mode 100644
index 0000000..d916821
--- /dev/null
+++ b/project2/common/scriptLoader.h
@@ -0,0 +1,141 @@
+#ifndef SCRIPTLOADER_H
+#define SCRIPTLOADER_H
+
+#include <set>
+#include <string>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include "intrusivePtrBase.h"
+#include "sourceObject.h"
+#include "exceptions.h"
+#include <glibmm/ustring.h>
+#include <map>
+#include <vector>
+
+enum UnsupportedHandling { ErrorOnUnsupported, WarnOnUnsupported, IgnoreUnsupported };
+class ElementLoader;
+class ComponentLoader;
+class CommonObjects;
+class Storer;
+class ScriptReader;
+
+class LoaderBase {
+ public:
+ typedef boost::intrusive_ptr<Storer> StorerPtr;
+ typedef std::vector<StorerPtr> StorerPtrs;
+ typedef std::map<ScriptNodePtr, StorerPtrs> Targets;
+
+ LoaderBase();
+ virtual ~LoaderBase();
+ void collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr script);
+
+ void addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target);
+
+ static void onAllComponents(const boost::function1<void, ComponentLoader *> &);
+
+ static std::set<boost::shared_ptr<ComponentLoader> > * & componentLoaders();
+
+ template <class T>
+ static std::map<std::string, boost::shared_ptr<T> > * & objLoaders()
+ {
+ static std::map<std::string, boost::shared_ptr<T> > * _objLoaders = NULL;
+ if (!_objLoaders) {
+ _objLoaders = new std::map<std::string, boost::shared_ptr<T> >();
+ }
+ return _objLoaders;
+ }
+
+ template <class T>
+ static void newLoader(const std::string & n, T * l)
+ {
+ boost::shared_ptr<T> p = boost::shared_ptr<T>(l);
+ objLoaders<T>()->insert(std::pair<std::string, boost::shared_ptr<T> >(n, p));
+ componentLoaders()->insert(boost::shared_ptr<T>(p));
+ }
+
+ template <class T>
+ static void removeLoader(const std::string & n)
+ {
+ std::map<std::string, boost::shared_ptr<T> > * & o = objLoaders<T>();
+ std::set<boost::shared_ptr<ComponentLoader> > * & c = componentLoaders();
+ typename std::map<std::string, boost::shared_ptr<T> >::iterator i = o->find(n);
+ c->erase(i->second);
+ o->erase(i);
+ if (o->empty()) {
+ delete o;
+ o = NULL;
+ }
+ if (c->empty()) {
+ delete c;
+ c = NULL;
+ }
+ }
+
+ template <class L, class E>
+ static boost::shared_ptr<L> getLoader(const std::string & n)
+ {
+ typename std::map<std::string, boost::shared_ptr<L> >::const_iterator i = objLoaders<L>()->find(n);
+ if (i != objLoaders<L>()->end()) {
+ return i->second;
+ }
+ else {
+ throw E(n);
+ }
+ }
+
+ private:
+ void collectAll(ScriptNodePtr script, bool childrenOnly, const StorerPtrs & sts) const;
+ Targets targets;
+ static unsigned int depth;
+ template <class X> friend class ElementLoaderImpl;
+ static std::set<SourceObjectPtr> loadedObjects;
+
+ const bool recursive;
+
+ public:
+ const Glib::ustring ns;
+};
+
+#define DECLARE_CUSTOM_COMPONENT_LOADER(N, I, T, B) \
+ static void init_loader_##I() __attribute__ ((constructor(201))); \
+ static void init_loader_##I() { LoaderBase::newLoader<B>(N, new T()); } \
+ static void kill_loader_##I() __attribute__ ((destructor(201))); \
+ static void kill_loader_##I() { LoaderBase::removeLoader<B>(N); }
+#define DECLARE_CUSTOM_LOADER(N, T) \
+ DECLARE_CUSTOM_COMPONENT_LOADER(N, T, T, ElementLoader)
+#define DECLARE_COMPONENT_LOADER(N, T, B) \
+ DECLARE_CUSTOM_COMPONENT_LOADER(N, T, B##Impl<T>, B)
+#define DECLARE_LOADER(N, T) \
+ DECLARE_COMPONENT_LOADER(N, T, ElementLoader)
+
+/// Helper for loading and maintaining Project2 components
+class Options;
+class ComponentLoader {
+ public:
+ virtual void onBegin(); // App engine start up (before settings are processed)
+ virtual void onBefore(); // Before the app engine processes a request (after settings are processed)
+ virtual void onIdle(); // When the app engine goes idle
+ virtual void onIteration(); // When the app engine has completed an iteration
+ virtual void onPeriodic(); // When the app engine feels like it
+ virtual const Options * options() const; // Options to be populated from the common config file/env/etc
+};
+/// Helper for loading and maintaining Project2 script components
+class ElementLoader : public ComponentLoader {
+ public:
+ virtual SourceObjectPtr createFrom(ScriptNodePtr) const = 0;
+};
+
+/// Helper for loading and maintaining Project2 script components (typed implementation)
+template <class X>
+class ElementLoaderImpl : public ElementLoader {
+ public:
+ SourceObjectPtr createFrom(ScriptNodePtr sn) const
+ {
+ SourceObjectPtr sop = new X(sn);
+ LoaderBase::loadedObjects.insert(sop);
+ return sop;
+ }
+};
+#endif
+