Skip to content

Instantly share code, notes, and snippets.

@jeremytregunna
Created December 18, 2011 23:20
Show Gist options
  • Save jeremytregunna/1494794 to your computer and use it in GitHub Desktop.
Save jeremytregunna/1494794 to your computer and use it in GitHub Desktop.
// Nodes represent what can be compared to a function in another programming language.
// They have inputs, produce outputs, and have some logic built into them. This Node
// is a concrete base class to be used for custom behaviours.
// It should be noted that the order of inputs/outputs fed into Nodes does not matter.
// The only thing that matters is that the Arc objects you plug into the ports of a Node
// have a name that corresponds to the names referenced in the logic contained within.
Node := Object clone do(
with := method(
r := self clone
r callable = call argAt(1)
if(r callable isNil,
r callable = call argAt(0)
,
r inputPorts = call evalArgAt(0)
)
r
)
init := method(
self callable := nil
self inputPorts := Map clone
self outputArcs := Map clone
)
call := method(
if(isFireable,
// We do this to avoid calling any custom init method on the sender.
// We don't want to create a new sender, just add a layer of indirection on top
// of the sender.
ctx := Object clone
ctx prependProto(call sender)
ctx removeProto(Object)
// Rather than set up the args/returns automatically, let the user decide.
ctx setSlot("inputPorts", inputPorts)
ctx setSlot("outputArcs", outputArcs)
// Call our callable in the right context
message(callable) doInContext(ctx, self)
)
nil
)
isFireable := method(
inputPorts select(k, v, v isNil) size == 0
// We don't want to check the outputs because we may be queueing items up that the
// node that our arc is connected to as input.
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment