#ifndef Object_First #define Object_First #ifdef __GNUG__ #pragma interface #endif #include "Types.h" #include "ET_varargs.h" #include "Storage.h" #include "Stream.h" class Object; class Class; class Collection; class AccessMembers; class Iterator; class _Object_dummy; const int cIdNone = -1, cPartAnyChange = 27; typedef bool (*BoolFun)(Object*, Object*, void*); typedef Object* (*ObjPtrFun)(Object*, Object*, void*); typedef void (Object::*ObjMemberFunc)(...); typedef void (Object::*VoidObjMemberFunc)(...); typedef u_char (Object::*BoolObjMemberFunc)(...); extern int gDebug; //---- client flags ------------------------------------------------------------ enum ObjFlags { eObjIsDeleted = BIT(0), cObjIsShared = BIT(1), eObjDefault = 0, eObjLast = 1 }; //---- private flags, clients can only test but not set them ------------------- const int cObjNonDeleted = 0x01000000, cObjDelayChanges = 0x02000000, cObjVisited = 0x04000000, cObjIsProto = 0x08000000, cObjIsObserved = 0x10000000; const int cFlagMask= 0x00ffffff; //---- Object ------------------------------------------------------------------ class Object { friend Class; public: //---- automatically added by macro metaDef static Class *isa; friend IStream &operator>> (IStream&, Object*&); friend Class *_Type(Object*); Object(_Object_dummy*); virtual Class *IsA() const; virtual void Members(AccessMembers*); public: Object(int f= eObjDefault); virtual ~Object(); virtual void FreeAll(); //---- memory allocation inline void *operator new(size_t sz); inline void operator delete(void *vp); # define IsKindOf(name) IsA()->isKindOf(Meta(name)) //----- flag manipulation void SetFlag(int, bool); void SetFlag(int); void ResetFlag(int); bool TestFlag(int); void InvertFlag(int); //---- attributes const char *ClassName() const; void MarkAsDeleted(); bool IsDeleted(); void SetVisited(); void ClearVisited(); bool IsObserved(); bool IsShared(); void SetShared(); //---- comparing virtual u_long Hash(); virtual bool IsEqual(Object*); virtual int Compare(Object*); //---- converting, activation passivation virtual const char *AsString(); virtual OStream& PrintOn(OStream&); virtual IStream& ReadFrom(IStream&); virtual Object *ReadAndMap(IStream&); friend OStream &operator<< (OStream&, Object&); friend IStream &operator>> (IStream&, Object&); friend IStream &LoadPtr(IStream&, Object*&, Class *staticclass); friend OStream& operator<< (OStream&, Object*); //---- cloning Object* New(); virtual void InitNew(); virtual Object *Clone(); virtual Object *deepclone(); Object *DeepClone(); //---- change propagation void AddObserver(Object*); Object* RemoveObserver(Object*); virtual void Send(int id= cIdNone, int part= cPartAnyChange, void *vp= 0); virtual void DoObserve(int id, int part, void *vp, Object *op); void Changed(); Iterator *GetObserverIter(); void DelayChanges(); void FlushChanges(); virtual bool PrintOnWhenObserving(Object*); //---- error handling virtual void DoError(int level, const char *location, const char *fmt, va_list va); void Error(const char *method, const char *msgfmt, ...); void SysError(const char *method, const char *msgfmt, ...); void Warning(const char *method, const char *msgfmt, ...); void Fatal(const char *method, const char *msgfmt, ...); //---- fire walls void AbstractMethod(const char*); void MayNotUse(const char*); Object *guard(Class*); # define Guard(p,name) ((name*)(p)->guard(Meta(name))) //---- inspecting, debugging void Inspect(bool block= FALSE); void EditSource(bool declaration); virtual void InspectorId(char *buf, int bufSize); virtual void CollectParts(Collection*); void ScanMembers(u_long, ...); // direct (unchecked) access to instance variables; returns address of variable void* GetAddrOf(const char *varname, Class *&cl); protected: static int _an; static AccessMembers *_accessMembers; protected: //---- overridden if observers are stored in the object itself virtual Collection *MakeObserverColl(); virtual Collection *GetObservers(); virtual void DestroyObserverColl(); virtual void SetObserverColl(Collection *); void CleanupObservers(Collection *); private: Object(const Object&); private: u_int flags_; }; inline IStream &operator>> (IStream &s, Object *&op) { return ::LoadPtr(s, op, Object::isa); } inline Class *_Type(Object*) { return Object::isa; } inline void *Object::operator new(size_t sz) { return Storage::ObjectAlloc(sz); } inline void Object::operator delete(void *vp) { delete vp; } inline void Object::SetFlag(int f) { flags_|= f & cFlagMask; } inline void Object::ResetFlag(int f) { flags_&= ~(f & cFlagMask); } inline bool Object::TestFlag(int f) { return (bool) ((flags_ & f) != 0); } inline void Object::InvertFlag(int f) { flags_^= f & cFlagMask; } inline void Object::MarkAsDeleted() { SetFlag(eObjIsDeleted); } inline bool Object::IsDeleted() { return TestFlag(eObjIsDeleted); } inline void Object::SetVisited() { flags_|= cObjVisited; } inline void Object::ClearVisited() { flags_&= ~cObjVisited; } inline bool Object::IsObserved() { return TestFlag(cObjIsObserved); } inline bool Object::IsShared() { return TestFlag(cObjIsShared); } inline void Object::SetShared() { SetFlag(cObjIsShared); } inline OStream &operator<< (OStream &os, Object &op) { return op.PrintOn(os); } inline IStream &operator>> (IStream &is, Object &op) { return op.ReadFrom(is); } inline void Object::Changed() { if (TestFlag(cObjIsObserved)) Send(); } //---- DoDelayChanges ---------------------------------------------------------- // to delay the calls to Changed and ChangedWhat an instance of the class // DelayChanges can be declared // eg: Text::Cut() { DelayChanges dc(this); ... } class DoDelayChanges { Object *op; public: DoDelayChanges(Object *o) { op= o; op->DelayChanges(); } ~DoDelayChanges() { op->FlushChanges(); } void Use() { } }; //---- MetaDef macros ---------------------------------------------------------- #define Meta(name) name::isa #define SMeta(name) _NAME2_(__isa__,name) #define MetaDef(name) \ name(_Object_dummy*); \ static Class *isa; \ Class *IsA() const; \ friend char *_NAME2_(name,DeclFileName)(char *p_= __FILE__) \ { return p_; } \ friend int _NAME2_(name,DeclFileLine)(int i_= __LINE__) \ { return i_; } \ friend IStream &operator>> (IStream &s_, name *&op_) \ { return LoadPtr(s_, (Object*&)op_, Meta(name)); } \ void Members(AccessMembers*); \ friend Class *_Type(name*) \ { return Meta(name); } #endif