home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Tools - Objects / MacApp / MacApp 3.0a2 / Libraries / UObject.cp < prev    next >
Encoding:
Text File  |  1991-05-01  |  13.7 KB  |  571 lines  |  [TEXT/MPS ]

  1. /* UObject.cp */
  2. /* Copyright © 1984-1991 by Apple Computer, Inc.  All rights reserved. */
  3.  
  4. #ifndef __UOBJECT__
  5. #include "UObject.h"
  6. #endif
  7.  
  8. #ifndef __STDIO__
  9. #include "StdIo.h"
  10. #endif
  11.  
  12. #ifndef __UDEPENDENCIES__
  13. #include "UDependencies.h"
  14. #endif
  15.  
  16. #ifndef __USTREAM__
  17. #include "UStream.h"
  18. #endif
  19.  
  20. // StripLong etc.
  21. #ifndef __UMACAPPUTILITIES__
  22. #include "UMacAppUtilities.h"
  23. #endif
  24.  
  25. // SetPermHandleSize, etc.
  26. #ifndef __UMEMORY__
  27. #include "UMemory.h"
  28. #endif
  29.  
  30. #ifndef __UFAILURE__
  31. #include "UFailure.h"
  32. #endif
  33.  
  34. #if qDebug
  35. #ifndef __UDEBUG__
  36. #include "UDebug.h"
  37. #endif
  38. #endif
  39.  
  40. #if qInspector
  41. #ifndef __UINSPECTOR__
  42. #include "UInspector.h"
  43. #endif
  44. #endif
  45.  
  46. #ifndef qMacApp
  47. #define qMacApp False
  48. #endif
  49.  
  50.  
  51. // • Move the following to UObject.h when I get it generated.
  52.  
  53. typedef pascal void(* DoToSubClassType)(ObjClassID theClass,
  54.                                         void* localScope);
  55. typedef pascal void(* DoToSuperClassType)(ObjClassID theClass,
  56.                                           void* localScope);
  57.  
  58. //!!! Also Defined in UList
  59. typedef pascal void(* DoToObjectType)(TObject* item,
  60.                                       void* staticLink);
  61.  
  62. //--------------------------------------------------------------------------------------------------
  63. #pragma segment MAObjectRes
  64.  
  65. pascal void TObject::Changed(ChangeID theChange,
  66.                              TObject* changedBy)
  67. {
  68.     this->MarkDependents(true);
  69.     this->UpdateDependents(theChange, this, changedBy);
  70.     this->MarkDependents(false);
  71. }
  72.  
  73. //--------------------------------------------------------------------------------------------------
  74. #pragma segment MAObjectRes
  75.  
  76. pascal void TObject::DoUpdate(ChangeID& theChange,
  77.                               TObject* changedObject,
  78.                               TObject* changedBy)
  79.  
  80. {
  81. }
  82.  
  83. //--------------------------------------------------------------------------------------------------
  84. #pragma segment MAObjectRes
  85.  
  86. pascal void TObject::AddDependent(TObject* dependent)
  87.  
  88. {
  89.     AddDependentOf(this, dependent, kNoLabel);
  90. }
  91.  
  92. //--------------------------------------------------------------------------------------------------
  93. #pragma segment MAObjectRes
  94.  
  95. pascal void TObject::RemoveDependent(TObject* dependent)
  96.  
  97. {
  98.     RemoveDependentOf(this, dependent, kNoLabel);
  99. }
  100.  
  101. //--------------------------------------------------------------------------------------------------
  102. #pragma segment MAObjectRes
  103.  
  104. pascal void TObject::RemoveAllDependencies(void)
  105.  
  106. {
  107.     RemoveDependencies(this);                    // Call the routine in UDependencies 
  108. }
  109.  
  110. //--------------------------------------------------------------------------------------------------
  111. #pragma segment MAObjectRes
  112.  
  113. pascal void TObject::EachDependent(DoToObjectType DoToDependent,
  114.                                    void* staticLink)
  115. {
  116.     EachDependentOf(this, DoToDependent, staticLink);
  117. }
  118.  
  119. //--------------------------------------------------------------------------------------------------
  120. #pragma segment MAObjectRes
  121.  
  122. pascal void TObject::EachNotifier(DoToObjectType DoToNotifier,
  123.                                   void* staticLink)
  124. {
  125.     EachNotifierOf(this, DoToNotifier, staticLink);
  126. }
  127.  
  128. //--------------------------------------------------------------------------------------------------
  129. #pragma segment MAObjectRes
  130.  
  131. pascal void TObject::HandleUpdate(ChangeID theChange,
  132.                                   TObject* changedObject,
  133.                                   TObject* changedBy)
  134. {
  135.     if (this->IsMarked())
  136.     {
  137.         this->SetMark(false);
  138.         this->UpdateNotifiers(theChange, changedObject, changedBy);
  139.         this->DoUpdate(theChange, changedObject, changedBy);
  140.         if (theChange != kNoChange)
  141.             this->UpdateDependents(theChange, changedObject, changedBy);
  142.     }
  143. }
  144.  
  145. //--------------------------------------------------------------------------------------------------
  146. #pragma segment MAObjectRes
  147.  
  148. pascal Boolean TObject::IsMarked(void)
  149. {
  150.     return IsObjectMarked(this);
  151. }
  152.  
  153. //--------------------------------------------------------------------------------------------------
  154. #pragma segment MAObjectRes
  155.  
  156. pascal void TObject::MarkRecursively(Boolean state)
  157. {
  158.     if (state != this->IsMarked())
  159.     {
  160.         this->SetMark(state);
  161.         this->MarkDependents(state);
  162.     }
  163. }
  164.  
  165. //--------------------------------------------------------------------------------------------------
  166. #pragma segment MAObjectRes
  167.  
  168. class CMarkDependent
  169. {
  170.     Boolean fState;
  171. public:
  172.     CMarkDependent(Boolean state) :
  173.         fState(state)
  174.     {
  175.     }
  176.  
  177.     pascal void MarkDependent(TObject* aDependent);
  178. };
  179.  
  180. #pragma segment MAObjectRes
  181. pascal void CMarkDependent::MarkDependent(TObject* aDependent)
  182. {
  183.     aDependent->MarkRecursively(fState);
  184. }
  185.  
  186. #pragma segment MAObjectRes
  187. pascal void TObject::MarkDependents(Boolean state)
  188. {
  189.     CMarkDependent scopeLink(state);
  190.     this->EachDependent((DoToObjectType) & CMarkDependent::MarkDependent, &scopeLink);
  191. }
  192.  
  193. //--------------------------------------------------------------------------------------------------
  194. #pragma segment MAObjectRes
  195.  
  196. pascal void TObject::SetMark(Boolean state)
  197. {
  198.     MarkObject(this, state);
  199. }
  200.  
  201. //--------------------------------------------------------------------------------------------------
  202. #pragma segment MAObjectRes
  203.  
  204. class CUpdateDependent
  205. {
  206.     ChangeID& fChange;
  207.     TObject* fChangedObject;
  208.     TObject* fChangedBy;
  209. public:
  210.     CUpdateDependent(ChangeID& theChange,
  211.                      TObject* changedObject,
  212.                      TObject* changedBy) :
  213.         fChange(theChange),
  214.         fChangedObject(changedObject),
  215.         fChangedBy(changedBy)
  216.     {
  217.     }
  218.  
  219.     pascal void UpdateDependent(TObject* aDependent);
  220. };
  221.  
  222. #pragma segment MAObjectRes
  223. pascal void CUpdateDependent::UpdateDependent(TObject* aDependent)
  224. {
  225.     aDependent->HandleUpdate(fChange, fChangedObject, fChangedBy);
  226. }
  227.  
  228. #pragma segment MAObjectRes
  229. pascal void TObject::UpdateDependents(ChangeID theChange,
  230.                                       TObject* changedObject,
  231.                                       TObject* changedBy)
  232. {
  233.     CUpdateDependent scopeLink(theChange, changedObject, changedBy);
  234.     this->EachDependent((DoToObjectType) & CUpdateDependent::UpdateDependent, &scopeLink);
  235. }
  236.  
  237. //--------------------------------------------------------------------------------------------------
  238. #pragma segment MAObjectRes
  239.  
  240. class CUpdateNotifier
  241. {
  242.     ChangeID& fChange;
  243.     TObject* fChangedObject;
  244.     TObject* fChangedBy;
  245. public:
  246.     CUpdateNotifier(ChangeID& theChange,
  247.                     TObject* changedObject,
  248.                     TObject* changedBy) :
  249.         fChange(theChange),
  250.         fChangedObject(changedObject),
  251.         fChangedBy(changedBy)
  252.     {
  253.     }
  254.     pascal void UpdateNotifier(TObject* aNotifier);
  255. };
  256.  
  257. #pragma segment MAObjectRes
  258. pascal void CUpdateNotifier::UpdateNotifier(TObject* aNotifier)
  259. {
  260.     aNotifier->HandleUpdate(fChange, fChangedObject, fChangedBy);
  261. }
  262.  
  263. #pragma segment MAObjectRes
  264. pascal void TObject::UpdateNotifiers(ChangeID theChange,
  265.                                      TObject* changedObject,
  266.                                      TObject* changedBy)
  267. {
  268.     CUpdateNotifier scopeLink(theChange, changedObject, changedBy);
  269.     this->EachNotifier((DoToObjectType) & CUpdateNotifier::UpdateNotifier, &scopeLink);
  270. }
  271.  
  272. //--------------------------------------------------------------------------------------------------
  273. #pragma segment MAObjectRes
  274.  
  275. pascal TObject* TObject::Clone(void)
  276.  
  277. {
  278.     return this->ShallowClone();
  279. }
  280.  
  281. //--------------------------------------------------------------------------------------------------
  282. #pragma segment MAStreamNever
  283.  
  284. pascal void TObject::ReadFrom(TStream* /* aStream */)
  285. {
  286.     this->SubClassResponsibility();
  287. }
  288.  
  289. //--------------------------------------------------------------------------------------------------
  290. #pragma segment MAStreamNever
  291.  
  292. pascal void TObject::WriteTo(TStream* /* aStream */)
  293. {
  294.     this->SubClassResponsibility();
  295. }
  296.  
  297. //--------------------------------------------------------------------------------------------------
  298. #pragma segment MAFields
  299.  
  300. pascal void TObject::DynamicFields(TObject* obj)
  301.  
  302. {
  303.     // ??? Would a nicer default be a formatted memory dump? 
  304. }
  305.  
  306. //--------------------------------------------------------------------------------------------------
  307. #pragma segment MAFields
  308.  
  309. pascal void TObject::DoToField(const Str255& ,
  310.                                void* ,
  311.                                short)
  312.  
  313. {
  314.     this->SubClassResponsibility();
  315. }
  316.  
  317. //--------------------------------------------------------------------------------------------------
  318. #pragma segment MAFields
  319.  
  320. pascal void TObject::Fields(TObject* obj)
  321. {
  322.     static const short bObjClassID = bInteger;
  323.     ObjClassID myID;
  324.     Size mySize;
  325.  
  326.     myID = this->GetClass();
  327.     mySize = this->GetClassSize() + this->GetDynamicSize();
  328.  
  329.     obj->DoToField("TObject", (Ptr)NULL, bClass);
  330.     obj->DoToField("ObjClassID", (Ptr) & myID, bObjClassID);
  331.     obj->DoToField("Size in bytes", &mySize, bLongInt);
  332.  
  333.     this->DynamicFields(obj);                            // Get the dynamic part inspected 
  334. }
  335.  
  336. //--------------------------------------------------------------------------------------------------
  337. #pragma segment MAObjectRes
  338.  
  339. pascal void TObject::ForAllSubClassesDo(DoToSubClassType DoToSubClass,
  340.                                         void* localScope)
  341. {
  342.     EachSubClassDo(this->GetClass(), DoToSubClass, localScope);
  343. }
  344.  
  345. //--------------------------------------------------------------------------------------------------
  346. #pragma segment MAObjectRes
  347.  
  348. pascal void TObject::ForAllSuperClassesDo(DoToSuperClassType DoToSuperClass,
  349.                                           void* localScope)
  350. {
  351.     EachSuperClassDo(this->GetClass(), DoToSuperClass, localScope);
  352. }
  353.  
  354. //--------------------------------------------------------------------------------------------------
  355. #pragma segment MAObjectRes
  356.  
  357. pascal void TObject::Free(void)
  358.  
  359. {
  360.     this->RemoveAllDependencies();
  361.     this->ShallowFree();
  362. }
  363.  
  364. //--------------------------------------------------------------------------------------------------
  365. #pragma segment MAObjectRes
  366.  
  367. pascal void TObject::GetClassName(MAName& clName)
  368. {
  369.     GetClassNameFromID(this->GetClass(), clName);
  370. }
  371.  
  372. //--------------------------------------------------------------------------------------------------
  373. #pragma segment MAObjectRes
  374.  
  375. pascal ObjClassID TObject::GetClass(void)
  376. {
  377.     return GetClassID(this);
  378. }
  379.  
  380. //--------------------------------------------------------------------------------------------------
  381. #pragma segment MAObjectRes
  382.  
  383. pascal Size TObject::GetClassSize(void)
  384. {
  385.     return GetClassSizeFromID(this->GetClass());
  386. }
  387.  
  388. //--------------------------------------------------------------------------------------------------
  389. #pragma segment MAObjectRes
  390.  
  391. pascal Ptr TObject::GetDynamicPtr(void)
  392. {
  393.     Size classSize = this->GetClassSize();
  394.  
  395.     if (GetHandleSize((Handle)this) - classSize > 0)
  396.         return (Ptr)(StripLong(*((Handle)this)) + classSize);
  397.     else
  398.         return NULL;
  399. }
  400.  
  401. //--------------------------------------------------------------------------------------------------
  402. #pragma segment MAInspector
  403.  
  404. pascal void TObject::GetInspectorName(Str255& inspectorName)
  405. {
  406. }
  407.  
  408. //--------------------------------------------------------------------------------------------------
  409. #pragma segment MAObjectRes
  410.  
  411. pascal Size TObject::GetDynamicSize(void)
  412. {
  413.     return GetHandleSize((Handle)this) - this->GetClassSize();
  414. }
  415.  
  416. //--------------------------------------------------------------------------------------------------
  417. #pragma segment MAObjectRes
  418.  
  419. pascal ObjClassID TObject::GetSuperClass(void)
  420. {
  421.     return GetSuperClassID(this->GetClass());
  422. }
  423.  
  424. //--------------------------------------------------------------------------------------------------
  425. #pragma segment MAObjectRes
  426.  
  427. pascal void TObject::Initialize(void)
  428. {
  429. }
  430.  
  431. //--------------------------------------------------------------------------------------------------
  432. #pragma segment MAObjectRes
  433.  
  434. pascal void TObject::IObject(void)
  435. {
  436.     this->Initialize();
  437. }
  438.  
  439. //--------------------------------------------------------------------------------------------------
  440. #pragma segment MAObjectRes
  441.  
  442. pascal Boolean TObject::IsSameClass(ObjClassID testClass)
  443. {
  444.     return this->GetClass() == testClass;
  445. }
  446.  
  447. //--------------------------------------------------------------------------------------------------
  448. #pragma segment MAObjectRes
  449.  
  450. pascal Boolean TObject::IsMemberClass(ObjClassID testClass)
  451. {
  452.     return IsClassIDMemberClass(this->GetClass(), testClass);
  453. }
  454.  
  455. //--------------------------------------------------------------------------------------------------
  456. #pragma segment MAObjectRes
  457.  
  458. pascal Boolean TObject::Lock(Boolean lockIt)
  459. {
  460.     Boolean wasLocked;
  461.  
  462.     wasLocked = IsHandleLocked((Handle)this);
  463.     if (wasLocked != lockIt)
  464.     {
  465.         if (lockIt)
  466.             HLock((Handle)this);
  467.         else
  468.             HUnlock((Handle)this);
  469.     }
  470.     return wasLocked;
  471. }
  472.  
  473. //--------------------------------------------------------------------------------------------------
  474. #pragma segment MAObjectRes
  475.  
  476. pascal void TObject::SetDynamicSize(Size newSize)
  477. {
  478.     Boolean objectsFromPerm = AllocateObjectsFromPerm(true);
  479.  
  480.     AllocateObjectsFromPerm(objectsFromPerm);
  481.  
  482.     if (qMacApp && objectsFromPerm)
  483.         SetPermHandleSize((Handle)this, newSize + this->GetClassSize());
  484.     else
  485.         SetHandleSize((Handle)this, newSize + this->GetClassSize());
  486. }
  487.  
  488. //--------------------------------------------------------------------------------------------------
  489. #pragma segment MAObjectRes
  490.  
  491. pascal TObject* TObject::ShallowClone(void)
  492. {
  493.     TObject * result;
  494.     Boolean oldPerm;
  495.     OSErr err;
  496.  
  497. #if qDebugMsg
  498.     MAName s;
  499. #endif
  500.  
  501. #if qDebugMsg
  502.     if (gAskAboutAlloc)
  503.     {
  504.         GetCallersMethodName(s);
  505.  
  506.         if (s == "TOBJECT.CLONE")                /* report about caller of TObject->Clone(),
  507.                                                   instead */
  508.             GetMethodName(*((LongIntPtr)GetCurStackFramePtr()) + 4, s);
  509.  
  510.         fprintf(stderr, "Within %s: trying to clone a: '", (char *) s);
  511.         this->GetClassName(s);
  512.         fprintf(stderr, "%s.", (char *) s);
  513.  
  514. #ifdef qDebug
  515.         if (ReadYesNo("     Return NULL (Y or N) [N]? "))
  516.             return NULL;
  517. #endif
  518.     }
  519. #endif
  520.  
  521.     result = this;
  522.  
  523. #if qMacApp
  524.     oldPerm = PermAllocation(true);
  525. #endif
  526.  
  527.     err = HandToHand(*((Handle*)&result));
  528.  
  529. #if qMacApp
  530.     oldPerm = PermAllocation(oldPerm);
  531. #endif
  532.  
  533.     if (err != noErr)
  534.         result = NULL;
  535.     FailNIL(result);
  536.  
  537.     if (qInspector)
  538.         AddObjectToInspector(result);
  539.  
  540.     return result;
  541. }
  542.  
  543. //--------------------------------------------------------------------------------------------------
  544. #pragma segment MAObjectRes
  545.  
  546. pascal void TObject::ShallowFree(void)
  547.  
  548. {
  549.     delete this;
  550. }
  551.  
  552. //--------------------------------------------------------------------------------------------------
  553. #pragma segment MAObjectRes
  554.  
  555. pascal void TObject::SubClassResponsibility(void)
  556. {
  557. #if qDebug
  558.     MAName s;
  559. #endif
  560.  
  561. #if qDebugMsg
  562.     GetCallersMethodName(s);
  563.  
  564.     fprintf(stderr, "%s: must be overridden!", (char *) s);
  565.     ProgramBreak("");
  566. #endif
  567.  
  568.     Failure(minErr, 0);                            // assign an error message 
  569. }
  570.  
  571.