home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- **
- ** C++ Class Library for the Amiga© system software.
- **
- ** Copyright (C) 1994 by Armin Vogt ** EMail: armin@uni-paderborn.de
- ** All Rights Reserved.
- **
- ** $Source: apphome:APlusPlus/RCS/libsource/IntuiObject.cxx,v $
- ** $Revision: 1.5 $
- ** $Date: 1994/05/08 13:48:21 $
- ** $Author: Armin_Vogt $
- **
- ******************************************************************************/
-
-
- #include <APlusPlus/intuition/IntuiObject.h>
- #include <APlusPlus/intuition/IntuiRoot.h>
-
-
- /*------------------------- IConstraints methods --------------------------------*/
-
- volatile static char rcs_id[] = "$Id: IntuiObject.cxx,v 1.5 1994/05/08 13:48:21 Armin_Vogt Exp Armin_Vogt $";
-
-
- LONG IntuiObject::newConstraint(Tag onChangedTag,IntuiObject *noticeThis,Tag mapToTag)
- {
- MapArray *dTable;
- if (NULL==(dTable=(MapArray*)cTable.find(onChangedTag)))
- cTable[onChangedTag] = dTable = new MapArray;
-
- (*dTable)[mapToTag] = noticeThis;
- ULONG dataStore;
- return getAttribute(onChangedTag,dataStore);
- }
-
- void IntuiObject::releaseObject(IntuiObject *obj)
- {
- }
-
- void IntuiObject::changedAttrs(AttrList& attrs)
- {
- AttrIterator tags(attrs);
- while (tags())
- {
- MapArray *dTable;
- if (NULL!=(dTable=(MapArray*)cTable.find(tags.tag())))
- {
- MapArrayIterator next(*dTable);
- IntuiObject *iob;
-
- while (NULL != (iob=(IntuiObject*)next()))
- {
- if (!(iob->setAttributesIsRecurrent))
- iob->setAttributes(AttrList(next.key(),tags.data(),TAG_END) );
- }
- }
- }
- }
-
- /*------------------------- IntuiRoot methods --------------------------------*/
-
- // initialise global static variable
- IntuiRoot *IntuiRoot::APPIntuiRoot = NULL;
-
-
- IntuiRoot::IntuiRoot() : ScreenC(NULL,(UBYTE*)NULL)
- {
- iob_count = 0;
- _dout("IntuiRoot initialised.\n");
- }
-
- IntuiRoot::~IntuiRoot()
- {
- _dout("IntuiRoot::~IntuiRoot()\n");
-
- FOREACHSAFE(IntuiObject,this)
- {
- _dout("kill "<<node->status()<<" at "<<(long)node<<" / ");
- delete node;
- _dout("\tkilled.\n");
- }
- NEXTSAFE
- _dout("IntuiRoot::~IntuiRoot() done.\n");
-
- /** This may prevent executing setAttributes() on a deleted object.
- ** But its the sendNotification() routine duty to check for the integrity of each
- ** addressed IntuiObject before calling setAttributes on it.
- ** Otherwise this may become a source of random enforcer hits when the deleted
- ** object's memory may already have been overwritten or not!
- **/
- setAttributesIsRecurrent = TRUE;
- }
-
- BOOL IntuiRoot::APPinitialise(int argc, char *argv[])
- /* MUST be called before creating any APP Intuition classes.
- */
- {
- APPIntuiRoot = new IntuiRoot;
- if (APPOK(APPIntuiRoot))
- {
- _dout("IntuiRoot initialised.\n");
- return TRUE;
- }
- else return FALSE;
- }
-
- void IntuiRoot::APPexit()
- {
- if (APPIntuiRoot)
- {
- delete APPIntuiRoot;
- APPIntuiRoot = NULL;
- }
- }
-
-
- /*------------------------- IntuiObject methods ------------------------------*/
-
- IntuiObject::IntuiObject(IntuiObject *owner,const AttrList& attrs)
- : attrList(attrs)
- {
- _dout("IntuiObject::IntuiObject()\n");
-
- iTransponder = NULL;
- setAttributesIsRecurrent = FALSE;
-
- setIOType(INTUIOBJECT_CLASS);
-
- if (owner==OWNER_ROOT)
- {
- if (IntuiRoot::APPIntuiRoot)
- IntuiRoot::APPIntuiRoot->addTail(this);
- }
- else
- {
- //_dout("\towner is class"<<owner->ID()<<endl);
- if (owner->isKindOfIntuiObject())
- owner->addTail(this);
- else
- {
- if (IntuiRoot::APPIntuiRoot)
- IntuiRoot::APPIntuiRoot->addTail(this);
- cerr << "IntuiObject: owner is not derived from IntuiObject!\n";
- }
- }
-
- if (IntuiRoot::APPIntuiRoot)
- IntuiRoot::APPIntuiRoot->iob_count++;
-
- IObject() = NULL; // initialise for safety
-
- processAttrs(attrList);
-
- _dout(".IntuiObject(" << status() << ")\n" );
- }
-
- void IntuiObject::processAttrs(AttrList& attrs)
- {
- AttrManipulator next(attrs);
-
- if (next.findTagItem(IOB_ITransponder)) // look out for itransponder attachment
- {
- iTransponder = (ITransponder*)next.data();
- }
-
- next.reset();
-
- while (next.findTagItem(IOB_CnstSource)) // look out for constraint definition
- {
- IntuiObject *sourceIOB = (IntuiObject*)next.data();
- if (APPOK(sourceIOB))
- {
- if (next())
- if (next.tag()==IOB_CnstTag) // following tag must be constraint source tag specifier
- {
- Tag sourceTag = next.data();
- // initialise own tag data from constraint source
- if (next())
- next.writeData( sourceIOB->newConstraint(sourceTag,this,next.tag()) );
- }
- }
- else _ierror(INTUIOBJECT_CONSTRAINTSOURCE_NO_IOB);
- }
- }
-
- IntuiObject::~IntuiObject()
- {
- _dout("IntuiObject::~IntuiObject() kill childs..\n");
- FOREACHSAFE(IntuiObject, this)
- {
- _dout("kill IntuiObject..\n");
- delete node;
- _dout("\tkilled.\n");
- }
- NEXTSAFE
-
- {
- MapArrayIterator next(cTable);
- MapArray *dTable;
- while (NULL != (dTable = (MapArray*)next())) delete dTable;
- }
-
- _dout("IntuiObject::~IntuiObject() done.\n");
- IObject() = NULL;
- if (IntuiRoot::APPIntuiRoot) IntuiRoot::APPIntuiRoot->iob_count--;
- }
-
-
- IntuiObject *IntuiObject::findRootOfKind(LONG basetype)
- /* get the first object upwards searching in the tree
- that is a kind of the given basetype.
- */
- {
- IntuiObject *io = this;
-
- /* this loop terminates when io addresses the IntuiRoot. Its MinNodeC is not linked
- into a list and therefore io->findList() will return NULL. */
- while (NULL != (io = io->findOwner()))
- if (io->isKindOf(basetype)) return io;
-
- return NULL;
- }
-
-
- IntuiObject *IntuiObject::findRootOfType(LONG type)
- /* get the first object upwards searching in the tree
- that matches the given IntuiObject type.
- */
- {
- IntuiObject *io = this;
- type |= INTUIOBJECT_CLASS;
- /* this loop terminates when io addresses the IntuiRoot. Its MinNodeC is not linked
- into a list and therefore io->findList() will return NULL. */
- while (NULL != (io = io->findOwner()))
- if (io->isType(type)) return io;
-
- return NULL;
- }
-
- ULONG IntuiObject::setAttributes(AttrList& attrs)
- /* Set attribute tags specified in the given taglist to their corresponding new values
- and start notifying other IntuiObjects via ITransponder and Constraints.
- Return 0L if setAttributes has been called recurrently.
- */
- {
- if (!setAttributesIsRecurrent) // check for a notification loop
- {
- _dout("IntuiObject::setAttributes("<<attrs<<")\n");
- processAttrs(attrs);
-
- attrList.updateAttrs(attrs); // apply changes to Attribute Taglist
-
- setAttributesIsRecurrent = TRUE;
- // a setAttributes call within sendNotification would be recurrent now!
- changedAttrs(attrs); // notify constraint destinations
- if (iTransponder)
- {
- _dout(" IntuiObject::sendNotify("<<attrs<<"\n");
- iTransponder->sendNotification(attrs); // attrs will be changed
- }
-
- setAttributesIsRecurrent = FALSE;
- return 1L;
- }
- else return 0L;
- }
-
- ULONG IntuiObject::getAttribute(Tag tag,ULONG& dataStore)
- {
- return (dataStore=intuiAttrs().getTagData(tag,0));
- }
-
- ostream& operator << (ostream& OS,IntuiObject *iob)
- {
- OS << "status="<<(LONG)iob->status()<<", attrList: "<<iob->intuiAttrs();
- return OS;
- }
-
- /*--------------------- IOBrowser methods ------------------------------------*/
-
- IOBrowser::IOBrowser(IntuiObject *start)
- /* Initialises a search object that iteratively visits all IntuiObjects dependend from
- the start IntuiObject. Note, that IntuiObjects on the same hierarchy level as
- start are not visited.
- */
- {
- sp = 0;
- push((IntuiObject*)start->head());
- _dout("IOBrowser created: "<<IntuiRoot::APPIntuiRoot->getIOBCount()<<" intuiobjects. \n");
- }
-
-
- IntuiObject *IOBrowser::getNext(LONG type)
- /* visits the next IntuiObject in the deep first search through the subtree of
- the start object the IOBrowser was initialised with that is a kind of the
- given IntuiObject type. Subsequent getNext() calls return all IntuiObjects
- in the start object's subtree that are kind of the given IOTYPE except subtrees
- that have a root object of some other kind. The whole subtree is leaved out.
- */
- {
- IntuiObject *root;
-
- do
-
- {
- root = pop(); // get the next node.
-
- if (root==NULL)
- {
- return NULL;
- }
- else
- {
- if (root->succ()) push((IntuiObject*)root->succ());
- // after the root subtree is empty, the successor will be visited
-
- if (root->isKindOf(type) && root->head()) push((IntuiObject*)root->head());
- // descent with the next getNext() into the subtree ONLY if the root of the
- // subtree matches the demanded IOTYPE.
- }
- }
- while ( !(root->isKindOf(type)));
- return root;
- }
-
-