core.h
来自「rcssserver3d Robocup 3D比赛官方指定平台」· C头文件 代码 · 共 382 行
H
382 行
/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: core.h,v 1.9 2008/02/20 17:16:29 hedayat Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#ifndef ZEITGEIST_CORE_H#define ZEITGEIST_CORE_H#include <string>#include <list>#include <map>#include <set>#include <boost/shared_ptr.hpp>#include <boost/weak_ptr.hpp>namespace salt{class SharedLibrary;}namespace zeitgeist{class Class;class Leaf;class Node;class FileServer;class LogServer;class ScriptServer;class CoreContext;class Object;class RandomServer;/** The Core is the hierarchy, i.e. it creates the root node, some basic class objects and installs fundamental server classes needed to run zeitgeist system. Further it provides a mechanism to import bundles- plugins containg new classes, that can be registered to the framework at runtime. */class Core{public: // // types // /** CacheKey is a struct used as the key for the internal node lookup cache */ struct CacheKey { public: //! node to which the path of this key is relative to boost::weak_ptr<Leaf> root; //! the path expression of this key std::string path; public: CacheKey() {} CacheKey(boost::weak_ptr<Leaf> r, const std::string& p) : root(r), path(p) {}; bool operator == (const CacheKey& key) const; bool operator < (const CacheKey& key) const; }; /** CachedLeafPath defines a pair of path key and it's corresponding weak reference. It acts like a smart pointer that is able to update the keep the managed reference up to date with the help of the core and the CacheKey */ struct CachedLeafPath { protected: CacheKey key; boost::weak_ptr<Leaf> leaf; public: // need to have virtual destructor virtual ~CachedLeafPath() {} const CacheKey& GetKey() { return key; } void SetKey(const CacheKey& k) { key = k; } boost::weak_ptr<Leaf>& GetLeaf() { return leaf; } virtual void Cache(boost::shared_ptr<Core> core, const std::string& pathStr) = 0; virtual void Update(boost::shared_ptr<Core> core) = 0; bool operator == (const CachedLeafPath& p) { return (key == p.key); } bool operator < (const CachedLeafPath& p) { return (key < p.key); } bool expired() { return leaf.expired(); } void reset() { leaf.reset(); } }; template<typename _CLASS> struct CachedPath : public CachedLeafPath { public: CachedPath() : CachedLeafPath() {} CachedPath(const CacheKey& k, const boost::weak_ptr<_CLASS> &l) : CachedLeafPath(k,l) {} virtual void Cache(boost::shared_ptr<Core> core, const std::string& pathStr) { if (core.get() == NULL) { leaf.reset(); return; } key = CacheKey(core->mRoot, pathStr); Update(core); } virtual void Update(boost::shared_ptr<Core> core) { if (core.get() == NULL) { leaf.reset(); return; } // lookup the path in the internal core cache boost::weak_ptr<Leaf> lookup = core->GetCachedInternal(key); if (! lookup.expired()) { leaf = boost::shared_dynamic_cast<_CLASS>(lookup.lock()); return; } leaf = boost::shared_dynamic_cast<_CLASS> (core->GetUncachedInternal(key)); } boost::shared_ptr<_CLASS> get() { return boost::shared_static_cast<_CLASS>(leaf.lock()); } _CLASS* operator -> () { return boost::shared_static_cast<_CLASS>(leaf.lock()).get(); } };protected: /** TPathCache defines a mapping from a CacheKey to a weak reference of the corresponding Leaf */ typedef std::map<CacheKey, boost::weak_ptr<Leaf> > TPathCache; /** TBundleMap defines a registry of loaded bundles */ typedef std::pair<std::string, boost::shared_ptr<salt::SharedLibrary> > TBundlePair; typedef std::map<std::string, boost::shared_ptr<salt::SharedLibrary> > TBundleMap; // // functions //public: Core(); ~Core(); /** Constructs the core, i.e. sets up the root object, registers some class objects for internal zeitgeist classes and creates servers for the basic services */ void Construct(const boost::weak_ptr<Core>& self); /** Destructs the core, i.e. unlinks the hierarchy below the root object */ void Desctruct(); /** creates a context for this Core */ boost::shared_ptr<CoreContext> CreateContext(); /** creates an instance of the class 'className' */ boost::shared_ptr<Object> New(const std::string& className); /** returns true iff the given class exists */ bool ExistsClass(const std::string& className); /** registers a class object * \param classObject is a reference to instance of the class object * \param subDir gives the directory below "/classes" where the * class object will be installed */ bool RegisterClassObject(const boost::shared_ptr<Class> &classObject, const std::string &subDir); /** registers a class object * \param classObject is a reference to instance of the class object * \param subDir gives the directory below "/classes" where the * class object will be installed */ bool RegisterClassObject(Class *classObject, const std::string &subDir); /** imports a bundle, i.e. registers classes contained inside * a plugin to the framework. * \param bundleName is the filneName of the bundle */ bool ImportBundle(const std::string& bundleName); /** returns a reference to the FileServer */ const boost::shared_ptr<FileServer>& GetFileServer() const; /** returns a reference to the LogServer */ const boost::shared_ptr<LogServer>& GetLogServer() const; /** returns a reference to the ScriptServer */ const boost::shared_ptr<ScriptServer>& GetScriptServer() const; /** returns a reference to the root node */ boost::shared_ptr<Leaf> GetRoot() const { return mRoot; } /** returns a reference to the object denoted by the path expression 'pathStr'. */ boost::shared_ptr<Leaf> Get(const std::string &pathStr); /** returns a reference to the object denoted by the path expression 'pathStr', relative to the node base. */ boost::shared_ptr<Leaf> Get(const std::string &pathStr, const boost::shared_ptr<Leaf>& base); /** returns true iff the object denoted by the path expression 'pathStr', relative to the node base exists */ bool Test(const std::string &pathStr, const boost::shared_ptr<Leaf>& base); /** returns true iff the object denoted by the path expression 'pathStr' exists. */ bool Test(const std::string &pathStr); /** returns a reference to a child node of 'parent' with the name 'childName' */ boost::shared_ptr<Leaf> GetChild(const boost::shared_ptr<Leaf> &parent, const std::string &childName); /** attaches the class 'newClass' to this core */ void BindClass(const boost::shared_ptr<Class> &newClass) const; /** releases all unused bundles, i.e. bundles the core holds the only reference to */ void GarbageCollectBundles();protected: /** returns a cached reference to the Leaf corresponding to the given key. If the cached reference expired the entry is removed from the cache */ boost::weak_ptr<Leaf> GetCachedInternal(const CacheKey& key); /** returns a reference to the object denoted by the path expression 'pathStr', relative to the node base. This method does not lookup for a cached reference but does update the cache accordingly */ boost::shared_ptr<Leaf> GetUncachedInternal(const CacheKey& key); /** checks that the leaf reference isn't expired and inserts the given key,leaf pair into the cache */ void PutCachedInternal(const CacheKey& key, const boost::weak_ptr<Leaf>& leaf); /** returns a reference to the object denoted by the path expression 'pathStr', relative to the node base. */ boost::shared_ptr<Leaf> GetInternal(const std::string &pathStr, const boost::shared_ptr<Leaf>& base); /** signal handler */ static void CatchSignal(int sig_num); // // members //private: /** a reference to the root node */ boost::shared_ptr<Leaf> mRoot; /** a reference to the class object of the node class */ boost::shared_ptr<Class> mNodeClass; /** a reference to the class object of the 'class' class */ boost::shared_ptr<Class> mClassClass; /** a reference to the file server */ boost::shared_ptr<FileServer> mFileServer; /** a reference to the logserver */ boost::shared_ptr<LogServer> mLogServer; /** a reference to the scriptserver */ boost::shared_ptr<ScriptServer> mScriptServer; /** a reference to the randomserver */ boost::shared_ptr<RandomServer> mRandomServer; /** a reference to the core, a smart this pointer */ boost::weak_ptr<Core> mSelf; /** a registry of all registered bundles. Whenever we load a bundle, we add it to this map. This is necessary, because we have to keep the connection to each bundle open, until all the class objects belonging to it are completely destructed. This workaround is very ugly ... it cost me about 3-4 hours of debugging to get this to work. Somehow, when I destroyed a class belonging to a bundle, it prevented the rest of the hierarchy deletion from working ... ouch. I have no idea, why this happened. Now, when I keep the bundles (DLLs,SOs) open for a while longer, then everything is nice and dandy. NOTE: I had this first as a member of Core, but I can't control the order in which the members are released and I would have to guarantee that gBundles gets deleted AFTER mRoot. Switching the order the variables are defined would probably take care of that, but sounds quite unportable, so I went with this option (making it global). I have added a 'GarbageCollectBundles' function, which erases 'unique' references. WARNING: Just making this global is (apparently) not enough. */ TBundleMap mBundles; //! the internal node lookup cache TPathCache mPathCache;};} //namespace zeitgeist#endif //ZEITGEIST_CORE_H
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?