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 ]:
2023-02-21 22:27:38 +08:00
pass
2023-02-22 10:23:05 +08:00
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