Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members

FXObject.h

Go to the documentation of this file.
00001 /********************************************************************************
00002 *                                                                               *
00003 *                         T o p l e v el   O b j e c t                          *
00004 *                                                                               *
00005 *********************************************************************************
00006 * Copyright (C) 1997,2010 by Jeroen van der Zijp.   All Rights Reserved.        *
00007 *********************************************************************************
00008 * This library is free software; you can redistribute it and/or modify          *
00009 * it under the terms of the GNU Lesser General Public License as published by   *
00010 * the Free Software Foundation; either version 3 of the License, or             *
00011 * (at your option) any later version.                                           *
00012 *                                                                               *
00013 * This library 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 Lesser General Public License for more details.                           *
00017 *                                                                               *
00018 * You should have received a copy of the GNU Lesser General Public License      *
00019 * along with this program.  If not, see <http://www.gnu.org/licenses/>          *
00020 ********************************************************************************/
00021 #ifndef FXOBJECT_H
00022 #define FXOBJECT_H
00023 
00024 
00025 namespace FX {
00026 
00027 /// Minimum and maximum message id
00028 enum {
00029   MINKEY = 0,
00030   MAXKEY = 65535
00031   };
00032 
00033 
00034 /// Minimum and maximum message type
00035 enum {
00036   MINTYPE = 0,
00037   MAXTYPE = 65535
00038   };
00039 
00040 
00041 /// Association key
00042 typedef FXuint FXSelector;
00043 
00044 
00045 /// Describes a FOX object
00046 class FXAPI FXMetaClass {
00047 private:
00048   const FXchar              *className;
00049   FXObject*                (*manufacture)();
00050   const FXMetaClass         *baseClass;
00051   const void                *assoc;
00052   FXuint                     nassocs;
00053   FXuint                     assocsz;
00054 private:
00055   static const FXMetaClass **metaClassTable;
00056   static FXuint              nmetaClassTable;
00057   static FXuint              nmetaClasses;
00058 private:
00059   static void resize(FXuint n);
00060 public:
00061   FXMetaClass(const FXchar* name,FXObject *(fac)(),const FXMetaClass* base,const void* ass,FXuint nass,FXuint assz);
00062 
00063   /// Check if metaclass is subclass of some other metaclass
00064   FXbool isSubClassOf(const FXMetaClass* metaclass) const;
00065 
00066   /// Make instance of some object
00067   FXObject* makeInstance() const;
00068 
00069   /// Ask class name
00070   const FXchar* getClassName() const { return className; }
00071 
00072   /// Ask base class
00073   const FXMetaClass* getBaseClass() const { return baseClass; }
00074 
00075   /// Find metaclass object
00076   static const FXMetaClass* getMetaClassFromName(const FXchar* name);
00077 
00078   /// Search message map
00079   const void* search(FXSelector key) const;
00080 
00081  ~FXMetaClass();
00082   };
00083 
00084 
00085 /// Macro to set up class declaration
00086 #define FXDECLARE(classname) \
00087   public: \
00088    struct FXMapEntry { FX::FXSelector keylo; FX::FXSelector keyhi; long (classname::* func)(FX::FXObject*,FX::FXSelector,void*); }; \
00089    static const FX::FXMetaClass metaClass; \
00090    static FX::FXObject* manufacture(); \
00091    virtual long handle(FX::FXObject* sender,FX::FXSelector sel,void* ptr); \
00092    virtual const FX::FXMetaClass* getMetaClass() const { return &metaClass; } \
00093    friend FX::FXStream& operator<<(FX::FXStream& store,const classname* obj){return store.saveObject((const FX::FXObject*)(obj));} \
00094    friend FX::FXStream& operator>>(FX::FXStream& store,classname*& obj){return store.loadObject((FX::FXObject*&)(obj));} \
00095   private:
00096 
00097 
00098 /// Macro to set up class implementation
00099 #define FXIMPLEMENT(classname,baseclassname,mapping,nmappings) \
00100   FX::FXObject* classname::manufacture(){return new classname;} \
00101   const FX::FXMetaClass classname::metaClass(#classname,classname::manufacture,&baseclassname::metaClass,mapping,nmappings,sizeof(classname::FXMapEntry)); \
00102   long classname::handle(FX::FXObject* sender,FX::FXSelector sel,void* ptr){ \
00103     const FXMapEntry* me=(const FXMapEntry*)metaClass.search(sel); \
00104     return me ? (this->* me->func)(sender,sel,ptr) : baseclassname::handle(sender,sel,ptr); \
00105     }
00106 
00107 
00108 /// Macro to set up abstract class declaration
00109 #define FXDECLARE_ABSTRACT(classname) \
00110   public: \
00111    struct FXMapEntry { FX::FXSelector keylo; FX::FXSelector keyhi; long (classname::* func)(FX::FXObject*,FX::FXSelector,void*); }; \
00112    static const FX::FXMetaClass metaClass; \
00113    virtual long handle(FX::FXObject* sender,FX::FXSelector sel,void* ptr); \
00114    virtual const FX::FXMetaClass* getMetaClass() const { return &metaClass; } \
00115    friend FX::FXStream& operator<<(FX::FXStream& store,const classname* obj){return store.saveObject((const FX::FXObject*)(obj));} \
00116    friend FX::FXStream& operator>>(FX::FXStream& store,classname*& obj){return store.loadObject((FX::FXObject*&)(obj));} \
00117   private:
00118 
00119 
00120 /// Macro to set up abstract class implementation
00121 #define FXIMPLEMENT_ABSTRACT(classname,baseclassname,mapping,nmappings) \
00122   const FX::FXMetaClass classname::metaClass(#classname,NULL,&baseclassname::metaClass,mapping,nmappings,sizeof(classname::FXMapEntry)); \
00123   long classname::handle(FX::FXObject* sender,FX::FXSelector sel,void* ptr){ \
00124     const FXMapEntry* me=(const FXMapEntry*)metaClass.search(sel); \
00125     return me ? (this->* me->func)(sender,sel,ptr) : baseclassname::handle(sender,sel,ptr); \
00126     }
00127 
00128 
00129 /// MetaClass of a class
00130 #define FXMETACLASS(classname) (&classname::metaClass)
00131 
00132 
00133 /// Set up map type
00134 #define FXDEFMAP(classname) static const classname::FXMapEntry
00135 
00136 /// Define range of function types
00137 #define FXMAPTYPES(typelo,typehi,func) {FXSEL(typelo,FX::MINKEY),FXSEL(typehi,FX::MAXKEY),&func}
00138 
00139 /// Define range of function types
00140 #define FXMAPTYPE(type,func) {FXSEL(type,FX::MINKEY),FXSEL(type,FX::MAXKEY),&func}
00141 
00142 /// Define range of functions
00143 #define FXMAPFUNCS(type,keylo,keyhi,func) {FXSEL(type,keylo),FXSEL(type,keyhi),&func}
00144 
00145 /// Define one function
00146 #define FXMAPFUNC(type,key,func) {FXSEL(type,key),FXSEL(type,key),&func}
00147 
00148 
00149 /**
00150 * Object is the base class for all objects in FOX; in order to receive
00151 * messages from the user interface, your class must derive from Object.
00152 * The Object class also provides serialization facilities, with which
00153 * you can save and restore the object's state.  If you've subclassed
00154 * from Object, you can save your subclasses' state by overloading the
00155 * save() and load() functions and use the stream API to serialize its
00156 * member data.
00157 */
00158 class FXAPI FXObject {
00159   FXDECLARE(FXObject)
00160 public:
00161 
00162   /// Called for unhandled messages
00163   virtual long onDefault(FXObject*,FXSelector,void*);
00164 
00165 public:
00166 
00167   /// Get class name of some object
00168   const FXchar* getClassName() const;
00169 
00170   /// Check if object is member of metaclass
00171   FXbool isMemberOf(const FXMetaClass* metaclass) const;
00172 
00173   /// Try handle message safely, catching certain exceptions
00174   virtual long tryHandle(FXObject* sender,FXSelector sel,void* ptr);
00175 
00176   /// Save object to stream
00177   virtual void save(FXStream& store) const;
00178 
00179   /// Load object from stream
00180   virtual void load(FXStream& store);
00181 
00182   /// Virtual destructor
00183   virtual ~FXObject();
00184   };
00185 
00186 }
00187 
00188 #endif

Copyright © 1997-2010 Jeroen van der Zijp