// $Revision: 1.3 $ // Copyright (C) 1994, 1995 Taligent, Inc. All rights reserved. // TilesModel.C #ifndef TaligentSample_TILESMODEL #include "TilesModel.h" #endif #ifndef TaligentSample_TILESSELECTIONS #include "TilesSelections.h" #endif // This macro call matches a macro call to TaligentTypeExtensionDeclarationsMacro // in the TTile class declaration. This macro defines the // TaligentTypeExtension utility functions. kOriginal version is the version // level of the Tile. TaligentTypeExtensionMacro(TTile); // A default (empty) constructor required by Taligent Type Extensions. A constructor // with parameters that all have defaults is not the same as an empty constructor. TTile::TTile () : fType(kRock), fColor(TRGBColor(1,0,0)), fBounds(TGPoint::kOrigin, TGPoint::kOrigin) {} TTile::TTile (EType type, TRGBColor color, TGPoint position, TGPoint size) : fType(type), fColor(color) { // The TGRect fBounds stores both position and size. fBounds.Set(position, position+size); } TTile::TTile (const TTile& copy) : fType(copy.fType), fColor(copy.fColor), fBounds(copy.fBounds) {} TTile::~TTile () {} // Stream out operator -- required by Taligent Type Extensions TStream& TTile::operator>>=(TStream& toStream) const { // Place the version number onto the stream ::WriteVersion(toStream, kOriginalVersion); // Stream out the TTile data. (short) fType >>= toStream; fColor >>= toStream; fBounds >>= toStream; return toStream; } // Stream in operator -- required by Taligent Type Extensions TStream& TTile::operator<<=(TStream& fromStream) { // Read in the version VersionInfo version = ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); switch (version) { case kOriginalVersion: { short type; type <<= fromStream; fType = (EType) type; fColor <<= fromStream; fBounds <<= fromStream; break; } // New versions would be added here to support changes in the TTile default: throw TInvalidVersionError(); } return fromStream; } TTile::EType TTile::GetType() const { return fType; } void TTile::SetType(EType type) { fType = type; } TRGBColor TTile::GetColor() const { return fColor; } void TTile::SetColor(TRGBColor color) { fColor = color; } // The TGRect fBounds stores both position and size. TGPoint TTile::GetPosition () const { return fBounds.GetTopLeft(); } void TTile::SetPosition (const TGPoint& point) { fBounds.Set(point, point+fBounds.GetSize()); } TGPoint TTile::GetSize () const { return fBounds.GetSize(); } void TTile::SetSize (const TGPoint& size) { TGPoint position = fBounds.GetTopLeft(); fBounds.Set(position, position+size); } bool TTile::ContainsPoint (const TGPoint& point) const { return fBounds.Contains(point); } TTile& TTile::operator=(const TTile& rhs) { // Always check for assignment to self. if (this != &rhs) { fType = rhs.fType; fColor = rhs.fColor; fBounds = rhs.fBounds; } return *this; } // This macro call matches the ModelDeclarationsMacro in the TTilesModel // class declaration. This macro defines the Taligent Type Extensions and DynamicCast // utility functions. Use ModelDefinitionsMacroTwo if there are two base classes, etc. // kOriginalVersion is used to "version stamp" this edition of TTilesModel and // should be incremented for newer versions if the data stream changes. ModelDefinitionsMacroOne(TTilesModel, kVersionTwo, TGUIEmbedderModel); // Default constructor -- required by Taligent Type Extensions TTilesModel::TTilesModel() // fTiles is constructed with a comparator and a streamer. A TMCollectibleComparator // allows two MCollectible objects of type T to be compared for equality. A // TMonomorphicStreamer allows only objects of type T to be streamed out and will not // handle objects derived from type T. The array is initialized to size 0. : TGUIEmbedderModel(), fTiles( 0, new TMonomorphicStreamer, 0) { fTiles.SetAutoGrowFlag(true); } // Copy constructor -- required by Taligent Type Extensions TTilesModel::TTilesModel(const TTilesModel& other) : TGUIEmbedderModel(other), fTiles( 0, new TMonomorphicStreamer, 0) { // Copying TArrayOf only copies the pointers. In order to copy // the elements, each element must be copied individually for (int i = 0; i < other.fTiles.Count(); i++) { AdoptTile(new TTile(*other.fTiles.At(i))); } } // Destructor TTilesModel::~TTilesModel() { fTiles.DeleteAll(); } // Stream out operator -- required by Taligent Type Extensions TStream& TTilesModel::operator>>=(TStream& toStream) const { // Place the version number onto the stream ::WriteVersion(toStream, kVersionTwo); // Stream out base class portion TGUIEmbedderModel::operator>>=(toStream); // Now stream out the array. fTiles >>= toStream; return toStream; } // Stream in operator -- required by Taligent Type Extensions TStream& TTilesModel::operator<<=(TStream& fromStream) { // Read in the version VersionInfo version = ::ReadVersion(fromStream, kOriginalVersion, kVersionTwo); switch (version) { // kOriginalVersion is the version where the model is derived from TModel. case kOriginalVersion: { // Stream in the base class portion TModel::operator<<=(fromStream); // Clear out array. fTiles.DeleteAll(); // Stream in the array fTiles <<= fromStream; break; } // kVersionTwo is the version where the model is derived from TGUIEmbedderModel. case kVersionTwo: { // Stream in the base class portion TGUIEmbedderModel::operator<<=(fromStream); // Clear out array. fTiles.DeleteAll(); // Stream in the array fTiles <<= fromStream; break; } default: throw TInvalidVersionError(); } return fromStream; } // Return a new, default selection on the model. TModelSelection* TTilesModel::CreateSelection() const { TTilesSelection* selection = new TTilesSelection(TModelReference(*this)); selection->SelectDefault(); return selection; } // Get... functions should be const TileIndex TTilesModel::GetNumTiles() const { return fTiles.Count(); } // Get a non-const pointer to a tile. Model should be locked // for reading or writing when this function is called and as long // as the pointer is used. TTile* TTilesModel::GetTileForWriting (TileIndex whichTile) { // cast away const return (TTile*) GetTileForReading (whichTile); } // Get a const pointer to a tile. Model should be locked for reading // when this function is called and as long as the pointer is used. const TTile* TTilesModel::GetTileForReading (TileIndex whichTile) const { const TTile* tile=0; if (whichTile >= 0 && whichTile < fTiles.Count()) { tile = fTiles.At(whichTile); } else { // throw an exception? ::qprintf("TTilesModel::GetTileForWriting: Illegal tile chosen from model"); } return tile; } // Adopt a TTile into the model. Responsibility for the TTile is taken from the // caller and the TileIndex is returned to the caller by which the caller can get // back to the TTile. The Taligent convention of calling the function AdoptSomething, // passing a pointer, and naming it adoptSomething is followed. TileIndex TTilesModel::AdoptTile (TTile* tileToAdopt) { TileIndex index = -1; if (tileToAdopt != 0) { index = fTiles.Count(); fTiles.AtPut(index, tileToAdopt); } return index; } // Orphan a TTile from the model. Return a pointer to the TTile for which the // caller now has responsibility. The Taligent convention of calling the function // OrphanSomething and returning a pointer is followed. TTile* TTilesModel::OrphanTile (TileIndex index) { TTile* tile = fTiles.At(index); fTiles.Compress(index, 1); return tile; }