home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windoware
/
WINDOWARE_1_6.iso
/
winutil
/
project
/
node.cls
< prev
next >
Wrap
Text File
|
1988-11-22
|
6KB
|
228 lines
/* Node is a formal class for things that are connected as part
of a Network. Node defines the connection protocol. Nodes
know their inputs and outputs, their network and their
relative display position in the network. */!!
inherit(Object, #Node, #(name /* node name */
desc /* longer description */
inputs /* collection of inputs */
outputs /* collection of outputs */
network /* who "owns" the node */
x /* display x position */
y /* display y position */), 2, nil)!!
now(NodeClass)!!
/* Create and initialize a new node. */
Def new(self)
{
^init(new(self:Behavior));
} !!
now(Node)!!
/* Return the network the node belongs to. */
Def getNetwork(self)
{
^network;
}!!
/* Return a point of the x and y instance variables. */
Def pos(self)
{
^point(x, y);
}!!
/* Get the description. */
Def getDesc(self)
{ ^desc;
} !!
/* Get the x position. */
Def x(self)
{ ^x;
} !!
/* Get the y position. */
Def y(self)
{ ^y;
} !!
/* Reset the position when disconnecting.
x : the maximum level of any inputs + 1
y : don't change it since it's already set
If the x position changes, propogate it.
Tell the network also.
*/
Def resetPosn(self, inputNode | oldPos)
{
oldPos := pos(self);
if x <= x(inputNode) + 1
x := 0;
do(inputs,
{using(input) x := max(x(input)+1, x);
});
do(outputs,
{using(output)
if inputNode <> output cand self <> output /* avoid loop */
resetPosn(output, self);
endif;
});
endif;
if x+y = 0 /* completely disconnected */
y := 1; /* use a "safe" location */
endif;
/* the new position could conflict with something else in the project */
if oldPos <> pos(self)
resetPosn(network, self, oldPos);
endif;
}!!
/* Set the position when connecting.
x : the maximum level of any inputs + 1
y : the y of input plus the output number
If the x position changes, propogate it.
Also, tell the network.
*/
Def setPosn(self, inputNode | oldPos)
{
oldPos := pos(self);
/* If the node position has not been set, set it's y. */
if x = 0
y := max(0,y(inputNode) + size(getOutputs(inputNode)) - 1);
endif;
/* If the level increases, set it and propogate. */
if x(inputNode) + 1 > x
x := x(inputNode) + 1;
do(outputs,
{using(output)
if inputNode <> output cand self <> output /* avoid loop */
setPosn(output, self);
endif;
});
endif;
/* the new position could conflict with something else in the project */
if oldPos <> pos(self)
resetPosn(network, self, oldPos);
endif;
}!!
/* Set the network the node belongs to. */
Def setNetwork(self, aNet)
{
network := aNet;
}!!
/* To disconnect node n1->n2, n1's outputs must remove n2. */
Def removeOutputs(self, aNode)
{ remove(outputs, aNode);
} !!
/* To disconnect node n1->n2, n2's inputs must remove n1. */
Def removeInputs(self, aNode)
{ remove(inputs, aNode);
} !!
/* Disconnect n1->n2 by updating n1's outputs and n2's inputs.
The node n2 position must be reset based on its former input. */
Def disconnect(self, aNode)
{ removeInputs(aNode, self);
removeOutputs(self, aNode);
resetPosn(aNode, self);
} !!
/* Recursively show all outputs, level by level.
Keep track of visited nodes to avoid looping.
n is the level for formatting. CurPos is a
global of current print position for formatting.
Note: This is for testing networks during development.
*/
Def show(self, visited, n)
{
do(n-CurPos, /* adjust position */
{using(i) print(" ");
});
CurPos:=n; /* update position */
print(self); /* show node */
if size(outputs) == 0 then
printLine("");print(" ");
CurPos := 0;
else
CurPos := CurPos +1;
endif;
do(outputs, /* show outputs */
{using(elem)
if(not(elem in visited)) /* not yet shown */
add(visited, elem); /* avoid looping */
show(elem, visited, n+1); /* recurse */
else
printLine("");
print(" ");
CurPos := 0; /* reset position */
endif;
});
} !!
/* pass through method to return a node's outputs */
Def getOutputs(self)
{ ^outputs;
} !!
/* pass through method to return a node's inputs */
Def getInputs(self)
{ ^inputs;
} !!
/* To connect node n1->n2, n1's outputs must contain n2. */
Def addOutputs(self, aNode)
{
add(outputs, aNode);
} !!
/* To connect n1->n2, n2's inputs must contain n1. */
Def addInputs(self, aNode)
{
add(inputs, aNode);
} !!
/* Connect self->aNode by updating self's outputs and
aNode's inputs. Also, aNode should know it's network
and the position should be set based on it's input. */
Def connect(self, aNode)
{ addInputs(aNode, self);
addOutputs(self, aNode);
setNetwork(aNode, network);
setPosn(aNode, self);
} !!
/* Set the name. */
Def setName(self, aName)
{ name := aName;
} !!
/* Get the name. */
Def getName(self)
{ ^name;
} !!
/* Initialize a new node. Set the name, desc
and position to safe values. Keep track of
our connections in inputs and outputs. These
sets will grow as necessary. */
Def init(self)
{ name := desc:= "";
x := y := 0;
inputs := new(Set, 2);
outputs := new(Set, 2);
} !!
/* Print the node.
This is used during development only. */
Def printOn(self, aStrm)
{
printOn(asString(class(self))+":"+asString(name), aStrm);
}!!