// $Revision: 1.2 $ // Copyright (C) 1994, 1995 Taligent, Inc. All rights reserved. #ifndef TaligentSamples_ATOMICMODELIMP #define TaligentSamples_ATOMICMODELIMP #ifndef TaligentSamples_ATOMICMODEL #error "Don't include this file directly; use AtomicModel.h" #endif #ifndef HIDE_TEMPLATE_DEFINITIONS #define MAKE_MAtomicModelOn_DEFINITIONS_VISIBLE #define MAKE_MAtomicSelectionOn_DEFINITIONS_VISIBLE #define MAKE_TAtomicModelOn_DEFINITIONS_VISIBLE #define MAKE_TAtomicSelectionOn_DEFINITIONS_VISIBLE #endif #ifdef MAKE_MAtomicModelOn_DEFINITIONS_VISIBLE //============================================================================== // MAtomicModelOn TaligentTypeExtensionTemplateMacro_Abstract(MAtomicModelOn,AType); template MAtomicModelOn::MAtomicModelOn() { } template MAtomicModelOn::~MAtomicModelOn() { } template const MAtomicModelOn* MAtomicModelOn::LookupForReading(const TModelReference& reference) { MAtomicModelOn* atomicModel; ::DynamicCastTo(atomicModel, TModel::LookupForReading(reference)); if (atomicModel == NIL) { throw TCompoundDocumentException(TCompoundDocumentException::kModelDoesNotExist); } return atomicModel; } template MAtomicModelOn* MAtomicModelOn::LookupForWriting(const TModelReference& reference) { MAtomicModelOn* atomicModel; ::DynamicCastTo(atomicModel, TModel::LookupForWriting(reference)); if (atomicModel == NIL) { throw TCompoundDocumentException(TCompoundDocumentException::kModelDoesNotExist); } return atomicModel; } #endif #ifdef MAKE_MAtomicSelectionOn_DEFINITIONS_VISIBLE //============================================================================== // MAtomicSelectionOn TaligentTypeExtensionTemplateMacro_Abstract(MAtomicSelectionOn,AType); template MAtomicSelectionOn::MAtomicSelectionOn() { } template MAtomicSelectionOn::~MAtomicSelectionOn() { } template const AType* MAtomicSelectionOn::GetValueForReading() const { CheckValueSelected(); return GetAtomicModelOnForReading()->GetValueForReading(); } template AType* MAtomicSelectionOn::GetValueForWriting() { CheckValueSelected(); return GetAtomicModelOnForWriting()->GetValueForWriting(); } template void MAtomicSelectionOn::SetValue(const AType& value) { CheckValueSelected(); GetAtomicModelOnForWriting()->SetValue(value); } template AType* MAtomicSelectionOn::CopyValue() const { CheckValueSelected(); return GetAtomicModelOnForReading()->CopyValue(); } template void MAtomicSelectionOn::AdoptValue(AType* value) { CheckValueSelected(); GetAtomicModelOnForWriting()->AdoptValue(value); } template AType* MAtomicSelectionOn::SwapValue(AType* value) { CheckValueSelected(); return GetAtomicModelOnForWriting()->SwapValue(value); } template void MAtomicSelectionOn::SwapContents(MAtomicModelOn& other) { CheckValueSelected(); GetAtomicModelOnForWriting()->SwapContents(other); } template void MAtomicSelectionOn::CheckValueSelected() const { TModelSelection* thisAsSelection; ::DynamicCastTo(thisAsSelection, this); if (thisAsSelection->IsEmpty() || !thisAsSelection->IsDefined()) { throw TAtomicModelException(TAtomicModelException::kNoValueSelected); } } #endif #ifdef MAKE_TAtomicModelOn_DEFINITIONS_VISIBLE //============================================================================== // TAtomicModelOn TaligentTypeExtensionTemplateMacro(TAtomicModelOn,AType); // We can't make this public because it violates the rep invariant by having a NIL fValue. // And we can't set a value because we don't know what public constructors AType has // defined. template TAtomicModelOn::TAtomicModelOn() : fValue(NIL) { } template TAtomicModelOn::TAtomicModelOn(AType* adopt) : fValue(adopt) { Assertion(adopt != NIL, "TAtomicModelOn can't store NIL."); } template TAtomicModelOn::TAtomicModelOn(const AType& copy) : fValue(NIL) { fValue = ::Copy(copy); } template TAtomicModelOn::TAtomicModelOn(const TAtomicModelOn& other) : fValue(NIL) { fValue = ::CopyPointer(other.fValue); } template TAtomicModelOn::~TAtomicModelOn() { delete fValue; } template TAtomicModelOn& TAtomicModelOn::operator=(const TAtomicModelOn& other) { if (&other != this) { TModel::operator=(other); SetValue(*other.fValue); } return *this; } template TModelSelection* TAtomicModelOn::CreateSelection() const { TModelReference reference(*this); return new TAtomicSelectionOn(reference); } template MAtomicSelectionOn* TAtomicModelOn::CreateAtomicSelectionOn() const { TModelReference reference(*this); return new TAtomicSelectionOn(reference); } template HashResult TAtomicModelOn::ContentHash() const { return fValue->Hash(); } template bool TAtomicModelOn::IsContentEqual(const TModel& other) const { bool result = false; if (TModel::IsContentEqual(other)) { const TAtomicModelOn& otherModel = (const TAtomicModelOn&)other; result = *GetValueForReading() == *otherModel.GetValueForReading(); } return result; } template bool TAtomicModelOn::IsOrphanable() const { return false; } template const AType* TAtomicModelOn::GetValueForReading() const { return fValue; } template AType* TAtomicModelOn::GetValueForWriting() { return fValue; } template void TAtomicModelOn::SetValue(const AType& data) { AdoptValue(::Copy(data)); } template AType* TAtomicModelOn::CopyValue() const { return ::Copy(*fValue); } template void TAtomicModelOn::AdoptValue(AType* adopt) { AType* oldValue = SwapValue(adopt); delete oldValue; } template AType* TAtomicModelOn::SwapValue(AType* swap) { // It all comes down to this one routine. Assertion(swap != NIL, "TAtomicModelOn can't store NIL."); AType* oldValue = fValue; fValue = swap; NotifyValueChanged(); return oldValue; } template void TAtomicModelOn::SwapContents(MAtomicModelOn& other) { // This routine swaps the contents of the two AtomicValueOn objects // without creating an extra temporary copy. if (&other != this) { if (other.GetValueForReading() == NIL) { throw TAtomicModelException(TAtomicModelException::kCannotStoreNIL); } fValue = other.SwapValue(fValue); if (fValue == NIL) { // We've been messed up by the other model throw TAtomicModelException(TAtomicModelException::kCannotStoreNIL); } } } template void TAtomicModelOn::NotifyValueChanged() { // Notify interested clients that the data has changed. This model // is asked to create the notification interest so that only clients for this // change on this model are notified. TModelInterest interest = GetSelectedContentsReplacedInterest(); TModelSelection* selection = CreateSelection(); TSelectionNotification notification(interest, *selection); delete selection; NotifyOfChange(notification); } template TStream& TAtomicModelOn::operator>>=(TStream& toStream) const { ::WriteVersion(toStream, kOriginalVersion); TModel::operator>>=(toStream); ::Flatten(fValue, toStream); return toStream; } template TStream& TAtomicModelOn::operator<<=(TStream& fromStream) { ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); TModel::operator<<=(fromStream); AType* data; ::Resurrect(data, fromStream); delete fValue; fValue = data; return fromStream; } template const TAtomicModelOn* TAtomicModelOn::LookupForReading(const TModelReference& reference) { const TAtomicModelOn* atomicModel; ::DynamicCastTo(atomicModel, TModel::LookupForReading(reference)); if (atomicModel == NIL) { throw TCompoundDocumentException(TCompoundDocumentException::kModelDoesNotExist); } return atomicModel; } template TAtomicModelOn* TAtomicModelOn::LookupForWriting(const TModelReference& reference) { TAtomicModelOn* atomicModel; ::DynamicCastTo(atomicModel, TModel::LookupForWriting(reference)); if (atomicModel == NIL) { throw TCompoundDocumentException(TCompoundDocumentException::kModelDoesNotExist); } return atomicModel; } #endif #ifdef MAKE_TAtomicSelectionOn_DEFINITIONS_VISIBLE //============================================================================== // TAtomicSelectionOn TaligentTypeExtensionTemplateMacro(TAtomicSelectionOn,AType); template const MAtomicModelOn* TAtomicSelectionOn::GetAtomicModelOnForReading() const { return (const TAtomicModelOn*)GetModelForReading(); } template MAtomicModelOn* TAtomicSelectionOn::GetAtomicModelOnForWriting() { return (TAtomicModelOn*)GetModelForWriting(); } template TModel* TAtomicSelectionOn::HandleCopyData(const TTypeDescription&) const { AType* value = GetAtomicModelOnForReading()->CopyValue(); return new TAtomicModelOn(value); } template void TAtomicSelectionOn::HandleCopyDataInto(TModel& model) const { TAtomicModelOn& otherModel = (TAtomicModelOn&)model; const AType* ourValue = GetAtomicModelOnForReading()->GetValueForReading(); otherModel.SetValue(*ourValue); } template TModel* TAtomicSelectionOn::HandleReplaceData(TModel* adoptedNewModelArg) { TAtomicModelOn* theNewModel = (TAtomicModelOn*)adoptedNewModelArg; MAtomicModelOn* ourModel = GetAtomicModelOnForWriting(); ourModel->SwapContents(*theNewModel); return theNewModel; } template TModel* TAtomicSelectionOn::HandleOrphanData() { // This kind of model does not allow orphaning data throw TAtomicModelException(TAtomicModelException::kCannotOrphanData); return NIL; } template TAtomicSelectionOn::TAtomicSelectionOn(const TModelReference& model) : TModelSelection(model), MDataExchanger(this), MAtomicSelectionOn() { } template TAtomicSelectionOn::TAtomicSelectionOn(const TAtomicSelectionOn& other) : TModelSelection(other), MDataExchanger(this), MAtomicSelectionOn(other) { } template TAtomicSelectionOn::~TAtomicSelectionOn() { } template TAtomicSelectionOn::TAtomicSelectionOn() : TModelSelection(), MDataExchanger(this), MAtomicSelectionOn() { } template TAtomicSelectionOn& TAtomicSelectionOn::operator=(const TAtomicSelectionOn& source) { if (&source != this) { TModelSelection::operator=(source); } return *this; } #endif #endif