diff options
Diffstat (limited to 'project2/common/scriptLoader.h')
-rw-r--r-- | project2/common/scriptLoader.h | 141 |
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 + |