Source: data-flow/include/Object.h


Annotated List
Files
Globals
Hierarchy
Index
// Copyright (C) 1999 Jean-Marc Valin

#ifndef _OBJECT_H_
#define _OBJECT_H_

#include "typemap.h"
#include "rc_ptrs.h"
#include <string>
#include <map>
#include "BaseException.h"
#include <typeinfo>

class Object;
/** Smart pointer to Object called ObjectRef
    @author Jean-Marc Valin
    @version 1.0
 */
typedef RCPtr<Object> ObjectRef;

class _ObjectFactory;

/** Our Object base class. Everything in the network must have Object as 
    base class.
    @author Dominic Letourneau & Jean-Marc Valin
*/
class Object {
  protected:
   
   int ref_count;
   
public:

   /**default constructor*/
   Object() : ref_count(1) {}

   /**destructor*/
   virtual ~Object() { }

   /**Notify the object we're adding a reference*/
   void ref() 
   {
      ref_count++;
   }

   /**Notify the object we're removing a reference (might destroy the object)*/
   void unref()
   {
      if (--ref_count==0)
      {
	 destroy();
      }
   }

   /**Returns the number of references*/
   int getCount () {return ref_count;}

   /**Causes the object to be destroyed, it might be redefined for an object pool*/
   virtual void destroy()
   {
      delete this;
   }

   /**Serialize (binary) the object to a stream*/
   virtual void serialize(ostream &out) const;

   /**Unserialize (binary) the object from a stream*/
   virtual void unserialize(istream &in);
   
   /**How to handle an ununderstood method (VMethod)*/
   virtual void doesNotUnderstand(string method);

   /**Generic print function*/
   virtual void printOn(ostream &out=cout) const = 0;

   /**Is it a nil Object*/
   virtual bool isNil() const {return false;}
   
   /**Prints an object in a more "user-friendly" format*/
   virtual void prettyPrint(ostream &out=cout) const
   {
      printOn(out);
   }

   /**Generic read function*/
   virtual void readFrom(istream &in=cin)
   {
      throw new GeneralException("Trying to read undefined Object", __FILE__, __LINE__);
   }

   /**Prints the object to a stream*/
   friend ostream &operator << (ostream &out, const Object& obj) 
   {
      obj.printOn (out);
      return out;
   }

   /**Makes a (deep) copy of the object*/
   virtual ObjectRef clone()
   {
      throw new GeneralException("Method clone() not implemented for this object", __FILE__, __LINE__);
   }

   /**Returns the name of the class of the Object*/
   virtual string className() const;
      
   /**Creates an instance of an object by class name*/
   static ObjectRef newObject(const string &objType);

#ifndef BROKEN_TEMPLATES /*Workaround for a compiler crash */

   /**Registers the object name*/
   template<class T>
   static int addObjectType(const string &objType, _ObjectFactory *factory)
   {
      ObjectFactoryDictionary()[objType] = factory;
      TypeidDictionary()[&typeid(T)] = factory;
      return 0;
   }

/*Because of f*ck*ng MSVC++*/
//private:

#endif

   static map<string, _ObjectFactory*>& ObjectFactoryDictionary();
   static TypeMap<_ObjectFactory*>& TypeidDictionary();
   //static map<const type_info *, _ObjectFactory*>& TypeidDictionary();
};


#ifdef BROKEN_TEMPLATES /*Workaround for a compiler crash */

/**Registers the object name*/
template<class T>
static int ObjectaddObjectType(const string &objType, _ObjectFactory *factory)
{
   Object::ObjectFactoryDictionary()[objType] = factory;
   Object::TypeidDictionary()[&typeid(T)] = factory;
   return 0;
}

#endif


class _ObjectFactory {
   string typeName;
public:
   _ObjectFactory(const string &_name) : typeName(_name) {}
   virtual ~_ObjectFactory() {}
   virtual ObjectRef create() = 0;
   const string &getName() {return typeName;}
};

template <class T>
class ObjectFactory : public _ObjectFactory {
public:
   ObjectFactory(const string &_name) : _ObjectFactory(_name) {}
   virtual ObjectRef create() {return ObjectRef(new T);}
};



/* This used to be Object::GetClassName<T>() but it changed because of stupid MSVC++ bugs*/
template<class T>
string ObjectGetClassName()
{
   static TypeMap<_ObjectFactory*> &m = Object::TypeidDictionary();
   static TypeMap<_ObjectFactory*>::iterator found = m.find(&typeid(T));
   if (found != m.end())
      return found->second->getName();
   else
   {
      //throw GeneralException ("Object::GetClassName() failed, object type is not registered",
      //		      __FILE__, __LINE__);
      //static const string unknown("unknown");
      return "unknown";
   }
}


#define UNIQUE_STRING(line) dummy_init_for ## line


#ifndef BROKEN_TEMPLATES /*Workaround for a compiler crash */

#define DECLARE_TYPE2A(type, dummyID) static int UNIQUE_STRING(dummyID) = \
               Object::addObjectType<type > (# type, new ObjectFactory<type > (#type));

#define DECLARE_TYPE3A(str, type, dummyID) static int UNIQUE_STRING(dummyID) = \
               Object::addObjectType<type > (str, new ObjectFactory<type > (str));

#else

#define DECLARE_TYPE2A(type, dummyID) static int UNIQUE_STRING(dummyID) = \
               ObjectaddObjectType<type > (# type, new ObjectFactory<type > (#type));

#define DECLARE_TYPE3A(str, type, dummyID) static int UNIQUE_STRING(dummyID) = \
               ObjectaddObjectType<type > (str, new ObjectFactory<type > (str));

#endif /*BROKEN_TEMPLATES*/


#define DECLARE_TYPE(type) DECLARE_TYPE2A(type, __LINE__)
#define DECLARE_TYPE2(str, type) DECLARE_TYPE3A(str, type, __LINE__)


class NilObject : public Object {
public:
   virtual void printOn(ostream &out=cout) const
   {
      out << "<NilObject >";
   }

   /**Is it a nil Object*/
   virtual bool isNil() const {return true;}
};

extern ObjectRef nilObject;

#endif

Generated by: jmvalin@usw-pr-shell2 on Mon Jun 24 00:06:36 2002, using kdoc 2.0a40.