uobject.hpp

00001 /* ==================================================== ======== ======= *
00002 *
00003 *  uobject.hpp
00004 *  Ubit Project
00005 *  Part of the Ubit Toolkit: A Brick Construction Game Model for Creating GUIs
00006 *  (C) 1999-2006 EricLecolinet / ENST Paris / http://www.enst.fr/~elc/ubit
00007 *
00008 * ***********************************************************************
00009 * COPYRIGHT NOTICE : 
00010 * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY AND WITHOUT EVEN THE 
00011 * IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 
00012 * YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF THE GNU 
00013 * GENERAL PUBLIC LICENSE AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION; 
00014 * EITHER VERSION 2 OF THE LICENSE, OR (AT YOUR OPTION) ANY LATER VERSION.
00015 * SEE FILES 'COPYRIGHT' AND 'COPYING' FOR MORE DETAILS.
00016 * ***********************************************************************
00017 * ==================================================== [(c)Elc] ======= *
00018 * ==================================================== ======== ======= */
00019 
00020 #ifndef _uobject_hpp_
00021 #define _uobject_hpp_
00022 //pragma ident  "@(#)uobject.hpp        ubit:05.05.00"
00023 #include <ubit/udefs.hpp>
00024 namespace ubit {
00025 
00030 class UObject {
00031 public:
00032   static const char* getVersion();
00034 
00035   const char* getTypeName() const;
00042   virtual const UStr& getClassName() const;
00050   virtual const UClass& getClass() const {return classid();}
00051   /* virtual function that returns the Ubit Class of this object (see details!).
00052     * this function MUST be redefined by ALL UObject subclassses. This can be done
00053     * by inserting one of the UCLASS, UELEMENT_CLASS or UATTRIBUTE_CLASS macros
00054     * in the class declaration (see examples in UObject subclasses)
00055     * @see: classid(), UClass.
00056     */
00057   
00058   static const UClass& classid();
00059   /* static function that returns the UClass of this class (see details!).
00060     * this function MUST be redefined by ALL UObject subclassses. This can be done
00061     * by inserting one of the UCLASS, UELEMENT_CLASS or UATTRIBUTE_CLASS macros
00062     * in the class declaration (see examples in UObject subclasses)    
00063     * @see: getClass(), UClass.
00064     */
00065   
00066   virtual UBrick* brickCast()  {return null;}
00067   virtual UProp*  propCast()   {return null;}
00068   virtual UData*  dataCast()   {return null;}
00069   virtual UStr*   strCast()    {return null;}
00070   virtual UCall*  callCast()   {return null;}
00071   virtual UGroup* groupCast()  {return null;}
00072   virtual UBox*   boxCast()    {return null;}
00073   virtual UWin*   winCast()    {return null;}
00074   virtual UMenu* menuCast()    {return null;}
00076   
00077   void addPtr() const {++ptrcount;}
00078   
00079   void removePtr() const;
00080   
00081   int getPtrCount() const {return ptrcount;}  
00082 
00083   virtual bool canPtrDelete() const;   // MUST be virtual!
00085 
00086   static void deferenceError(const void*);
00087 
00088   UObject() {ptrcount = 0;}  
00089 
00090   UObject(const UObject&) {ptrcount = 0;}  
00091 
00092   UObject& operator=(const UBrick&) {ptrcount = 0; return *this;} 
00093 
00094   virtual ~UObject() {ptrcount = -1;}
00095   //NB: prtrcount<0 means that the object has been destructed
00096 
00097 private:
00098   friend class UBrick;
00099   mutable int ptrcount;      
00100 };
00101 
00102 /* ==================================================== [Elc] ======= */
00103 /* ==================================================== ===== ======= */
00104 /* uptr<> template : Ubit Smart Pointer.
00105 *
00106 * Smart Pointers make it possible to handle objects created in the heap
00107 * in a safe way. An object pointed by a uptr<> :
00108 *  - is NOT destroyed when its parents are destroyed (if this object can have parents)
00109 *  - is AUTOMATICALLY destroyed when the last uptr to this object is removed
00110 *  - CAN'T be destroyed by using the 'delete' primitive ('delete' is dangerous
00111  *    because other pointers may reference the deleted object; hence methods
00112  *    such as UGroup::remove() should be uesed instead of 'delete')
00113 *
00114 *  @see: UBrick.
00115 *
00116 * Example:
00117 *  <pre><tt>
00118 *    uptr<UStr> p1 = new UStr("111");
00119 *    uptr<UStr> p2 = ustr("222");
00120 *
00121 *    *p1 = *p2;        // copies the *content* of p2 into p1 (but p1
00122 *                      // (and p2 still point to different objects)
00123 *
00124 *    p1 = p2;          // p1 now points to the same object as p2
00125 *                      // the object that was formerly pointed by p1 is deleted
00126 *                      // as there is no other reference to it
00127 *
00128 *    p1->append("xyz") // the content of the object pointed by p1 is changed
00129 *
00130 *    cerr << *p1;      // writes the content of the object: 222xyz
00131 *    cerr << &p1;      // writes the address of the object
00132 *
00133 *    p1 = null;        // p1 now points to null. the object that 
00134 *                      // was pointed by p1 is deleted
00135 * </tt></pre>
00136 */
00137 template <class CC> class uptr {
00138 public:
00139   uptr()         {obj = null;}
00140   uptr(CC& _obj) {obj = &_obj; obj->addPtr();}
00141   uptr(CC* _obj) {obj = _obj; if(obj) obj->addPtr();}
00143   
00144   uptr(const uptr<CC>& ref2) {obj = ref2.obj; if(obj) obj->addPtr();}
00146   
00147   ~uptr() {if (obj) obj->removePtr();}
00149   
00150   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00151   
00152   uptr<CC>& operator=(CC& _obj) {
00153     if(obj) obj->removePtr(); obj = &_obj; if(obj) obj->addPtr(); return *this;
00154   }
00155   uptr<CC>& operator=(CC* _obj) {
00156     if(obj) obj->removePtr(); obj = _obj; if(obj) obj->addPtr(); return *this;
00157   }
00159   
00160   uptr<CC>& operator=(const uptr<CC>& p2) {
00161     if(obj) obj->removePtr(); obj = p2.obj; if(obj) obj->addPtr(); return *this;
00162   }
00164   
00165   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00166   
00167   operator CC*() const {return obj;}
00169   
00170   CC* operator&() const {return obj;}
00172   
00173   CC& operator*() const {
00174     if (!obj) UObject::deferenceError(this);
00175     return *obj;
00176   }
00178   
00179   CC* operator->() const {
00180     if (!obj) UObject::deferenceError(this);
00181     return obj;
00182   }
00184   
00185 private:
00186   CC* obj;
00187   CC& operator[](int);  // [] meaningless and forbidden.
00188 };
00189 
00190 
00191 }
00192 #endif
00193 /* ==================================================== [TheEnd] ======= */
00194 /* ==================================================== [(c)Elc] ======= */
00195 

Generated on Mon Jan 29 00:20:39 2007 for Ubit by  doxygen 1.4.7