00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __LINK_INCLUDED
00020 #define __LINK_INCLUDED
00021
00022 #include <deque>
00023 #include <fstream>
00024 #include <list>
00025 #include <map>
00026 #include <string>
00027
00028 #include "common/defs.h"
00029 #include "common/global.h"
00030
00031 using namespace std;
00032
00033 class TDataPackageList;
00034 class TObjectID;
00035 class TLinkBase;
00036 class TLinkable;
00037 class TLinkUpdate;
00038
00039
00040
00041
00042
00043
00044
00054 ostream& operator<<( ostream& Stream, const TObjectID& ObjectID );
00055
00064 ostream& operator<<( ostream& Stream, const TLinkBase& Link );
00065
00066
00067
00068
00069
00070
00071
00098 class TObjectID
00099 {
00100 friend class TLinkUpdate;
00101
00102 public:
00104 static const int ID_SIZE = 6;
00105
00110 TObjectID();
00115 TObjectID( const TObjectID& Object );
00125 TObjectID( const byte* ByteArray, bool bTemp=false );
00136 TObjectID( const int* IntArray, bool bTemp=false );
00137
00143 bool isNull() const;
00147 bool isTemp() const;
00152 static int getIDSize();
00163 bool load( TDataPackageList* in, const string& sIdentifier, bool bUnique=true );
00169 TObjectID& operator=( const TObjectID& Object );
00175 TObjectID operator++();
00184 TObjectID operator++( int );
00192 bool operator==( const TObjectID& Object ) const;
00199 bool operator!=( const TObjectID& Object ) const;
00207 bool operator<( const TObjectID& Object ) const;
00221 bool save( TDataPackageList* out, const string& sIdentifier,
00222 bool bUnique=true, bool bAutoDelete=false ) const;
00229 void setID( const byte* ByteArray, bool bTemp=false );
00238 void setID( const int* IntArray, bool bTemp=false );
00243 void setNull();
00249 void setTemp( bool bTemp );
00255 void write( ostream& out ) const;
00256
00257 private:
00261 byte ObjectID[ID_SIZE];
00265 bool bTemp;
00266 };
00267
00268
00269
00270
00271
00272
00273
00323 class TLinkBase
00324 {
00325 friend class TLinkUpdate;
00326 friend class TLinkable;
00327
00328 public:
00332 enum {
00333 LINK_BASE = 0,
00334 LINK,
00335 DOUBLE_LINK
00336 };
00337
00341 TLinkBase();
00347 TLinkBase( TLinkable* p );
00353 TLinkBase( const TObjectID& DestID );
00358 TLinkBase( const TLinkBase& link );
00363 virtual ~TLinkBase();
00368 TLinkable* getDest() const;
00372 const TObjectID& getDestID() const;
00377 int2 getDestType() const;
00387 virtual int2 getType() const;
00392 const string& getDestTypeName() const;
00400 bool isNull() const;
00405 bool isUpdated() const;
00415 bool isValid() const;
00426 bool load( TDataPackageList* in, const string& sIdentifier, bool bUnique=true );
00433 TLinkBase& operator=( const TLinkBase& src );
00438 bool operator==( const TLinkBase& Two ) const;
00449 bool save( TDataPackageList* out, const string& sIdentifier,
00450 bool bUnique=true ) const;
00455 virtual void setDest( TLinkable* p );
00462 virtual void setNull();
00467 void Write( ostream& out ) const;
00468
00469 protected:
00474 bool bNeedUpdate;
00478 TLinkable* pDest;
00482 TObjectID DestID;
00486 static TObjectID NullID;
00493 void removeUpdateRequest();
00499 void requestUpdate();
00507 void reset();
00514 void setDest( const TObjectID& DestID );
00515 };
00516
00517
00518
00519
00520
00521
00522
00534 template<class X> class TLink : public TLinkBase
00535 {
00536 friend class TLinkUpdate;
00537
00538 public:
00539 TLink() : TLinkBase()
00540 {
00541 };
00542 TLink( const TObjectID& DestID ) : TLinkBase( DestID )
00543 {
00544 };
00545 TLink( X* p ) : TLinkBase( p )
00546 {
00547 };
00548 TLink( const TLink<X>& link ) : TLinkBase( link )
00549 {
00550
00551
00552 TLinkBase::operator=( link );
00553 }
00554
00561 operator X*() const
00562 {
00563 if ( getDest() == 0 ) {
00564 ELOG("TLink","operator X*") << "Link -> pointer conversion for null link :-(" << endl;
00565 }
00566 return getPointerToDest();
00567 }
00580 X* operator->() const
00581 {
00582 if ( getDest()== 0 ) {
00583 ELOG("TLink","operator->") << "Null pointer used for call :-(" << endl;
00584 }
00585 return getPointerToDest();
00586 }
00593 X* getPointerToDest() const
00594 {
00595 if ( TLinkBase::getDest() == 0 ) return 0;
00596 X* p = dynamic_cast<X*>(TLinkBase::getDest());
00597 if ( p == 0 )
00598 Fatal("TLink","GetPointerToDest", "TLink => TLinkable type mismatch or null pointer");
00599 return p;
00600 }
00605 virtual int2 getType() const
00606 {
00607 return TLinkBase::LINK;
00608 }
00613 void setDest( X* p )
00614 {
00615 TLinkBase::setDest( p );
00616 }
00620 virtual void setNull()
00621 {
00622 TLinkBase::setDest( (X*) 0 );
00623 }
00624
00625 private:
00632 virtual void setDest( TLinkable* ) { }
00633 };
00634
00635
00636
00637
00638
00639
00656 template<class X> class TDoubleLink : public TLink<X>
00657 {
00658 public:
00659 TDoubleLink() : TLink<X>()
00660 {
00661 setInverse( 0 );
00662 }
00663 TDoubleLink( TLinkable* src, X* dest ) : TLink<X>()
00664 {
00665 setDest( dest );
00666 setInverse( src );
00667 };
00668
00672 TLinkable* getInverse() const
00673 {
00674 return fInverse.getDest();
00675 }
00680 virtual int2 getType() const
00681 {
00682 return TLinkBase::DOUBLE_LINK;
00683 }
00689 void setInverse( TLinkable* src )
00690 {
00691 fInverse.setDest( src );
00692 }
00693
00694 private:
00695 TLinkBase fInverse;
00696 };
00697
00698
00699
00700
00701
00702
00703
00714 class TLinkBaseList : public list<TLinkBase*>
00715 {
00716 };
00717
00718
00719
00720
00721
00722
00723
00734 template<class X> class TLinkList : public list< TLink<X> >
00735 {
00736 };
00737
00738
00739
00740
00741
00742
00743
00754 class TType
00755 {
00756 public:
00757 enum
00758 {
00759 UNKNOWN = 0,
00760 LINKABLE,
00761 FLEET,
00762 SUBFLEET,
00763 GALAXY,
00764 SHIPDESIGN,
00765 ITEM,
00766 MINEFIELD,
00767 MINERAL_PACKAGE,
00768 MYSTERY_TRADER,
00769 PLANET,
00770 SYSTEM,
00771 ACTION
00772 };
00773
00777 virtual int2 getType() const;
00781 virtual const string& getTypeName() const;
00782 };
00783
00784
00785
00786
00787
00788
00789
00809 class TLinkable : public TType
00810 {
00811 friend class TLinkBase;
00812 friend class TLinkUpdate;
00813
00814 public:
00818 const TObjectID& getID() const;
00822 const TLinkBaseList& getLinkedByList() const;
00827 int4 getNumberOfLinks() const;
00831 virtual int2 getType() const;
00835 virtual const string& getTypeName() const;
00844 virtual bool load( TDataPackageList* in );
00853 virtual bool save( TDataPackageList* out ) const;
00854
00855 protected:
00860 TLinkable();
00866 virtual ~TLinkable();
00867
00872 virtual void reset();
00873
00874 private:
00878 static TObjectID UniqueID;
00882 TObjectID ID;
00886 TLinkBaseList LinkedBy;
00887
00894 TLinkable( const TLinkable& Src );
00895
00900 void addInverseLink( TLinkBase* p );
00906 TLinkable& operator=( const TLinkable& Src );
00911 void removeInverseLink( TLinkBase* p );
00912 };
00913
00914
00915
00916
00917
00918
00919
00936 class TLinkUpdate
00937 {
00938 public:
00942 ~TLinkUpdate();
00943
00949 bool checkConsistency();
00958 void commitUpdate( TLinkable* pNew, const TObjectID& OldID );
00964 void deleteUpdateRequest( const TLinkBase* pLink );
00968 static TLinkUpdate* instance();
00975 void requestUpdate( TLinkBase* pLink );
00980 void reset();
00981
00982 protected:
00988 TLinkUpdate();
00989
00990 private:
00992 static TLinkUpdate* fInstance;
00996 map<TObjectID, TLinkable*> fMap;
01000 TLinkBaseList fUpdateList;
01001
01002
01003 void showMap();
01004 void showUpdateList();
01005 };
01006
01007
01008
01009
01010
01011 #endif // __LINK_INCLUDED