home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 5
/
FreshFish_July-August1994.bin
/
bbs
/
gnu
/
aplusplus-1.01-src.lha
/
src
/
amiga
/
aplusplus-1.01
/
libsource
/
IntuiObject.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-08
|
9KB
|
326 lines
/******************************************************************************
**
** 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.
*/
{
Intu