Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

class.cpp

Go to the documentation of this file.
00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
00002 
00003    this file is part of rcssserver3D
00004    Fri May 9 2003
00005    Copyright (C) 2002,2003 Koblenz University
00006    Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group
00007    $Id: class.cpp,v 1.9 2004/04/25 16:33:30 rollmark Exp $
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; version 2 of the License.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 #include "class.h"
00023 #include "leaf.h"
00024 #include "core.h"
00025 #include <iostream>
00026 
00027 using namespace boost;
00028 using namespace std;
00029 using namespace zeitgeist;
00030 
00031 Class::Class(const std::string &name) : Leaf(name)
00032 {
00033 }
00034 
00035 Class::~Class()
00036 {
00037     if (mInstances.size() > 0)
00038     {
00039         cout << "(Class) Leaked "
00040              << mInstances.size() << " instances..." << endl;
00041 
00042         for (
00043              TObjectList::iterator i = mInstances.begin();
00044              i != mInstances.end(); ++i
00045              )
00046         {
00047             if (shared_ptr<Object> j = i->lock())
00048             {
00049                 cout << "    " << j.get() << endl;
00050             } else
00051             {
00052                 cout << "    " << "(expired)" << endl;
00053             }
00054         }
00055     }
00056 }
00057 
00058 boost::shared_ptr<Object> Class::Create()
00059 {
00060     shared_ptr<Object> obj(CreateInstance());
00061 
00062     if (obj.get())
00063     {
00064         if (obj->Construct(obj, shared_static_cast<Class>
00065                            (make_shared(GetSelf()))) == true)
00066         {
00067             // successfully constructed
00068             AttachInstance(obj);
00069         }
00070         else
00071         {
00072             obj.reset();
00073         }
00074     }
00075 
00076     return obj;
00077 }
00078 
00079 boost::shared_ptr<Core> Class::GetCore() const
00080 {
00081     if (mCore.expired())
00082         {
00083             std::cerr << "(Class) ERROR: failed to get zeitgeist Core for class '"
00084                       << GetName() << "'" << std::endl;
00085 
00086         }
00087 
00088     return make_shared(mCore);
00089 }
00090 
00091 void Class::AttachInstance(const boost::weak_ptr<Object> &instance)
00092 {
00093     mInstances.push_back(instance);
00094 }
00095 
00096 void Class::DetachInstance(const boost::weak_ptr<Object> &instance)
00097 {
00098     // mInstances.remove() doesn't work in this case because
00099     // operator== is not implemented for weak_ptr
00100     TObjectList::iterator first = mInstances.begin();
00101     TObjectList::iterator last = mInstances.end();
00102 
00103     while (first != last)
00104     {
00105         TObjectList::iterator next = first;
00106         ++next;
00107 
00108         boost::shared_ptr<Object> i = first->lock();
00109         boost::shared_ptr<Object> j = instance.lock();
00110 
00111         if (i.get() == j.get())
00112         {
00113             mInstances.erase(first);
00114         }
00115         first = next;
00116     }
00117 }
00118 
00119 Object* Class::CreateInstance() const
00120 {
00121     return NULL;
00122 }
00123 
00124 void Class::AttachTo(const boost::weak_ptr<Core>& core)
00125 {
00126     mCore = core;
00127 }
00128 
00129 void Class::SetBundle(const boost::shared_ptr<salt::SharedLibrary> &bundle)
00130 {
00131     mBundle = bundle;
00132 }
00133 
00134 Class::TCmdProc Class::GetCmdProc(const std::string &functionName) const
00135 {
00136     TCommandMap::const_iterator cmd = mFunctions.find(functionName);
00137 
00138     if (cmd != mFunctions.end())
00139     {
00140         return (*cmd).second;
00141     }
00142 
00143     // ok, we don't have the requested function, so we'll try the base
00144     // class objects
00145     shared_ptr<Leaf> classDir = GetCore()->Get("/classes");
00146 
00147     for (
00148          TStringList::const_iterator baseClass = mBaseClasses.begin();
00149          baseClass != mBaseClasses.end();
00150          ++baseClass
00151          )
00152     {
00153         // this should get the base class object (it has to live on
00154         // the same level of the hierarchy as this class object)
00155         shared_ptr<Class> theClass = shared_static_cast<Class>
00156             (GetCore()->Get(*baseClass, classDir));
00157 
00158         if (theClass)
00159         {
00160             // now, we ask the class object, if it knows the command
00161             // in question
00162             TCmdProc theCmd = theClass->GetCmdProc(functionName);
00163             //printf("theCmd: %s - %d\n", functionName.c_str(), theCmd);
00164 
00165             if (theCmd != NULL)
00166             {
00167                 // here we have found the command and return it
00168                 return theCmd;
00169             }
00170         }
00171     }
00172 
00173     return NULL;
00174 }
00175 
00176 const Class::TStringList& Class::GetBaseClasses() const
00177 {
00178     return mBaseClasses;
00179 }
00180 
00181 bool Class::SupportsCommand(const std::string & name) const
00182 {
00183     return (GetCmdProc(name) != 0);
00184 }
00185 
00186 bool Class::SupportsClass(const std::string &name) const
00187 {
00188     if (GetName().compare(name) == 0)
00189     {
00190         return true;
00191     }
00192 
00193     // check base-classes
00194     shared_ptr<Leaf> classDir = GetCore()->Get("/classes");
00195 
00196     for (
00197          TStringList::const_iterator i = mBaseClasses.begin();
00198          i != mBaseClasses.end();
00199          ++i
00200          )
00201     {
00202         shared_ptr<Class> theClass = shared_static_cast<Class>
00203             (GetCore()->Get(*i, classDir));
00204 
00205         if (theClass)
00206         {
00207             if (theClass->SupportsClass(name))
00208             {
00209                 return true;
00210             }
00211         }
00212         else
00213         {
00214             cout << "(Class) WARNING: Illegal BaseClass '" << (*i)
00215                  << "' in Class '" << GetName() << "'" << endl;
00216         }
00217     }
00218 
00219     return false;
00220 }

Generated on Thu Apr 6 15:25:37 2006 for rcssserver3d by  doxygen 1.4.4