SuperScriptMaterializer/SuperScriptDecorator/DecoratorBB.py

142 lines
6.1 KiB
Python
Raw Normal View History

2023-02-22 10:23:05 +08:00
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()
2023-02-21 22:27:38 +08:00
class BlocksFactory(object):
def __init__(self, db: sqlite3.Connection, graph: int):
# assign members
self.m_GraphCKID: int = graph
self.m_Db: sqlite3.Connection = db
self.__Cursor: sqlite3.Cursor = db.cursor()
self.m_BBDict: dict[int, DecoratorData.BBTreeNode] = {}
self.m_OperDict: dict[int, DecoratorData.OperTreeNode] = {}
self.__AllBB: 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
self.__FillDataFromDb()
2023-02-22 10:23:05 +08:00
# proc each data
self.__ProcActiveBB()
self.__ProcPassiveBB()
self.__ProcPassiveOper()
2023-02-21 22:27:38 +08:00
def __GetOneFromSet(self, vals: set[int]) -> int:
return next(iter(vals))
def __FillDataFromDb(self):
self.__Cursor.execute('SELECT * FROM [script_behavior] WHERE parent == ?', (self.m_GraphCKID, ))
for sqldata in self.__Cursor.fetchall():
payload: DecoratorData.BBDataPayload = DecoratorData.BBDataPayload(sqldata)
self.m_BBDict[payload.m_CKID] = DecoratorData.BBTreeNode(payload)
self.__AllBB.add(payload.m_CKID)
self.__Cursor.execute('SELECT * FROM [script_pOper] WHERE parent == ?', (self.m_GraphCKID, ))
for sqldata in self.__Cursor.fetchall():
payload: DecoratorData.OperDataPayload = DecoratorData.OperDataPayload(sqldata)
self.m_OperDict[payload.m_CKID] = DecoratorData.OperTreeNode(payload)
self.__AllOper.add(payload.m_CKID)
2023-02-22 10:23:05 +08:00
def __FindBBBottomOperRoot(self, start_pOut: int) -> tuple[int]:
pass
def __BuildOper(self, tree: DecoratorData.TreeLayout, start_oper: int):
2023-02-21 22:27:38 +08:00
pass
2023-02-22 10:23:05 +08:00
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