Skip to content

Commit

Permalink
subgraph test wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ilgarlunin committed Mar 28, 2019
1 parent 553b609 commit 79ca53d
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 26 deletions.
4 changes: 2 additions & 2 deletions PyFlow/Core/Common.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ def canConnectPins(src, dst):
if src.owningNode().graph() is None or dst.owningNode().graph() is None:
return False

if src.owningNode().graph() != dst.owningNode().graph():
return False
# if src.owningNode().graph() != dst.owningNode().graph():
# return False

if cycle_check(src, dst):
print('cycles are not allowed')
Expand Down
4 changes: 4 additions & 0 deletions PyFlow/Core/GraphTree.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ def Tick(self, deltaTime):
node.data.Tick(deltaTime)

def switchGraph(self, newGraphName):
if newGraphName not in self.getTree():
return False

old = self.activeGraph()
new = self.getTree()[newGraphName].data
if old == new:
return False

self.__activeGraph = new
self.onGraphSwitched.send(old=old, new=new)
return True
Expand Down
6 changes: 4 additions & 2 deletions PyFlow/Core/PinBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ def getName(self):
def pinDataTypeHint():
return None

def supportedDataTypes(self):
return (self.dataType,)
@staticmethod
def supportedDataTypes():
return ()

def defaultValue(self):
return self._defaultValue
Expand Down Expand Up @@ -162,6 +163,7 @@ def setData(self, data):
if self.direction == PinDirection.Output:
for i in self.affects:
i._data = self.currentData()
# i.setData(self.currentData())
i.setClean()
if self.direction == PinDirection.Input or self._alwaysPushDirty:
push(self)
Expand Down
15 changes: 6 additions & 9 deletions PyFlow/Packages/PyflowBase/Nodes/graphNodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ def description():
def addOutPin(self):
name = str(len(self.outputs))
p = self.addOutputPin(name, 'AnyPin')
p.setAlwaysPushDirty(True)
# p.setAlwaysPushDirty(True)
p.actLikeDirection = PinDirection.Input
self.onPinCreated.send(p)
return p

def compute(self):
for i in self.outputs.values():
for j in i.affected_by:
i.setData(j.getData())

def postCreate(self, jsonTemplate=None):
super(graphInputs, self).postCreate(jsonTemplate=jsonTemplate)
# recreate dynamically created pins
Expand All @@ -43,14 +48,6 @@ def postCreate(self, jsonTemplate=None):
# add outputs
pass

def compute(self):
# This node is special. Output pins of this node are actually inputs pins in terms of execution and data gathering
# We get data from input pin on subgraphNode and put it to corresponding output pin on graphInputs node
for valuePin in [p for p in self.outputs.values() if p.IsValuePin()]:
# this can be changed to support multiple connections later
# affected_by is list of connected pins
valuePin.setData(list(valuePin.affected_by)[0].getData())


class graphOutputs(NodeBase):
"""Represents a group of output pins on subgraph node
Expand Down
34 changes: 26 additions & 8 deletions PyFlow/Packages/PyflowBase/Nodes/subgraph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import json
import weakref

from PyFlow.Core import NodeBase
from PyFlow.Core import GraphBase
Expand All @@ -15,8 +16,8 @@ class subgraph(NodeBase):
def __init__(self, name):
super(subgraph, self).__init__(name)
self.rawGraph = None
self.__inputsMap = {} # { self.[inputPin].uid: innerPinUid }
self.__outputsMap = {} # { self.[outputPin].uid: innerPinUid }
self.__inputsMap = {} # { self.[inputPin]: innerOutPin }
self.__outputsMap = {} # { self.[outputPin]: innerInPin }

@staticmethod
def pinTypeHints():
Expand Down Expand Up @@ -46,9 +47,10 @@ def onGraphInputPinCreated(self, outPin):
outPin.dataType,
outPin.defaultValue(),
outPin.call,
outPin.constraint,
outPin.supportedDataTypes())
self.__inputsMap[subgraphInputPin.uid] = outPin.uid
outPin.constraint)
subgraphInputPin.supportedDataTypes = outPin.supportedDataTypes
self.__inputsMap[subgraphInputPin] = outPin
pinAffects(subgraphInputPin, outPin)
# connect
outPin.nameChanged.connect(subgraphInputPin.setName)
outPin.killed.connect(subgraphInputPin.kill)
Expand All @@ -58,14 +60,21 @@ def onGraphInputPinDeleted(self, inPin):
print("onGraphInputPinDeleted", inPin.getName())

def onGraphOutputPinCreated(self, inPin):
"""Reaction when pin added to graphOutputs node
Arguments:
inPin {PinBase} -- input pin on graphOutputs node
"""

# add companion pin for graphOutputs node's input pin
subgraphOutputPin = self.addOutputPin(inPin.name,
inPin.dataType,
inPin.defaultValue(),
inPin.call,
inPin.constraint,
inPin.supportedDataTypes())
self.__outputsMap[subgraphOutputPin.uid] = inPin.uid
inPin.constraint)
subgraphOutputPin.supportedDataTypes = inPin.supportedDataTypes
self.__outputsMap[subgraphOutputPin] = inPin
pinAffects(inPin, subgraphOutputPin)
# connect
inPin.nameChanged.connect(subgraphOutputPin.setName)
inPin.killed.connect(subgraphOutputPin.kill)
Expand All @@ -83,3 +92,12 @@ def postCreate(self, jsonTemplate=None):
self.rawGraph.onInputPinDeleted.connect(self.onGraphInputPinDeleted)
self.rawGraph.onOutputPinCreated.connect(self.onGraphOutputPinCreated)
self.rawGraph.onOutputPinDeleted.connect(self.onGraphOutputPinDeleted)

def compute(self):
# get data from subgraph node input pins and put it to inner companions
# for inputPin, innerOutPin in self.__inputsMap.items():
# innerOutPin.setData(inputPin.getData())

# put data from inner graph pins to outer subgraph node output companions
for outputPin, innerPin in self.__outputsMap.items():
outputPin.setData(innerPin.getData())
6 changes: 5 additions & 1 deletion PyFlow/Packages/PyflowBase/Pins/AnyPin.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def serialize(self):
dt['value'] = encodedValue
return dt

def pinConnected(self, other):
self.updateOnConnection(other)
super(AnyPin, self).pinConnected(other)

def updateOnConnection(self, other):
if self.constraint is None:
self.setType(other)
Expand Down Expand Up @@ -149,10 +153,10 @@ def setType(self, other):
self.super = other.__class__
self.dataType = other.dataType
self.color = other.color
self._wrapper().setType(other.color())
self.setData(other.defaultValue())
self.setDefaultValue(other.defaultValue())
self.dirty = other.dirty
self.isPrimitiveType = other.isPrimitiveType
self.jsonEncoderClass = other.jsonEncoderClass
self.jsonDecoderClass = other.jsonDecoderClass
# self._wrapper().setType(other.color())
2 changes: 1 addition & 1 deletion PyFlow/Packages/PyflowBase/Pins/FloatPin.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def color():

@staticmethod
def supportedDataTypes():
return ('FloatPin', 'IntPin')
return ('FloatPin', 'IntPin',)

@staticmethod
def processData(data):
Expand Down
2 changes: 1 addition & 1 deletion PyFlow/Packages/PyflowBase/Pins/IntPin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def color():

@staticmethod
def supportedDataTypes():
return ('IntPin', 'FloatPin')
return ('IntPin', 'FloatPin',)

@staticmethod
def processData(data):
Expand Down
46 changes: 45 additions & 1 deletion PyFlow/Tests/Test_General.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,17 +348,61 @@ def test_subgraph(self):
self.assertEqual(list(subgraphNodeInstance.outputs.values())[0].name, inPin.name, "name is not synchronized")

# add simple calculation
foos = packages['PyflowBase'].GetFunctionLibraries()["IntLib"].getFunctions()

addNode1 = NodeBase.initializeFromFunction(foos["add"])
addNode2 = NodeBase.initializeFromFunction(foos["add"])
GT.activeGraph().addNode(addNode1)
GT.activeGraph().addNode(addNode2)
addNode1.setData("b", 1)
addNode2.setData("b", 1)
connection = connectPins(addNode1.getPinByName('out', PinSelectionGroup.Outputs), addNode2.getPinByName('a', PinSelectionGroup.Inputs))
self.assertEqual(connection, True)

# connect add nodes with graph inputs/outputs
connected = connectPins(inputs1.getPinByName('first'), addNode1.getPinByName('a'))
self.assertEqual(connected, True)
connected = connectPins(outputs1.getPinByName('first'), addNode2.getPinByName('out'))
self.assertEqual(connected, True)

# go back to root graph
GT.switchGraph("testGraph")
self.assertEqual(GT.activeGraph().name, "testGraph", "failed to return back to root from subgraph node")

# check exposed pins added
self.assertEqual(len(subgraphNodeInstance.inputs), 1)
self.assertEqual(len(subgraphNodeInstance.outputs), 1)

# connect getter to subgraph output pin
defaultLibFoos = packages['PyflowBase'].GetFunctionLibraries()["DefaultLib"].getFunctions()
printNode = NodeBase.initializeFromFunction(defaultLibFoos["pyprint"])
GT.activeGraph().addNode(printNode)

subgraphOutPin = subgraphNodeInstance.getPinByName('first', PinSelectionGroup.Outputs)
self.assertIsNotNone(subgraphOutPin, "failed to find subgraph out pin")

connected = connectPins(printNode.getPinByName('entity'), subgraphOutPin)
self.assertEqual(connected, True)

# check value
pass
printNode.getPinByName('inExec').call()
self.assertEqual(printNode.getPinByName('entity').currentData(), 2)

# connect another add node to exposed subgraph input
addNode3 = NodeBase.initializeFromFunction(foos["add"])
GT.activeGraph().addNode(addNode3)
addNode3.setData('a', 1)

subgraphInPin = subgraphNodeInstance.getPinByName('first', PinSelectionGroup.Inputs)
self.assertIsNotNone(subgraphInPin, "failed to find subgraph out pin")

GT.activeGraph().plot()

connected = connectPins(addNode3.getPinByName('out'), subgraphInPin)
self.assertEqual(connected, True)

printNode.getPinByName('inExec').call()
self.assertEqual(printNode.getPinByName('entity').currentData(), 3)


if __name__ == '__main__':
Expand Down
3 changes: 2 additions & 1 deletion run_tests.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
@echo off
python -m unittest discover "PyFlow/Tests"
python -m unittest discover "PyFlow/Tests"
pause

0 comments on commit 79ca53d

Please sign in to comment.