home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / aplusplus-1.01-src.lha / GNU / src / amiga / APlusPlus-1.01 / libsource / IntuiObject.cxx < prev    next >
C/C++ Source or Header  |  1994-05-08  |  9KB  |  326 lines

  1. /******************************************************************************
  2.  **
  3.  **    C++ Class Library for the Amiga© system software.
  4.  **
  5.  **    Copyright (C) 1994 by Armin Vogt  **  EMail: armin@uni-paderborn.de
  6.  **    All Rights Reserved.
  7.  **
  8.  **    $Source: apphome:APlusPlus/RCS/libsource/IntuiObject.cxx,v $
  9.  **    $Revision: 1.5 $
  10.  **    $Date: 1994/05/08 13:48:21 $
  11.  **    $Author: Armin_Vogt $
  12.  **
  13.  ******************************************************************************/
  14.  
  15.  
  16. #include <APlusPlus/intuition/IntuiObject.h>
  17. #include <APlusPlus/intuition/IntuiRoot.h>
  18.  
  19.  
  20. /*------------------------- IConstraints methods --------------------------------*/
  21.  
  22. volatile static char rcs_id[] = "$Id: IntuiObject.cxx,v 1.5 1994/05/08 13:48:21 Armin_Vogt Exp Armin_Vogt $";
  23.  
  24.  
  25. LONG IntuiObject::newConstraint(Tag onChangedTag,IntuiObject *noticeThis,Tag mapToTag)
  26. {
  27.     MapArray *dTable;
  28.     if (NULL==(dTable=(MapArray*)cTable.find(onChangedTag)))
  29.         cTable[onChangedTag] = dTable = new MapArray;
  30.         
  31.     (*dTable)[mapToTag] = noticeThis;
  32.     ULONG dataStore;
  33.     return getAttribute(onChangedTag,dataStore);
  34. }
  35.  
  36. void IntuiObject::releaseObject(IntuiObject *obj)
  37. {
  38. }
  39.  
  40. void IntuiObject::changedAttrs(AttrList& attrs)
  41. {
  42.     AttrIterator tags(attrs);
  43.     while (tags())
  44.     {
  45.         MapArray *dTable;
  46.         if (NULL!=(dTable=(MapArray*)cTable.find(tags.tag())))
  47.         {
  48.             MapArrayIterator next(*dTable);
  49.             IntuiObject *iob;
  50.         
  51.             while (NULL != (iob=(IntuiObject*)next())) 
  52.             {
  53.                 if (!(iob->setAttributesIsRecurrent))
  54.                     iob->setAttributes(AttrList(next.key(),tags.data(),TAG_END) );
  55.             }
  56.         }
  57.     }        
  58. }
  59.  
  60. /*------------------------- IntuiRoot methods --------------------------------*/
  61.  
  62. // initialise global static variable
  63. IntuiRoot *IntuiRoot::APPIntuiRoot = NULL;
  64.  
  65.  
  66. IntuiRoot::IntuiRoot() : ScreenC(NULL,(UBYTE*)NULL)
  67. {
  68.    iob_count = 0;
  69.    _dout("IntuiRoot initialised.\n");
  70. }
  71.  
  72. IntuiRoot::~IntuiRoot()
  73. {
  74.    _dout("IntuiRoot::~IntuiRoot()\n");
  75.  
  76.    FOREACHSAFE(IntuiObject,this)
  77.    {
  78.       _dout("kill "<<node->status()<<" at "<<(long)node<<" / ");
  79.       delete node;
  80.       _dout("\tkilled.\n");
  81.    }
  82.    NEXTSAFE
  83.    _dout("IntuiRoot::~IntuiRoot() done.\n");
  84.     
  85.     /** This may prevent executing setAttributes() on a deleted object.
  86.      ** But its the sendNotification() routine duty to check for the integrity of each 
  87.      ** addressed IntuiObject before calling setAttributes on it. 
  88.      ** Otherwise this may become a source of random enforcer hits when the deleted
  89.      ** object's memory  may already have been overwritten or not!
  90.      **/    
  91.     setAttributesIsRecurrent = TRUE;
  92. }
  93.  
  94. BOOL IntuiRoot::APPinitialise(int argc, char *argv[])
  95.    /* MUST be called before creating any APP Intuition classes.
  96.    */
  97. {
  98.    APPIntuiRoot = new IntuiRoot;
  99.    if (APPOK(APPIntuiRoot))
  100.    {
  101.         _dout("IntuiRoot initialised.\n");
  102.         return TRUE;
  103.    }
  104.     else return FALSE;
  105. }
  106.  
  107. void IntuiRoot::APPexit()
  108. {
  109.    if (APPIntuiRoot)
  110.    {
  111.       delete APPIntuiRoot;
  112.       APPIntuiRoot = NULL;
  113.    }
  114. }
  115.  
  116.  
  117. /*------------------------- IntuiObject methods ------------------------------*/
  118.  
  119. IntuiObject::IntuiObject(IntuiObject *owner,const AttrList& attrs)
  120.     : attrList(attrs)
  121. {        
  122.    _dout("IntuiObject::IntuiObject()\n");
  123.     
  124.     iTransponder = NULL;
  125.    setAttributesIsRecurrent = FALSE;
  126.  
  127.    setIOType(INTUIOBJECT_CLASS);
  128.  
  129.    if (owner==OWNER_ROOT)
  130.    {
  131.       if (IntuiRoot::APPIntuiRoot)
  132.          IntuiRoot::APPIntuiRoot->addTail(this);
  133.    }
  134.    else
  135.    {
  136.       //_dout("\towner is class"<<owner->ID()<<endl);
  137.       if (owner->isKindOfIntuiObject())
  138.          owner->addTail(this);
  139.       else
  140.       {
  141.          if (IntuiRoot::APPIntuiRoot)
  142.             IntuiRoot::APPIntuiRoot->addTail(this);
  143.          cerr << "IntuiObject: owner is not derived from IntuiObject!\n";
  144.       }
  145.    }
  146.  
  147.    if (IntuiRoot::APPIntuiRoot)
  148.       IntuiRoot::APPIntuiRoot->iob_count++;
  149.  
  150.    IObject() = NULL;    // initialise for safety
  151.     
  152.     processAttrs(attrList);
  153.     
  154.     _dout(".IntuiObject(" << status() << ")\n" );
  155. }
  156.  
  157. void IntuiObject::processAttrs(AttrList& attrs)
  158. {
  159.     AttrManipulator next(attrs);
  160.     
  161.     if (next.findTagItem(IOB_ITransponder))    // look out for itransponder attachment
  162.     {
  163.         iTransponder = (ITransponder*)next.data();
  164.     }
  165.  
  166.     next.reset();
  167.  
  168.     while (next.findTagItem(IOB_CnstSource))        // look out for constraint definition
  169.     {
  170.         IntuiObject *sourceIOB = (IntuiObject*)next.data();
  171.         if (APPOK(sourceIOB))
  172.         {
  173.             if (next())
  174.                 if (next.tag()==IOB_CnstTag)    // following tag must be constraint source tag specifier
  175.             {                
  176.                 Tag sourceTag = next.data();
  177.                 // initialise own tag data from constraint source
  178.                 if (next())
  179.                     next.writeData( sourceIOB->newConstraint(sourceTag,this,next.tag()) );
  180.             }
  181.         }
  182.         else _ierror(INTUIOBJECT_CONSTRAINTSOURCE_NO_IOB);
  183.     }
  184. }
  185.  
  186. IntuiObject::~IntuiObject()
  187. {        
  188.    _dout("IntuiObject::~IntuiObject() kill childs..\n");
  189.    FOREACHSAFE(IntuiObject, this)
  190.    {
  191.       _dout("kill IntuiObject..\n");
  192.       delete node;
  193.       _dout("\tkilled.\n");
  194.    }
  195.    NEXTSAFE
  196.     
  197.     {    
  198.     MapArrayIterator next(cTable);
  199.     MapArray *dTable;
  200.     while (NULL != (dTable = (MapArray*)next())) delete dTable;
  201.     }    
  202.    
  203.     _dout("IntuiObject::~IntuiObject() done.\n");
  204.    IObject() = NULL;
  205.    if (IntuiRoot::APPIntuiRoot)  IntuiRoot::APPIntuiRoot->iob_count--;
  206. }
  207.  
  208.  
  209. IntuiObject *IntuiObject::findRootOfKind(LONG basetype)
  210.    /* get the first object upwards searching in the tree
  211.       that is a kind of the given basetype.
  212.    */
  213. {
  214.    IntuiObject *io = this;
  215.  
  216.    /* this loop terminates when io addresses the IntuiRoot. Its MinNodeC is not linked
  217.       into a list and therefore io->findList() will return NULL. */
  218.    while (NULL != (io = io->findOwner()))
  219.       if (io->isKindOf(basetype)) return io;
  220.  
  221.    return NULL;
  222. }
  223.  
  224.  
  225. IntuiObject *IntuiObject::findRootOfType(LONG type)
  226.    /* get the first object upwards searching in the tree
  227.       that matches the given IntuiObject type.
  228.    */
  229. {
  230.    IntuiObject *io = this;
  231.    type |= INTUIOBJECT_CLASS;
  232.    /* this loop terminates when io addresses the IntuiRoot. Its MinNodeC is not linked
  233.       into a list and therefore io->findList() will return NULL. */
  234.    while (NULL != (io = io->findOwner()))
  235.       if (io->isType(type)) return io;
  236.  
  237.    return NULL;
  238. }
  239.  
  240. ULONG IntuiObject::setAttributes(AttrList& attrs)
  241.    /* Set attribute tags specified in the given taglist to their corresponding new values
  242.       and start notifying other IntuiObjects via ITransponder and Constraints.
  243.         Return 0L if setAttributes has been called recurrently.
  244.    */
  245. {
  246.    if (!setAttributesIsRecurrent)   // check for a notification loop
  247.    {
  248.       _dout("IntuiObject::setAttributes("<<attrs<<")\n");
  249.         processAttrs(attrs);
  250.                       
  251.         attrList.updateAttrs(attrs);    // apply changes to Attribute Taglist
  252.  
  253.         setAttributesIsRecurrent = TRUE;
  254.         // a setAttributes call within sendNotification would be recurrent now!
  255.         changedAttrs(attrs);        // notify constraint destinations
  256.         if (iTransponder)
  257.        {     
  258.             _dout(" IntuiObject::sendNotify("<<attrs<<"\n");
  259.             iTransponder->sendNotification(attrs);      // attrs will be changed
  260.        }
  261.                     
  262.         setAttributesIsRecurrent = FALSE;
  263.        return 1L;
  264.     }
  265.     else return 0L;
  266. }
  267.  
  268. ULONG IntuiObject::getAttribute(Tag tag,ULONG& dataStore)
  269. {
  270.     return (dataStore=intuiAttrs().getTagData(tag,0));
  271. }
  272.  
  273. ostream& operator << (ostream& OS,IntuiObject *iob)
  274. {
  275.    OS << "status="<<(LONG)iob->status()<<", attrList: "<<iob->intuiAttrs();
  276.    return OS;    
  277. }
  278.  
  279. /*--------------------- IOBrowser methods ------------------------------------*/
  280.  
  281. IOBrowser::IOBrowser(IntuiObject *start)
  282.    /* Initialises a search object that iteratively visits all IntuiObjects dependend from
  283.       the start IntuiObject. Note, that IntuiObjects on the same hierarchy level as
  284.       start are not visited.
  285.    */
  286. {
  287.    sp = 0;
  288.    push((IntuiObject*)start->head());
  289.    _dout("IOBrowser created: "<<IntuiRoot::APPIntuiRoot->getIOBCount()<<" intuiobjects. \n");
  290. }
  291.  
  292.  
  293. IntuiObject *IOBrowser::getNext(LONG type)
  294.    /* visits the next IntuiObject in the deep first search through the subtree of 
  295.         the start object the IOBrowser was initialised with that is a kind of the 
  296.         given IntuiObject type. Subsequent getNext() calls return all IntuiObjects
  297.         in the start object's subtree that are kind of the given IOTYPE except subtrees
  298.         that have a root object of some other kind. The whole subtree is leaved out.
  299.    */
  300. {
  301.    Intu