home *** CD-ROM | disk | FTP | other *** search
/ Dream 57 / Amiga_Dream_57.iso / Amiga / Programmation / c / Extensions / APPSource.lha / APlusPlus / libsource / IntuiObject.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-29  |  7.7 KB  |  264 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:RCS/libsource/IntuiObject.cxx,v $
  9.  **   $Revision: 1.11 $
  10.  **   $Date: 1994/07/27 11:49:20 $
  11.  **   $Author: Armin_Vogt $
  12.  **
  13.  ******************************************************************************/
  14.  
  15.  
  16. #include <APlusPlus/intuition/IntuiObject.h>
  17. #include <APlusPlus/intuition/IntuiRoot.h>
  18. #include <APlusPlus/intuition/ITransponder.h>
  19.  
  20.  
  21. /*------------------------- Constraints methods ------------------------------*/
  22.  
  23. static const char rcs_id[] = "$Id: IntuiObject.cxx,v 1.11 1994/07/27 11:49:20 Armin_Vogt Exp Armin_Vogt $";
  24.  
  25. // runtime type inquiry support
  26. intui_typeinfo(IntuiObject, no_bases, rcs_id)
  27.  
  28.  
  29. LONG IntuiObject::newConstraint(Tag onChangedTag,IntuiObject* noticeThis,Tag mapToTag)
  30. {
  31.    MapArray* dTable;
  32.    if (NULL==(dTable=(MapArray*)cTable.find(onChangedTag)))
  33.       cTable[onChangedTag] = dTable = new MapArray;
  34.  
  35.    (*dTable)[mapToTag] = noticeThis;
  36.    ULONG dataStore;
  37.    return getAttribute(onChangedTag,dataStore);
  38. }
  39.  
  40. void IntuiObject::releaseObject(IntuiObject* obj)
  41. {
  42. }
  43.  
  44. void IntuiObject::changedAttrs(AttrList& attrs)
  45. {
  46.    AttrIterator tags(attrs);
  47.    while (tags())
  48.    {
  49.       MapArray* dTable;
  50.       if (NULL!=(dTable=(MapArray*)cTable.find(tags.tag())))
  51.       {
  52.          MapArrayIterator next(*dTable);
  53.          IntuiObject* iob;
  54.  
  55.          while (NULL != (iob=(IntuiObject*)next()))
  56.          {
  57.             if (!(iob->setAttributesIsRecurrent))
  58.                iob->setAttributes(AttrList(next.key(),tags.data(),TAG_END) );
  59.          }
  60.       }
  61.    }
  62. }
  63.  
  64. /*------------------------- IntuiObject methods ------------------------------*/
  65.  
  66. IntuiObject::IntuiObject(IntuiObject* owner,const AttrList& attrs)
  67.    : attrList(attrs)
  68. {
  69.    _dprintf("IntuiObject::IntuiObject()\n");
  70.  
  71.    iTransponder = NULL;
  72.    setAttributesIsRecurrent = FALSE;
  73.  
  74.    setIOType(INTUIOBJECT_CLASS);
  75.  
  76.    if (owner==OWNER_ROOT)
  77.    {
  78.       if (IntuiRoot::APPIntuiRoot)
  79.          IntuiRoot::APPIntuiRoot->addTail(this);
  80.    }
  81.    else
  82.    {
  83.       if (ptr_cast(IntuiObject,owner))
  84.          owner->addTail(this);
  85.       else
  86.       {
  87.          if (IntuiRoot::APPIntuiRoot)
  88.             IntuiRoot::APPIntuiRoot->addTail(this);
  89.          puterr("IntuiObject: owner is not derived from IntuiObject!\n");
  90.       }
  91.    }
  92.  
  93.    if (IntuiRoot::APPIntuiRoot)
  94.       IntuiRoot::APPIntuiRoot->iob_count++;
  95.  
  96.    IObject() = NULL;    // initialise for safety
  97.  
  98.    processAttrs(attrList);
  99. }
  100.  
  101. void IntuiObject::processAttrs(AttrList& attrs)
  102. {
  103.    AttrManipulator next(attrs);
  104.  
  105.    if (next.findTagItem(IOB_ITransponder))   // look out for itransponder attachment
  106.    {
  107.       iTransponder = (ITransponder*)next.data();
  108.    }
  109.  
  110.    next.reset();
  111.  
  112.    while (next.findTagItem(IOB_CnstSource))     // look out for constraint definition
  113.    {
  114.       IntuiObject* sourceIOB = (IntuiObject*)next.data();
  115.       if (APPOK(sourceIOB))
  116.       {
  117.          if (next())
  118.             if (next.tag()==IOB_CnstTag)  // following tag must be constraint source tag specifier
  119.          {
  120.             Tag sourceTag = next.data();
  121.             // initialise own tag data from constraint source
  122.             if (next())
  123.                next.writeData( sourceIOB->newConstraint(sourceTag,this,next.tag()) );
  124.          }
  125.       }
  126.       else _ierror(INTUIOBJECT_CONSTRAINTSOURCE_NO_IOB);
  127.    }
  128. }
  129.  
  130. IntuiObject::~IntuiObject()
  131. {
  132.    _dprintf("IntuiObject::~IntuiObject() kill childs..\n");
  133.    FOREACHSAFE(IntuiObject, this)
  134.    {
  135.       _dprintf("kill IntuiObject..\n");
  136.       delete node;
  137.       _dprintf("\tkilled.\n");
  138.    }
  139.    NEXTSAFE
  140.  
  141.    {
  142.    MapArrayIterator next(cTable);
  143.    MapArray* dTable;
  144.    while (NULL != (dTable = (MapArray*)next())) delete dTable;
  145.    }
  146.  
  147.    _dprintf("IntuiObject::~IntuiObject() done.\n");
  148.    IObject() = NULL;
  149.    if (IntuiRoot::APPIntuiRoot)  IntuiRoot::APPIntuiRoot->iob_count--;
  150. }
  151.  
  152.  
  153. IntuiObject* IntuiObject::findRootOfKind(const Type_info& class_info)
  154.    /* Get the first object upwards searching in the tree that is a kind 
  155.       of the given base class, ie derived from that class..
  156.    */
  157. {
  158.    IntuiObject* io = this;
  159.  
  160.    // This loop terminates when io addresses the IntuiRoot. Its MinNodeC is
  161.    // not linked into a list and therefore io->findList() will return NULL.*/
  162.    while (NULL != (io = io->findOwner()))
  163.       if (class_info.can_cast(ptr_type_id(io))) return io;
  164.  
  165.    return NULL;
  166. }
  167.  
  168. ULONG IntuiObject::setAttributes(AttrList& attrs)
  169.    /* Set attribute tags specified in the given taglist to their corresponding new values
  170.       and start notifying other IntuiObjects via ITransponder and Constraints.
  171.       Return 0L if setAttributes has been called recurrently.
  172.    */
  173. {
  174.    if (!setAttributesIsRecurrent)   // check for a notification loop
  175.    {
  176.       _dprintf("IntuiObject::setAttributes()\n");
  177.       processAttrs(attrs);
  178.  
  179.       attrList.updateAttrs(attrs);  // apply changes to Attribute Taglist
  180.  
  181.       setAttributesIsRecurrent = TRUE;
  182.       // a setAttributes call within sendNotification would be recurrent now!
  183.       changedAttrs(attrs);    // notify constraint destinations
  184.       if (iTransponder)
  185.       {
  186.          _dprintf(" IntuiObject::sendNotify()\n");
  187.          iTransponder->sendNotification(attrs);      // attrs will be changed
  188.       }
  189.  
  190.       setAttributesIsRecurrent = FALSE;
  191.       return 1L;
  192.    }
  193.    else return 0L;
  194. }
  195.  
  196. ULONG IntuiObject::getAttribute(Tag tag,ULONG& dataStore)
  197. {
  198.    return (dataStore=intuiAttrs().getTagData(tag,0));
  199. }
  200.  
  201. void IntuiObject::applyDefaultAttrs(const AttrList& userAttrs, 
  202.                                     const AttrList& defaults)
  203.    /* Work on the 'intuiAttrs': add those tags in the 'defaults' list to 
  204.       'intuiAttrs' which are not already present in 'userAttrs'(!).
  205.       Intended is that the class user can override every Attribute Tag
  206.       the class itself preset as default value. Within the class subclasses
  207.       may override presets of their base classes.
  208.    */
  209. {
  210.    AttrList df_copy(defaults);
  211.    // remove tags already set by the user
  212.    df_copy.filterAttrs(userAttrs,TAGFILTER_NOT);
  213.    // add remaining to intuiAttrs       
  214.    intuiAttrs().addAttrs(df_copy);       
  215.    // and override former values in intuiAttrs
  216.    intuiAttrs().updateAttrs(defaults);
  217. }
  218.  
  219. /*--------------------- IOBrowser methods ------------------------------------*/
  220.  
  221. IOBrowser::IOBrowser(IntuiObject* start)
  222.    /* Initialises a search object that iteratively visits all IntuiObjects that 
  223.       are dependend from the 'start' IntuiObject. 
  224.       Note, that IntuiObjects on the same hierarchy level as start are not visited.
  225.    */
  226. {
  227.    sp = 0;
  228.    push((IntuiObject*)start->head());
  229. }
  230.  
  231.  
  232. IntuiObject* IOBrowser::getNext(const Type_info& class_info)
  233.    /* visits the next IntuiObject in the deep first search through the subtree of
  234.       the start object the IOBrowser was initialised with that is a kind of the
  235.       given IntuiObject type. Subsequent getNext() calls return all IntuiObjects
  236.       in the start object's subtree that are kind of the given IOTYPE except subtrees
  237.       that have a root object of some other kind. The whole subtree is left out.
  238.    */
  239. {
  240.    IntuiObject* root;
  241.  
  242.    do
  243.    {
  244.       root = pop();  // get the next node.
  245.  
  246.       if (root==NULL)
  247.       {
  248.           return NULL;
  249.       }
  250.       else
  251.       {
  252.          if (root->succ()) push((IntuiObject*)root->succ());
  253.          // after the root subtree is empty, the successor will be visited
  254.  
  255.          if (class_info.can_cast(ptr_type_id(root)) && root->head()) push((IntuiObject*)root->head());
  256.          // descent with the next getNext() into the subtree ONLY if the root of the
  257.          // subtree is derived from the specified class.
  258.       }
  259.    }
  260.    while ( !(class_info.can_cast(ptr_type_id(root))) );
  261.    return root;
  262. }
  263.  
  264.