finsish BuildOper

This commit is contained in:
yyc12345 2023-02-22 21:49:31 +08:00
parent 979183e9fc
commit 54d31ed6bd
3 changed files with 199 additions and 52 deletions

View File

@ -8,22 +8,19 @@ class IntermediateTreeNode(object):
self.m_LocatedPos: int = DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER self.m_LocatedPos: int = DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER
self.m_Collection: collections.deque[int] = collections.deque() self.m_Collection: collections.deque[int] = collections.deque()
class BlocksFactory(object): class IntermediateOperDownwardSearch(object):
def __init__(self, db: sqlite3.Connection, graph: int): def __init__(self):
# assign members self.m_Collection: collections.deque[int] = collections.deque()
self.m_GraphCKID: int = graph
self.m_Db: sqlite3.Connection = db class BlocksFactory(object):
self.__Cursor: sqlite3.Cursor = db.cursor() def __init__(self, db: sqlite3.Connection, graph: DecoratorData.GraphResult):
# assign members
self.m_Graph: DecoratorData.GraphResult = graph
self.m_Db: sqlite3.Connection = db
self.m_BBDict: dict[int, DecoratorData.BBTreeNode] = {}
self.m_OperDict: dict[int, DecoratorData.OperTreeNode] = {}
self.__AllBB: set[int] = set() self.__AllBB: set[int] = set()
self.__AllOper: set[int] = set() self.__AllOper: set[int] = set()
self.m_PassiveOperLayer: DecoratorData.TreeLayout = DecoratorData.TreeLayout()
self.m_ActiveBBLayer: DecoratorData.TreeLayout = DecoratorData.TreeLayout()
self.m_PassiveBBLayer: DecoratorData.TreeLayout = DecoratorData.TreeLayout()
# fill data first # fill data first
self.__FillDataFromDb() self.__FillDataFromDb()
@ -37,25 +34,146 @@ class BlocksFactory(object):
return next(iter(vals)) return next(iter(vals))
def __FillDataFromDb(self): def __FillDataFromDb(self):
self.__Cursor.execute('SELECT * FROM [script_behavior] WHERE parent == ?', (self.m_GraphCKID, )) cursor: sqlite3.Cursor = self.m_Db.cursor()
for sqldata in self.__Cursor.fetchall(): cursor.execute('SELECT * FROM [script_behavior] WHERE parent == ?', (self.m_Graph.m_GraphCKID, ))
for sqldata in cursor.fetchall():
payload: DecoratorData.BBDataPayload = DecoratorData.BBDataPayload(sqldata) payload: DecoratorData.BBDataPayload = DecoratorData.BBDataPayload(sqldata)
self.m_BBDict[payload.m_CKID] = DecoratorData.BBTreeNode(payload) self.m_Graph.m_BlockDict[payload.m_CKID] = DecoratorData.BBTreeNode(payload)
self.__AllBB.add(payload.m_CKID) self.__AllBB.add(payload.m_CKID)
self.__Cursor.execute('SELECT * FROM [script_pOper] WHERE parent == ?', (self.m_GraphCKID, )) cursor.execute('SELECT * FROM [script_pOper] WHERE parent == ?', (self.m_Graph.m_GraphCKID, ))
for sqldata in self.__Cursor.fetchall(): for sqldata in cursor.fetchall():
payload: DecoratorData.OperDataPayload = DecoratorData.OperDataPayload(sqldata) payload: DecoratorData.OperDataPayload = DecoratorData.OperDataPayload(sqldata)
self.m_OperDict[payload.m_CKID] = DecoratorData.OperTreeNode(payload) self.m_Graph.m_BlockDict[payload.m_CKID] = DecoratorData.OperTreeNode(payload)
self.__AllOper.add(payload.m_CKID) self.__AllOper.add(payload.m_CKID)
def __FindBBBottomOperRoot(self, start_pOut: int) -> tuple[int]: cursor.close()
pass
def __BuildOper(self, tree: DecoratorData.TreeLayout, start_oper: int): def __FindBBBottomOperRoot(self, start_pOut: tuple[int]) -> tuple[int]:
pass cursor: sqlite3.Cursor = self.m_Db.cursor()
cursor_outget: sqlite3.Cursor = self.m_Db.cursor()
def __BuildBB(self, tree: DecoratorData.TreeLayout, start_bb: int): # prepare something
stack: collections.deque[int] = collections.deque()
procedOut: set[int] = set()
result: set[int] = set()
# prepare start symbol
stack.extend(start_pOut)
# analyze
while len(stack) != 0:
# peek again
pout: int = stack.pop()
# search this pOut in pLink
cursor.execute('SELECT [output], [output_obj], [output_type], [output_is_bb] FROM [script_pLink] WHERE ([input] == ? AND NOT (([output_type] == ? OR [output_type] == ?) AND [output_is_bb] == ?) AND [parent] == ?);',
(pout,
DecoratorConst.Export_pLink_InputOutputType.PIN, DecoratorConst.Export_pLink_InputOutputType.PTARGET, DecoratorConst.Export_Boolean.TRUE, # filter all BB's pIn
self.m_Graph.m_GraphCKID)
)
# read datas
for (output, output_obj, output_type, output_is_bb, ) in cursor.fetchall():
# check dup
if output in procedOut:
continue
procedOut.add(output)
if output_type == DecoratorConst.Export_pLink_InputOutputType.PIN and output_is_bb == DecoratorConst.Export_Boolean.FALSE:
# this is a oper. find its pOut and add into stack
cursor_outget.execute('SELECT [thisobj] FROM [script_pOut] WHERE [parent] == ?;',
(output_obj, )
)
for (thisobj, ) in cursor_outget.fetchall():
stack.append(thisobj)
else:
# this oper point to non-pIn, should be add into result
result.add(output_obj)
# free cursor and return
cursor.close()
cursor_outget.close()
return tuple(i for i in result)
def __BuildOper(self, tree: DecoratorData.TreeLayout[DecoratorData.OperTreeNode], start_oper: int):
# prepare stack and start condition
stack: collections.deque[IntermediateTreeNode] = collections.deque()
# check whether this BB has been processed
if start_oper not in self.__AllOper:
return
self.__AllOper.remove(start_oper)
# create cursor
cursor: sqlite3.Cursor = self.m_Db.cursor()
# create new layer and insert it
tree.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
tree.NewItem(self.m_Graph.m_BlockDict[start_oper])
# prepare stack data
start_oper_data: IntermediateTreeNode = IntermediateTreeNode()
start_oper_data.m_LoactedLayer = tree.GetCurrentLayerIndex()
start_oper_data.m_LocatedPos = tree.GetCurrentItemIndex()
cursor.execute("SELECT [input_obj] FROM [script_pLink] WHERE ([output_obj] == ? AND [output_type] == ? AND [input_type] == ? AND [input_is_bb] == ? AND [parent] = ?);",
(start_oper, DecoratorConst.Export_pLink_InputOutputType.PIN, # order pOper's pIn
DecoratorConst.Export_pLink_InputOutputType.POUT, DecoratorConst.Export_Boolean.FALSE, # order pOper's pOut
self.m_Graph.m_GraphCKID, )
)
for (input_obj, ) in cursor.fetchall():
start_oper_data.m_Collection.append(input_obj)
stack.append(start_oper_data)
# start analyze
while len(stack) != 0:
# pick stack and decide whether pop this
stack_entry: IntermediateTreeNode = stack[-1]
if len(stack_entry.m_Collection) == 0:
stack.pop()
continue
# pick a new Oper from collection.
# check whether it need process
oper_id: int = stack_entry.m_Collection[-1]
if oper_id not in self.__AllOper:
stack_entry.m_Collection.pop()
continue
self.__AllOper.remove(oper_id)
# get corresponding tree node
tree_node: DecoratorData.BBTreeNode = self.m_Graph.m_BlockDict[oper_id]
# start proc Oper
# create new stack entry
oper_data: IntermediateTreeNode = IntermediateTreeNode()
# push tree node into tree layout and get corresponding index.
# create new layer according to whether first visit
if stack_entry.m_FirstVisit:
tree.NewItem(tree_node)
oper_data.m_LoactedLayer = stack_entry.m_LoactedLayer
oper_data.m_LocatedPos = stack_entry.m_LocatedPos + 1
# reset first visit
stack_entry.m_FirstVisit = False
else:
tree.NewLayer(stack_entry.m_LoactedLayer, stack_entry.m_LocatedPos)
tree.NewItem(tree_node)
oper_data.m_LoactedLayer = tree.GetCurrentLayerIndex()
oper_data.m_LocatedPos = tree.GetCurrentItemIndex()
# query and fill stack entry data
cursor.execute("SELECT [input_obj] FROM [script_pLink] WHERE ([output_obj] == ? AND [output_type] == ? AND [input_type] == ? AND [input_is_bb] == ? AND [parent] = ?);",
(oper_id, DecoratorConst.Export_pLink_InputOutputType.PIN, # order pOper's pIn
DecoratorConst.Export_pLink_InputOutputType.POUT, DecoratorConst.Export_Boolean.FALSE, # order pOper's pOut
self.m_Graph.m_GraphCKID, )
)
for (output_obj, ) in cursor.fetchall():
oper_data.m_Collection.append(output_obj)
stack.append(oper_data)
cursor.close()
def __BuildBB(self, tree: DecoratorData.TreeLayout[DecoratorData.BBTreeNode], start_bb: int):
# prepare stack and start condition # prepare stack and start condition
stack: collections.deque[IntermediateTreeNode] = collections.deque() stack: collections.deque[IntermediateTreeNode] = collections.deque()
@ -64,18 +182,21 @@ class BlocksFactory(object):
return return
self.__AllBB.remove(start_bb) self.__AllBB.remove(start_bb)
# create cursor
cursor: sqlite3.Cursor = self.m_Db.cursor()
# create new layer and insert it # create new layer and insert it
tree.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER) tree.NewLayer(DecoratorData.TreeLayout.NO_REFERENCE_LAYER, DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER)
tree.NewItem(self.m_BBDict[start_bb]) tree.NewItem(self.m_Graph.m_BlockDict[start_bb])
# prepare stack data # prepare stack data
start_bb_data: IntermediateTreeNode = IntermediateTreeNode() start_bb_data: IntermediateTreeNode = IntermediateTreeNode()
start_bb_data.m_LoactedLayer = tree.GetCurrentLayerIndex() start_bb_data.m_LoactedLayer = tree.GetCurrentLayerIndex()
start_bb_data.m_LocatedPos = tree.GetCurrentItemIndex() start_bb_data.m_LocatedPos = tree.GetCurrentItemIndex()
self.__Cursor.execute("SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;", cursor.execute("SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [parent] = ?) ORDER BY [input_index] ASC;",
(start_bb, DecoratorConst.Database_bLink_InputOutputType.OUTPUT, self.m_GraphCKID, ) (start_bb, DecoratorConst.Export_bLink_InputOutputType.OUTPUT, self.m_Graph.m_GraphCKID, )
) )
for (output_obj, ) in self.__Cursor.fetchall(): for (output_obj, ) in cursor.fetchall():
start_bb_data.m_Collection.append(output_obj) start_bb_data.m_Collection.append(output_obj)
stack.append(start_bb_data) stack.append(start_bb_data)
@ -96,7 +217,7 @@ class BlocksFactory(object):
self.__AllBB.remove(bb_id) self.__AllBB.remove(bb_id)
# get corresponding tree node # get corresponding tree node
tree_node = self.m_BBDict[bb_id] tree_node: DecoratorData.BBTreeNode = self.m_Graph.m_BlockDict[bb_id]
# start proc BB # start proc BB
# create new stack entry # create new stack entry
@ -117,25 +238,33 @@ class BlocksFactory(object):
bb_data.m_LoactedLayer = tree.GetCurrentLayerIndex() bb_data.m_LoactedLayer = tree.GetCurrentLayerIndex()
bb_data.m_LocatedPos = tree.GetCurrentItemIndex() bb_data.m_LocatedPos = tree.GetCurrentItemIndex()
# query and fill stack entry data # query and fill stack entry data
self.__Cursor.execute("SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;", cursor.execute("SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;",
(bb_id, DecoratorConst.Database_bLink_InputOutputType.OUTPUT, self.m_GraphCKID, ) (bb_id, DecoratorConst.Export_bLink_InputOutputType.OUTPUT, self.m_Graph.m_GraphCKID, )
) )
for (output_obj, ) in self.__Cursor.fetchall(): for (output_obj, ) in cursor.fetchall():
bb_data.m_Collection.append(output_obj) bb_data.m_Collection.append(output_obj)
stack.append(bb_data) stack.append(bb_data)
# todo: executing oper finder for current bb # todo: executing oper finder for current bb
cursor.close()
def __ProcActiveBB(self): def __ProcActiveBB(self):
self.__Cursor.execute("SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;", cursor: sqlite3.Cursor = self.m_Db.cursor()
(self.m_GraphCKID, DecoratorConst.Database_bLink_InputOutputType.INPUT, self.m_GraphCKID, ) cursor.execute("SELECT [output_obj] FROM [script_bLink] WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;",
(self.m_Graph.m_GraphCKID, DecoratorConst.Export_bLink_InputOutputType.INPUT, self.m_Graph.m_GraphCKID, )
) )
for (output_obj, ) in self.__Cursor.fetchall(): for (output_obj, ) in cursor.fetchall():
self.__BuildBB(self.m_ActiveBBLayer, output_obj) self.__BuildBB(self.m_Graph.m_ActiveBB, output_obj)
cursor.close()
def __ProcPassiveBB(self): def __ProcPassiveBB(self):
cursor: sqlite3.Cursor = self.m_Db.cursor()
while len(self.__AllBB) != 0: while len(self.__AllBB) != 0:
self.__BuildBB(self.m_PassiveBBLayer, self.__GetOneFromSet(self.__AllBB)) self.__BuildBB(self.m_PassiveBBLayer, self.__GetOneFromSet(self.__AllBB))
cursor.close()
def __ProcPassiveOper(self): def __ProcPassiveOper(self):
pass pass

View File

@ -1,9 +1,13 @@
class Database_bLink_InputOutputType(object): class Export_Boolean(object):
TRUE = 1
FALSE = 0
class Export_bLink_InputOutputType(object):
INPUT = 0 INPUT = 0
OUTPUT = 1 OUTPUT = 1
class Database_pLink_InputOutputType(object): class Export_pLink_InputOutputType(object):
PIN = 0 PIN = 0
POUT = 1 POUT = 1
PLOCAL = 2 PLOCAL = 2

View File

@ -1,3 +1,14 @@
'''
NOTE:
There are 3 different styles shape in generated graph.
"Block" is stands for the large block, including BB and pOper.
"Cell" is stands for the medium block, including pLocal, pAttr, Shortcut.
"Particle" is stands for the small block, including bIO, pIO, pTarget.
Besides these shapes, the generated graph also include various links.
There are 2 types link. bLink and pLink.
'''
import typing, collections, sqlite3 import typing, collections, sqlite3
class Vector(object): class Vector(object):
@ -59,7 +70,7 @@ class Margin(object):
self.m_BodySize: Vector = Vector() self.m_BodySize: Vector = Vector()
self.m_BottomSize: Vector = Vector() self.m_BottomSize: Vector = Vector()
class ICanComputeSize(object): class ICanManipulate(object):
''' '''
This class is served for TreeLayout class. This class is served for TreeLayout class.
@ -70,23 +81,15 @@ class ICanComputeSize(object):
The reason is that the vertical and horizonal direction between BB and Oper is opposited. The reason is that the vertical and horizonal direction between BB and Oper is opposited.
So we use Leaves and Root to give theme an uniformed concept. So we use Leaves and Root to give theme an uniformed concept.
''' '''
def GetPos() -> Vector: def SetOrigin():
''' pass
Get current node's start position.
'''
raise NotImplementedError()
def GetSize() -> Vector:
'''
Get current node's size.
'''
raise NotImplementedError()
def ComputeSize() -> Vector: def ComputeSize() -> Vector:
''' '''
Get current node's start position Get current node's start position
''' '''
raise NotImplementedError() raise NotImplementedError()
TNode = typing.TypeVar('TNode', bound=ICanComputeSize) TNode = typing.TypeVar('TNode', bound=ICanManipulate)
class TreeLayoutLayer(typing.Generic[TNode]): class TreeLayoutLayer(typing.Generic[TNode]):
def __init__(self, ref_layer: int, start_pos_of_ref_layer: int): def __init__(self, ref_layer: int, start_pos_of_ref_layer: int):
@ -154,11 +157,11 @@ class OperDataPayload(object):
self.m_OpGuid: str = v.op_guid self.m_OpGuid: str = v.op_guid
self.m_Parent: int = v.parent self.m_Parent: int = v.parent
class OperTreeNode(ICanComputeSize): class OperTreeNode(ICanManipulate):
def __init__(self, payload: OperDataPayload): def __init__(self, payload: OperDataPayload):
self.m_Payload: OperDataPayload = payload self.m_Payload: OperDataPayload = payload
class BBTreeNode(ICanComputeSize): class BBTreeNode(ICanManipulate):
def __init__(self, payload: BBDataPayload): def __init__(self, payload: BBDataPayload):
self.m_UpperOper: TreeLayout[OperTreeNode] = TreeLayout() self.m_UpperOper: TreeLayout[OperTreeNode] = TreeLayout()
self.m_LowerOper: TreeLayout[OperTreeNode] = TreeLayout() self.m_LowerOper: TreeLayout[OperTreeNode] = TreeLayout()
@ -167,8 +170,19 @@ class BBTreeNode(ICanComputeSize):
self.m_Payload: BBDataPayload = payload self.m_Payload: BBDataPayload = payload
class GraphWork(ICanComputeSize): class GraphResult(ICanManipulate):
def __init__(self): def __init__(self):
self.m_GraphCKID: int = 0
self.m_BlockDict: dict[int, ICanManipulate] = {}
self.m_CellDict: dict[int, ICanManipulate] = {}
self.m_ParticleDict: dict[int, ICanManipulate] = {}
self.m_bIn: collections.deque = collections.deque()
self.m_bOut: collections.deque = collections.deque()
self.m_pIn: collections.deque = collections.deque()
self.m_pOut: collections.deque = collections.deque()
self.m_PassiveVal: collections.deque = collections.deque() self.m_PassiveVal: collections.deque = collections.deque()
self.m_PassiveOper: TreeLayout[OperTreeNode] = TreeLayout() self.m_PassiveOper: TreeLayout[OperTreeNode] = TreeLayout()
self.m_ActiveBB: TreeLayout[BBTreeNode] = TreeLayout() self.m_ActiveBB: TreeLayout[BBTreeNode] = TreeLayout()