diff --git a/SuperScriptDecorator/DecoratorBB.py b/SuperScriptDecorator/DecoratorBB.py index 4784198..e6ebaa2 100644 --- a/SuperScriptDecorator/DecoratorBB.py +++ b/SuperScriptDecorator/DecoratorBB.py @@ -1,5 +1,12 @@ -import sqlite3 -import DecoratorData +import sqlite3, collections +import DecoratorData, DecoratorConst + +class IntermediateTreeNode(object): + def __init__(self): + self.m_FirstVisit: bool = True + self.m_LoactedLayer: int = DecoratorData.TreeLayout.NO_REFERENCE_LAYER + self.m_LocatedPos: int = DecoratorData.TreeLayout.NO_START_POS_OF_REF_LAYER + self.m_Collection: collections.deque[int] = collections.deque() class BlocksFactory(object): def __init__(self, db: sqlite3.Connection, graph: int): @@ -20,6 +27,12 @@ class BlocksFactory(object): # fill data first self.__FillDataFromDb() + # proc each data + self.__ProcActiveBB() + self.__ProcPassiveBB() + self.__ProcPassiveOper() + + def __GetOneFromSet(self, vals: set[int]) -> int: return next(iter(vals)) @@ -36,6 +49,93 @@ class BlocksFactory(object): self.m_OperDict[payload.m_CKID] = DecoratorData.OperTreeNode(payload) self.__AllOper.add(payload.m_CKID) - def __BuildBB(self, tree: DecoratorData.TreeLayout, start_io: tuple[int]): + def __FindBBBottomOperRoot(self, start_pOut: int) -> tuple[int]: pass + def __BuildOper(self, tree: DecoratorData.TreeLayout, start_oper: int): + pass + + def __BuildBB(self, tree: DecoratorData.TreeLayout, start_bb: int): + # prepare stack and start condition + stack: collections.deque[IntermediateTreeNode] = collections.deque() + + # check whether this BB has been processed + if start_bb not in self.__AllBB: + return + self.__AllBB.remove(start_bb) + + # 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_BBDict[start_bb]) + + # prepare stack data + start_bb_data: IntermediateTreeNode = IntermediateTreeNode() + start_bb_data.m_LoactedLayer = tree.GetCurrentLayerIndex() + 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;", + (start_bb, DecoratorConst.Database_bLink_InputOutputType.OUTPUT, self.m_GraphCKID, ) + ) + for (output_obj, ) in self.__Cursor.fetchall(): + start_bb_data.m_Collection.append(output_obj) + stack.append(start_bb_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 BB from collection. + # check whether it need process + bb_id: int = stack_entry.m_Collection[-1] + if bb_id not in self.__AllBB: + stack_entry.m_Collection.pop() + continue + self.__AllBB.remove(bb_id) + + # get corresponding tree node + tree_node = self.m_BBDict[bb_id] + + # start proc BB + # create new stack entry + bb_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) + + bb_data.m_LoactedLayer = stack_entry.m_LoactedLayer + bb_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) + + bb_data.m_LoactedLayer = tree.GetCurrentLayerIndex() + bb_data.m_LocatedPos = tree.GetCurrentItemIndex() + # 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;", + (bb_id, DecoratorConst.Database_bLink_InputOutputType.OUTPUT, self.m_GraphCKID, ) + ) + for (output_obj, ) in self.__Cursor.fetchall(): + bb_data.m_Collection.append(output_obj) + stack.append(bb_data) + + # todo: executing oper finder for current bb + + 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;", + (self.m_GraphCKID, DecoratorConst.Database_bLink_InputOutputType.INPUT, self.m_GraphCKID, ) + ) + for (output_obj, ) in self.__Cursor.fetchall(): + self.__BuildBB(self.m_ActiveBBLayer, output_obj) + + def __ProcPassiveBB(self): + while len(self.__AllBB) != 0: + self.__BuildBB(self.m_PassiveBBLayer, self.__GetOneFromSet(self.__AllBB)) + + def __ProcPassiveOper(self): + pass diff --git a/SuperScriptDecorator/DecoratorConst.py b/SuperScriptDecorator/DecoratorConst.py new file mode 100644 index 0000000..b24f0f7 --- /dev/null +++ b/SuperScriptDecorator/DecoratorConst.py @@ -0,0 +1,11 @@ + +class Database_bLink_InputOutputType(object): + INPUT = 0 + OUTPUT = 1 + +class Database_pLink_InputOutputType(object): + PIN = 0 + POUT = 1 + PLOCAL = 2 + PTARGET = 3 + PATTR = 4 diff --git a/SuperScriptDecorator/DecoratorData.py b/SuperScriptDecorator/DecoratorData.py index 0b8df39..cd037e7 100644 --- a/SuperScriptDecorator/DecoratorData.py +++ b/SuperScriptDecorator/DecoratorData.py @@ -96,11 +96,22 @@ class TreeLayoutLayer(typing.Generic[TNode]): class TreeLayout(typing.Generic[TNode]): NO_REFERENCE_LAYER: int = -1 + NO_START_POS_OF_REF_LAYER: int = -1 def __init__(self): self.m_Layers: collections.deque[TreeLayoutLayer[TNode]] = collections.deque() self.__CurrentLayer: TreeLayoutLayer[TNode] = None + def GetCurrentLayerIndex(self) -> int: + if self.__CurrentLayer is None: raise Exception("No layer!") + return len(self.m_Layers) - 1 + + def GetCurrentItemIndex(self) -> int: + if self.__CurrentLayer is None: raise Exception("No layer!") + result = len(self.__CurrentLayer) + if result == 0: raise Exception("No item!") + return result - 1 + def NewLayer(self, ref_layer: int, start_pos_of_ref_layer: int): self.__CurrentLayer = TreeLayoutLayer(ref_layer, start_pos_of_ref_layer) self.m_Layers.append(self.__CurrentLayer)