fix a SSMat sqlite3 fatal error. promote decorator
This commit is contained in:
		
							
								
								
									
										0
									
								
								SuperScriptDecorator/DecoratorBB.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								SuperScriptDecorator/DecoratorBB.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										710
									
								
								SuperScriptDecorator/DecoratorCore.old.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										710
									
								
								SuperScriptDecorator/DecoratorCore.old.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,710 @@
 | 
			
		||||
import sqlite3
 | 
			
		||||
import DecoratorConstValue as dcv
 | 
			
		||||
import json
 | 
			
		||||
import CustomConfig
 | 
			
		||||
import Progressbar
 | 
			
		||||
 | 
			
		||||
def run():
 | 
			
		||||
    exportDb = sqlite3.connect(CustomConfig.export_db)
 | 
			
		||||
    exportDb.text_factory = lambda x: x.decode(CustomConfig.database_encoding, errors="ignore")
 | 
			
		||||
    decorateDb = sqlite3.connect(CustomConfig.decorated_db)
 | 
			
		||||
 | 
			
		||||
    # init table
 | 
			
		||||
    print('Init decorate database...')
 | 
			
		||||
    initDecorateDb(decorateDb)
 | 
			
		||||
    decorateDb.commit()
 | 
			
		||||
 | 
			
		||||
    # decorate graph
 | 
			
		||||
    print('Generating gragh list...')
 | 
			
		||||
    graphList = []
 | 
			
		||||
    decorateGraph(exportDb, decorateDb, graphList)
 | 
			
		||||
 | 
			
		||||
    # decorate each graph
 | 
			
		||||
    print('Generating graph...')
 | 
			
		||||
    currentGraphBlockCell = {}
 | 
			
		||||
    Progressbar.initProgressbar(len(graphList))
 | 
			
		||||
    for i in graphList:
 | 
			
		||||
        currentGraphBlockCell.clear()
 | 
			
		||||
        buildBlock(exportDb, decorateDb, i, currentGraphBlockCell)
 | 
			
		||||
        graphPIO = buildCell(exportDb, decorateDb, i, currentGraphBlockCell)
 | 
			
		||||
        buildLink(exportDb, decorateDb, i, currentGraphBlockCell, graphPIO)
 | 
			
		||||
 | 
			
		||||
        Progressbar.stepProgressbar()
 | 
			
		||||
    Progressbar.finProgressbar()
 | 
			
		||||
 | 
			
		||||
    # export information
 | 
			
		||||
    print('Generating info...')
 | 
			
		||||
    buildInfo(exportDb, decorateDb)
 | 
			
		||||
 | 
			
		||||
    # give up all change of eexport.db (because no change)
 | 
			
		||||
    exportDb.close()
 | 
			
		||||
    decorateDb.commit()
 | 
			
		||||
    decorateDb.close()
 | 
			
		||||
 | 
			
		||||
def initDecorateDb(db):
 | 
			
		||||
    cur = db.cursor()
 | 
			
		||||
    cur.execute("CREATE TABLE graph([graph] INTEGER, [graph_name] TEXT, [width] INTEGER, [height] INTEGER, [index] INTEGER, [belong_to] TEXT);")
 | 
			
		||||
    cur.execute("CREATE TABLE info([target] INTEGER, [attach_bb] INTEGER, [is_setting] INTEGER, [name] TEXT, [field] TEXT, [data] TEXT);")
 | 
			
		||||
 | 
			
		||||
    cur.execute("CREATE TABLE block([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [pin-ptarget] TEXT, [pin-pin] TEXT, [pin-pout] TEXT, [pin-bin] TEXT, [pin-bout] TEXT, [x] REAL, [y] REAL, [width] REAL, [height] REAL, [expandable] INTEGER);")
 | 
			
		||||
    cur.execute("CREATE TABLE cell([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [x] REAL, [y] REAL, [type] INTEGER);")
 | 
			
		||||
    cur.execute("CREATE TABLE link([belong_to_graph] INETGER, [delay] INTEGER, [start_interface] INTEGER, [end_interface] INTEGER, [startobj] INTEGER, [endobj] INTEGER, [start_type] INTEGER, [end_type] INTEGER, [start_index] INTEGER, [end_index] INTEGER, [x1] REAL, [y1] REAL, [x2] REAL, [y2] REAL);")
 | 
			
		||||
 | 
			
		||||
def decorateGraph(exDb, deDb, graph):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
    scriptMap = {}
 | 
			
		||||
 | 
			
		||||
    exCur.execute("SELECT [behavior], [index], [name] FROM script;")
 | 
			
		||||
    while True:
 | 
			
		||||
        lines = exCur.fetchone()
 | 
			
		||||
        if lines == None:
 | 
			
		||||
            break
 | 
			
		||||
        scriptMap[lines[0]] = (lines[1], lines[2])
 | 
			
		||||
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [type], [name] FROM behavior WHERE [type] != 0;")
 | 
			
		||||
    while True:
 | 
			
		||||
        lines = exCur.fetchone()
 | 
			
		||||
        if lines == None:
 | 
			
		||||
            break
 | 
			
		||||
 | 
			
		||||
        # add into global graph list
 | 
			
		||||
        graph.append(lines[0])
 | 
			
		||||
 | 
			
		||||
        # width and height will be computed by following method and use update
 | 
			
		||||
        # statement to change it
 | 
			
		||||
        if lines[1] == 1:
 | 
			
		||||
            # script
 | 
			
		||||
            deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, ?, ?)", (lines[0], lines[2], scriptMap[lines[0]][0], scriptMap[lines[0]][1]))
 | 
			
		||||
        else:
 | 
			
		||||
            # sub bb
 | 
			
		||||
            deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, -1, '')", (lines[0], lines[2]))
 | 
			
		||||
 | 
			
		||||
def buildBlock(exDb, deDb, target, currentGraphBlockCell):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
 | 
			
		||||
    # sort inner bb
 | 
			
		||||
    # use current graph input as the start point
 | 
			
		||||
    treeRoot = dcv.BBTreeNode(target, -1)
 | 
			
		||||
    processedBB = set()
 | 
			
		||||
    # layer start from 2, 0 is occupied for pLocal, 1 is occupied for pOper
 | 
			
		||||
    arrangedLayer = recursiveBuildBBTree(treeRoot, exCur, processedBB, 2, 0, target)
 | 
			
		||||
    
 | 
			
		||||
    # get no linked bb and place them.  linked bb position will be computed
 | 
			
		||||
    # following
 | 
			
		||||
    # calc each bb's x postion, as for y, calc later
 | 
			
		||||
    # flat bb tree
 | 
			
		||||
    arrangedLayer+=1
 | 
			
		||||
    singleBB = set()
 | 
			
		||||
    bbResult = {}
 | 
			
		||||
    bb_layer_map = {}
 | 
			
		||||
    baseX = dcv.GRAPH_CONTENTOFFSET_X
 | 
			
		||||
    exCur.execute('SELECT [thisobj], [name], [type], [proto_name], [pin_count] FROM behavior WHERE parent == ?', (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        pinSplit = i[4].split(',')
 | 
			
		||||
        bbCache = dcv.BBResult(i[1], i[3], pinSplit[1], pinSplit[2], pinSplit[3], pinSplit[4], (i[0] if i[2] != 0 else -1))
 | 
			
		||||
        bbCache.computSize()
 | 
			
		||||
        if i[0] not in processedBB:
 | 
			
		||||
            # single bb, process it
 | 
			
		||||
            singleBB.add(i[0])
 | 
			
		||||
            bbCache.x = baseX
 | 
			
		||||
            baseX += bbCache.width + dcv.GRAPH_BB_SPAN
 | 
			
		||||
            bb_layer_map[i[0]] = arrangedLayer
 | 
			
		||||
 | 
			
		||||
        bbResult[i[0]] = bbCache
 | 
			
		||||
 | 
			
		||||
    recursiveCalcBBX(treeRoot, dcv.GRAPH_CONTENTOFFSET_X, bbResult, bb_layer_map)
 | 
			
		||||
 | 
			
		||||
    # calc poper
 | 
			
		||||
    allBB = processedBB | singleBB
 | 
			
		||||
    processedOper = set()
 | 
			
		||||
    pluggedOper = {}
 | 
			
		||||
    occupiedLayerCountForSpecificBB = {}
 | 
			
		||||
    exCur.execute('SELECT [thisobj] FROM pOper WHERE [belong_to] == ?', (target,))
 | 
			
		||||
    newCur = exDb.cursor()
 | 
			
		||||
    newCur2 = exDb.cursor()
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[0] in processedOper:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        # check current bout, plugin into the first bb
 | 
			
		||||
        newCur.execute("SELECT [output_obj] FROM pLink WHERE ([input_obj] == ? AND [output_type] == ? AND [output_is_bb] == 1)", (i[0], dcv.dbPLinkInputOutputType.PIN))
 | 
			
		||||
        for j in newCur.fetchall():
 | 
			
		||||
            if j[0] in allBB:
 | 
			
		||||
                # can be plugin
 | 
			
		||||
                # try get tree
 | 
			
		||||
                if j[0] not in pluggedOper.keys():
 | 
			
		||||
                    pluggedOper[j[0]] = {}
 | 
			
		||||
                recursiveBuildOperTree(i[0], bb_layer_map, processedOper, occupiedLayerCountForSpecificBB, newCur2, 1, j[0], target, pluggedOper[j[0]])
 | 
			
		||||
                # exit for due to have found a proper host bb
 | 
			
		||||
                break
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
    # calc layer position
 | 
			
		||||
    layer_height = {}
 | 
			
		||||
    layer_y = {}
 | 
			
		||||
    layer_height[0] = 25
 | 
			
		||||
    layer_height[1] = 50
 | 
			
		||||
    for i in bb_layer_map.keys():
 | 
			
		||||
        curLayer = bb_layer_map[i]
 | 
			
		||||
        if curLayer not in layer_height.keys():
 | 
			
		||||
            layer_height[curLayer] = bbResult[i].height
 | 
			
		||||
        else:
 | 
			
		||||
            layer_height[curLayer] = max(layer_height.get(curLayer, 0), bbResult[i].height)
 | 
			
		||||
    layer_height[arrangedLayer] = layer_height.get(arrangedLayer, 0) # make sure misc bb height exist
 | 
			
		||||
    layer_height[2] = layer_height.get(2, 0)    # make sure at least have a bb layer (when there are no bb in a map)
 | 
			
		||||
 | 
			
		||||
    # calc bb Y
 | 
			
		||||
    baseY = dcv.GRAPH_CONTENTOFFSET_Y
 | 
			
		||||
    for i in range(arrangedLayer + 1):
 | 
			
		||||
        baseY += layer_height[i] + dcv.GRAPH_LAYER_SPAN
 | 
			
		||||
        baseY += occupiedLayerCountForSpecificBB.get(i, 0) * dcv.GRAPH_SPAN_BB_POPER    # add oper occipation
 | 
			
		||||
        layer_y[i] = baseY
 | 
			
		||||
    for i in bbResult.keys():
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        layer = bb_layer_map[i]
 | 
			
		||||
        cache.y = layer_y[layer] - layer_height[layer]
 | 
			
		||||
 | 
			
		||||
    # calc oper position
 | 
			
		||||
    # flat oper tree
 | 
			
		||||
    operResult = {}
 | 
			
		||||
    exCur.execute('SELECT [thisobj], [op] FROM pOper WHERE [belong_to] == ?', (target,))
 | 
			
		||||
    homelessOperCurrentX = dcv.GRAPH_CONTENTOFFSET_X
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[0] not in processedOper:
 | 
			
		||||
            # homeless oper
 | 
			
		||||
            cache2 = dcv.OperResult(i[1])
 | 
			
		||||
            cache2.computSize()
 | 
			
		||||
            cache2.x = homelessOperCurrentX
 | 
			
		||||
            cache2.y = layer_y[1] - cache2.height
 | 
			
		||||
            homelessOperCurrentX += cache2.width + dcv.GRAPH_BB_SPAN
 | 
			
		||||
            operResult[i[0]] = cache2
 | 
			
		||||
 | 
			
		||||
    for i in pluggedOper.keys():   # plugged oper
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        for j in pluggedOper[i]:
 | 
			
		||||
            jCache = pluggedOper[i][j]
 | 
			
		||||
            baseX = cache.x
 | 
			
		||||
            for q in jCache:
 | 
			
		||||
                exCur.execute("SELECT [op] FROM pOper WHERE [thisobj] == ?", (q,))
 | 
			
		||||
                cache2 = dcv.OperResult(exCur.fetchone()[0])
 | 
			
		||||
                cache2.computSize()
 | 
			
		||||
                cache2.x = baseX
 | 
			
		||||
                baseX += cache2.width + dcv.GRAPH_BB_SPAN
 | 
			
		||||
                cache2.y = cache.y - j * dcv.GRAPH_SPAN_BB_POPER
 | 
			
		||||
                operResult[q] = cache2
 | 
			
		||||
 | 
			
		||||
    # query bb pin's data
 | 
			
		||||
    listCache = []
 | 
			
		||||
    listItemCache = None
 | 
			
		||||
    for i in allBB:
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pTarget WHERE [belong_to] == ?;", (i,))
 | 
			
		||||
        temp = exCur.fetchone()
 | 
			
		||||
        if temp == None:
 | 
			
		||||
            cache.ptargetData = '{}'
 | 
			
		||||
        else:
 | 
			
		||||
            cache.ptargetData = json.dumps(dcv.PinInformation(temp[0], temp[1], temp[2]), cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name] FROM bIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], '')
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.binData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name] FROM bOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], '')
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.boutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.pinData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.poutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
    # query oper pin's data
 | 
			
		||||
    for i in operResult.keys():
 | 
			
		||||
        cache = operResult[i]
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.pinData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.poutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
    # write to database and return
 | 
			
		||||
    for i in bbResult.keys():
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        currentGraphBlockCell[i] = dcv.BlockCellItem(cache.x, cache.y, cache.width, cache.height)
 | 
			
		||||
        deCur.execute('INSERT INTO block VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
 | 
			
		||||
                      (target, i, cache.name, cache.assistName, cache.ptargetData, cache.pinData, cache.poutData, cache.binData, cache.boutData, cache.x, cache.y, cache.width, cache.height, cache.expandable))
 | 
			
		||||
    for i in operResult.keys():
 | 
			
		||||
        cache = operResult[i]
 | 
			
		||||
        currentGraphBlockCell[i] = dcv.BlockCellItem(cache.x, cache.y, cache.width, cache.height)
 | 
			
		||||
        deCur.execute("INSERT INTO block VALUES (?, ?, ?, '', '{}', ?, ?, '[]', '[]', ?, ?, ?, ?, -1)",
 | 
			
		||||
                      (target, i, cache.name, cache.pinData, cache.poutData, cache.x, cache.y, cache.width, cache.height))
 | 
			
		||||
 | 
			
		||||
def recursiveBuildBBTree(node, exCur, processedBB, layer, depth, graphId):
 | 
			
		||||
    realLinkedBB = set()
 | 
			
		||||
    # find links
 | 
			
		||||
    exCur.execute("SELECT [output_obj] FROM bLink WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;",
 | 
			
		||||
                  (node.bb, (dcv.dbBLinkInputOutputType.INPUT if depth == 0 else dcv.dbBLinkInputOutputType.OUTPUT), graphId))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[0] != graphId: # omit self
 | 
			
		||||
            realLinkedBB.add(i[0])
 | 
			
		||||
 | 
			
		||||
    if (len(realLinkedBB) == 0):
 | 
			
		||||
        return layer
 | 
			
		||||
 | 
			
		||||
    # ignore duplicated bb
 | 
			
		||||
    # calc need processed bb first
 | 
			
		||||
    # and register all gotten bb.  for preventing infinity resursive func and
 | 
			
		||||
    # keep bb tree structure
 | 
			
		||||
    realLinkedBB = realLinkedBB - processedBB
 | 
			
		||||
    processedBB.update(realLinkedBB)
 | 
			
		||||
 | 
			
		||||
    # iterate each bb
 | 
			
		||||
    for i in realLinkedBB:
 | 
			
		||||
        # recursive execute this method
 | 
			
		||||
        newNode = dcv.BBTreeNode(i, layer)
 | 
			
		||||
        layer = recursiveBuildBBTree(newNode, exCur, processedBB, layer, depth + 1, graphId)
 | 
			
		||||
        # add new node into list and ++layer
 | 
			
		||||
        layer+=1
 | 
			
		||||
        node.nodes.append(newNode)
 | 
			
		||||
 | 
			
		||||
    # minus extra ++ due to for
 | 
			
		||||
    if (len(realLinkedBB) != 0):
 | 
			
		||||
        layer-=1
 | 
			
		||||
    
 | 
			
		||||
    return layer
 | 
			
		||||
 | 
			
		||||
def recursiveCalcBBX(node, baseX, resultList, layerMap):
 | 
			
		||||
    maxExpand = 0
 | 
			
		||||
    for i in node.nodes:
 | 
			
		||||
        layerMap[i.bb] = i.layer
 | 
			
		||||
        resultList[i.bb].x = baseX
 | 
			
		||||
        maxExpand = max(maxExpand, resultList[i.bb].width)
 | 
			
		||||
 | 
			
		||||
    for i in node.nodes:
 | 
			
		||||
        recursiveCalcBBX(i, baseX + maxExpand + dcv.GRAPH_BB_SPAN, resultList, layerMap)
 | 
			
		||||
 | 
			
		||||
def recursiveBuildOperTree(oper, bb_layer_map, processedOper, occupiedLayerMap, exCur, sublayer, bb, graphId, subLayerColumnMap):
 | 
			
		||||
    if oper in processedOper:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # for avoid fucking export parameter feature.  check whether self is
 | 
			
		||||
    # current graph's memeber
 | 
			
		||||
    exCur.execute("SELECT [belong_to] FROM pOper WHERE [thisobj] == ?;", (oper,))
 | 
			
		||||
    if (exCur.fetchone()[0] != graphId):
 | 
			
		||||
        # fuck export param, exit
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # make sure sub layer column map is ok
 | 
			
		||||
    if sublayer not in subLayerColumnMap.keys():
 | 
			
		||||
        subLayerColumnMap[sublayer] = []
 | 
			
		||||
 | 
			
		||||
    # register self
 | 
			
		||||
    # mark processed
 | 
			
		||||
    processedOper.add(oper)
 | 
			
		||||
    subLayerColumnMap[sublayer].append(oper)
 | 
			
		||||
 | 
			
		||||
    # record layer occupation
 | 
			
		||||
    layer = bb_layer_map[bb]
 | 
			
		||||
    occupiedLayerMap[layer] = max(occupiedLayerMap.get(layer, -1), sublayer)
 | 
			
		||||
 | 
			
		||||
    # iterate sub item
 | 
			
		||||
    exCur.execute("SELECT [input_obj] FROM pLink WHERE ([output_obj] == ? AND [input_type] == ? AND [input_is_bb] == 0) ORDER BY [output_index];", (oper, dcv.dbPLinkInputOutputType.POUT))
 | 
			
		||||
    res = []
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        res.append(i[0])
 | 
			
		||||
 | 
			
		||||
    for i in res:
 | 
			
		||||
        recursiveBuildOperTree(i, bb_layer_map, processedOper, occupiedLayerMap, exCur, sublayer + 1, bb, graphId, subLayerColumnMap)
 | 
			
		||||
 | 
			
		||||
def buildCell(exDb, deDb, target, currentGraphBlockCell):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
    # prepare block set
 | 
			
		||||
    blockSet = set()
 | 
			
		||||
    for i in currentGraphBlockCell.keys():
 | 
			
		||||
        blockSet.add(i)
 | 
			
		||||
 | 
			
		||||
    # find current graph's pio bio
 | 
			
		||||
    boutx = set()
 | 
			
		||||
    pouty = set()
 | 
			
		||||
    graphPIO = set()
 | 
			
		||||
 | 
			
		||||
    # bOut.x and pOut.y data is not confirmed, when graph size was confirmed,
 | 
			
		||||
    # update it
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index] FROM bIn WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = 0
 | 
			
		||||
        y = dcv.GRAPH_BOFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_BSPAN)
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, '', ?, ?, ?)", (target, i[0], i[1], x, y, dcv.CellType.BIO))
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index] FROM bOut WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = 0
 | 
			
		||||
        y = dcv.GRAPH_BOFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_BSPAN)
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, '', ?, ?, ?)", (target, i[0], i[1], x, y, dcv.CellType.BIO))
 | 
			
		||||
        boutx.add(i[0])
 | 
			
		||||
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index], [type] FROM pIn WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = dcv.GRAPH_POFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_PSPAN)
 | 
			
		||||
        y = 0
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)", (target, i[0], i[1], i[3], x, y, dcv.CellType.PIO))
 | 
			
		||||
        graphPIO.add(i[0])
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index], [type] FROM pOut WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = dcv.GRAPH_POFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_PSPAN)
 | 
			
		||||
        y = 0
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)", (target, i[0], i[1], i[3], x, y, dcv.CellType.PIO))
 | 
			
		||||
        graphPIO.add(i[0])
 | 
			
		||||
        pouty.add(i[0])
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [type] FROM pTarget WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    cache = exCur.fetchone()
 | 
			
		||||
    if cache != None:
 | 
			
		||||
        currentGraphBlockCell[cache[0]] = dcv.BlockCellItem(0, 0, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, 0, 0, ?)", (target, i[0], i[1], i[2], dcv.CellType.PTARGET))
 | 
			
		||||
        graphPIO.add(cache[0])
 | 
			
		||||
 | 
			
		||||
    # query all plocal
 | 
			
		||||
    allLocal = set()
 | 
			
		||||
    localUsageCounter = {}
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [type] FROM pLocal WHERE [belong_to] == ?;", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        allLocal.add(i[0])
 | 
			
		||||
        localUsageCounter[i[0]] = dcv.LocalUsageItem(0, False, dcv.LocalUsageType.PLOCAL)
 | 
			
		||||
 | 
			
		||||
    # query all links(don't need to consider export pIO, due to it will not add
 | 
			
		||||
    # any shortcut)
 | 
			
		||||
    # !!  the same if framework in pLink generator function !!  SHARED
 | 
			
		||||
    createdShortcut = set()
 | 
			
		||||
    exCur.execute("SELECT * FROM pLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
 | 
			
		||||
        # analyse 5 chancee one by one
 | 
			
		||||
        if (i[7] == dcv.dbPLinkInputOutputType.PTARGET or i[7] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
            if (i[3] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                if i[2] in allLocal or i[2] in createdShortcut:
 | 
			
		||||
                    cache = localUsageCounter[i[2]]
 | 
			
		||||
                else:
 | 
			
		||||
                    cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PLOCAL)
 | 
			
		||||
                    localUsageCounter[i[2]] = cache
 | 
			
		||||
                    createdShortcut.add(i[2])
 | 
			
		||||
 | 
			
		||||
                cache.count += 1
 | 
			
		||||
                cache.lastUse = i[6]
 | 
			
		||||
                cache.lastDirection = 0
 | 
			
		||||
                cache.lastIndex = i[9]
 | 
			
		||||
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
                if i[2] == target:
 | 
			
		||||
                    continue    # ignore self pIn/pOut.  it doesn't need any shortcut
 | 
			
		||||
                if i[2] not in blockSet:
 | 
			
		||||
                    if i[0] not in createdShortcut:
 | 
			
		||||
                        cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PIN)
 | 
			
		||||
                        localUsageCounter[i[0]] = cache
 | 
			
		||||
                        createdShortcut.add(i[0])
 | 
			
		||||
                    else:
 | 
			
		||||
                        cache = localUsageCounter[i[0]]
 | 
			
		||||
 | 
			
		||||
                    cache.count+=1
 | 
			
		||||
                    cache.lastUse = i[6]
 | 
			
		||||
                    cache.lastDirection = 0
 | 
			
		||||
                    cache.lastIndex = i[9]
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PATTR):    # for attribute using
 | 
			
		||||
                if i[2] not in createdShortcut:
 | 
			
		||||
                    cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PATTR)
 | 
			
		||||
                    localUsageCounter[i[2]] = cache
 | 
			
		||||
                    createdShortcut.add(i[2])
 | 
			
		||||
                else:
 | 
			
		||||
                    cache = localUsageCounter[i[2]]
 | 
			
		||||
 | 
			
		||||
                    cache.count+=1
 | 
			
		||||
                    cache.lastUse = i[6]
 | 
			
		||||
                    cache.lastDirection = 0
 | 
			
		||||
                    cache.lastIndex = i[9]
 | 
			
		||||
            else:
 | 
			
		||||
                if i[2] not in blockSet:
 | 
			
		||||
                    if i[0] not in createdShortcut:
 | 
			
		||||
                        cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.POUT)
 | 
			
		||||
                        localUsageCounter[i[0]] = cache
 | 
			
		||||
                        createdShortcut.add(i[0])
 | 
			
		||||
                    else:
 | 
			
		||||
                        cache = localUsageCounter[i[0]]
 | 
			
		||||
 | 
			
		||||
                    cache.count+=1
 | 
			
		||||
                    cache.lastUse = i[6]
 | 
			
		||||
                    cache.lastDirection = 1
 | 
			
		||||
                    cache.lastIndex = i[9]
 | 
			
		||||
        else:
 | 
			
		||||
            if (i[7] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                if i[6] in allLocal or i[6] in createdShortcut:
 | 
			
		||||
                    cache = localUsageCounter[i[6]]
 | 
			
		||||
                else:
 | 
			
		||||
                    cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PLOCAL)
 | 
			
		||||
                    localUsageCounter[i[6]] = cache
 | 
			
		||||
                    createdShortcut.add(i[6])
 | 
			
		||||
 | 
			
		||||
                cache.count += 1
 | 
			
		||||
                cache.lastUse = i[2]
 | 
			
		||||
                cache.lastDirection = 1
 | 
			
		||||
                cache.lastIndex = i[5]
 | 
			
		||||
            else:
 | 
			
		||||
                if i[6] == target:
 | 
			
		||||
                    continue    # ignore self pIn/pOut.  it doesn't need any shortcut
 | 
			
		||||
                if i[6] not in blockSet:
 | 
			
		||||
                    if i[1] not in createdShortcut:
 | 
			
		||||
                        cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.POUT)
 | 
			
		||||
                        localUsageCounter[i[1]] = cache
 | 
			
		||||
                        createdShortcut.add(i[1])
 | 
			
		||||
                    else:
 | 
			
		||||
                        cache = localUsageCounter[i[1]]
 | 
			
		||||
 | 
			
		||||
                    cache.count += 1
 | 
			
		||||
                    cache.lastUse = i[2]
 | 
			
		||||
                    cache.lastDirection = 1
 | 
			
		||||
                    cache.lastIndex = i[5]
 | 
			
		||||
 | 
			
		||||
    # apply all cells
 | 
			
		||||
    defaultCellIndex = 0
 | 
			
		||||
    for i in localUsageCounter.keys():
 | 
			
		||||
        cache = localUsageCounter[i]
 | 
			
		||||
        # comput x,y
 | 
			
		||||
        if (cache.count == 1):
 | 
			
		||||
            # attachable
 | 
			
		||||
            attachTarget = currentGraphBlockCell[cache.lastUse]
 | 
			
		||||
            (x, y) = computCellPosition(attachTarget.x, attachTarget.y, attachTarget.h, cache.lastDirection, cache.lastIndex)
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            # place it in default area
 | 
			
		||||
            y = dcv.GRAPH_CONTENTOFFSET_Y
 | 
			
		||||
            x = dcv.GRAPH_CONTENTOFFSET_X + defaultCellIndex * (dcv.CELL_WIDTH + dcv.GRAPH_BB_SPAN)
 | 
			
		||||
            defaultCellIndex += 1
 | 
			
		||||
        # get information
 | 
			
		||||
        if (cache.internal_type == dcv.LocalUsageType.PIN):
 | 
			
		||||
            tableName = 'pIn'
 | 
			
		||||
        elif (cache.internal_type == dcv.LocalUsageType.POUT):
 | 
			
		||||
            tableName = 'pOut'
 | 
			
		||||
        elif (cache.internal_type == dcv.LocalUsageType.PATTR):
 | 
			
		||||
            tableName = 'pAttr'
 | 
			
		||||
        else:
 | 
			
		||||
            tableName = 'pLocal'
 | 
			
		||||
        exCur.execute("SELECT [name], [type] FROM {} WHERE [thisobj] == ?".format(tableName), (i,))
 | 
			
		||||
        temp = exCur.fetchone()
 | 
			
		||||
 | 
			
		||||
        # submit to database and map
 | 
			
		||||
        currentGraphBlockCell[i] = dcv.BlockCellItem(x, y, dcv.CELL_WIDTH, dcv.CELL_HEIGHT)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)",
 | 
			
		||||
                      (target, i, temp[0], temp[1], x, y, (dcv.CellType.SHORTCUT if cache.isshortcut else dcv.CellType.PLOCAL)))
 | 
			
		||||
 | 
			
		||||
    # comput size and update database and currentGraphBlockCell
 | 
			
		||||
    graphX = 0
 | 
			
		||||
    graphY = 0
 | 
			
		||||
    for key, values in currentGraphBlockCell.items():
 | 
			
		||||
        graphX = max(graphX, values.x + values.w)
 | 
			
		||||
        graphY = max(graphY, values.y + values.h)
 | 
			
		||||
    graphX += dcv.GRAPH_POFFSET
 | 
			
		||||
    graphY += dcv.GRAPH_BOFFSET
 | 
			
		||||
 | 
			
		||||
    deCur.execute("UPDATE graph SET [width] = ?, [height] = ? WHERE [graph] == ?", (graphX, graphY, target))
 | 
			
		||||
 | 
			
		||||
    # update bOut.x and pOut.y data
 | 
			
		||||
    for i in boutx:
 | 
			
		||||
        deCur.execute("UPDATE cell SET [x] = ? WHERE ([thisobj] == ? AND [belong_to_graph] == ?)", (graphX - dcv.BB_PBSIZE, i, target))
 | 
			
		||||
        currentGraphBlockCell[i].x = graphX - dcv.BB_PBSIZE
 | 
			
		||||
    for i in pouty:
 | 
			
		||||
        deCur.execute("UPDATE cell SET [y] = ? WHERE ([thisobj] == ? AND [belong_to_graph] == ?)", (graphY - dcv.BB_PBSIZE, i, target))
 | 
			
		||||
        currentGraphBlockCell[i].y = graphY - dcv.BB_PBSIZE
 | 
			
		||||
 | 
			
		||||
    return graphPIO
 | 
			
		||||
 | 
			
		||||
def computCellPosition(baseX, baseY, height, direction, index):
 | 
			
		||||
    if (index == -1):
 | 
			
		||||
        return (baseX, baseY - dcv.GRAPH_SPAN_BB_PLOCAL)
 | 
			
		||||
 | 
			
		||||
    if (direction == 0):
 | 
			
		||||
        return (baseX + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN), baseY - dcv.GRAPH_SPAN_BB_PLOCAL)
 | 
			
		||||
    else:
 | 
			
		||||
        return (baseX + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN), baseY + height + dcv.GRAPH_SPAN_BB_PLOCAL)
 | 
			
		||||
 | 
			
		||||
def buildLink(exDb, deDb, target, currentGraphBlockCell, graphPIO):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
 | 
			
		||||
    # prepare block set
 | 
			
		||||
    blockSet = set()
 | 
			
		||||
    for i in currentGraphBlockCell.keys():
 | 
			
		||||
        blockSet.add(i)
 | 
			
		||||
 | 
			
		||||
    # bLink
 | 
			
		||||
    exCur.execute("SELECT * FROM bLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[3] == target:
 | 
			
		||||
            (x1, y1) = computLinkBTerminal(i[0], 0, -1 ,currentGraphBlockCell)
 | 
			
		||||
            bStartObj = i[0]
 | 
			
		||||
            bStartType = 0
 | 
			
		||||
            bStartIndex = -1
 | 
			
		||||
        else:
 | 
			
		||||
            (x1, y1) = computLinkBTerminal(i[3], i[4], i[5], currentGraphBlockCell)
 | 
			
		||||
            bStartObj = i[3]
 | 
			
		||||
            bStartType = i[4]
 | 
			
		||||
            bStartIndex = i[5]
 | 
			
		||||
        if i[6] == target:
 | 
			
		||||
            (x2, y2) = computLinkBTerminal(i[1], 0, -1,currentGraphBlockCell)
 | 
			
		||||
            bEndObj = i[1]
 | 
			
		||||
            bEndType = 0
 | 
			
		||||
            bEndIndex = -1
 | 
			
		||||
        else:
 | 
			
		||||
            (x2, y2) = computLinkBTerminal(i[6], i[7], i[8],currentGraphBlockCell)
 | 
			
		||||
            bEndObj = i[6]
 | 
			
		||||
            bEndType = i[7]
 | 
			
		||||
            bEndIndex = i[8]
 | 
			
		||||
 | 
			
		||||
        deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                      (target, i[2], i[0], i[1], bStartObj, bEndObj, bStartType, bEndType, bStartIndex, bEndIndex, x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
    # pLink
 | 
			
		||||
    # !!  the same if framework in cell generator function !!  SHARED
 | 
			
		||||
    exCur.execute("SELECT * FROM pLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        # analyse 5 chancee one by one
 | 
			
		||||
        if (i[7] == dcv.dbPLinkInputOutputType.PTARGET or i[7] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
            if (i[3] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                if i[2] == target:
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[0], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
 | 
			
		||||
                else:
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[2], 0, i[5], currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[2], i[6], 0, 0, i[5], i[9], x1, y1, x2, y2))
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PATTR):
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
 | 
			
		||||
            else:
 | 
			
		||||
                if i[2] in blockSet:    # process protencial pOut(shortcut) (because plocal input/input_obj
 | 
			
		||||
                                        # output/output_obj is same, so don't need add for them)
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                else:
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[0], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 1, 0, i[5], i[9], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            if (i[7] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[1], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 1, 0, i[5], -1, x1, y1, x2, y2))
 | 
			
		||||
            else:
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                if i[6] == target:
 | 
			
		||||
                    (x2, y2) = computLinkPTerminal(i[1], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[2], i[1], 1, 0, i[5], -1, x1, y1, x2, y2))
 | 
			
		||||
                else:
 | 
			
		||||
                    (x2, y2) = computLinkPTerminal(i[6], 1, i[9], currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[2], i[6], 1, 1, i[5], i[9], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
    # eLink
 | 
			
		||||
    exCur.execute("SELECT * FROM eLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
        (x2, y2) = computLinkPTerminal(i[1], 0 if i[2] == 1 else 1, i[3], currentGraphBlockCell)
 | 
			
		||||
        deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                        (target, -2, i[0], i[0], target, i[1], 0, 0 if i[2] == 1 else 1, -1, i[3], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
def computLinkBTerminal(obj, xtype, index, currentGraphBlockCell):
 | 
			
		||||
    # index = -1 mean no offset, it will connect to graph io
 | 
			
		||||
    cache = currentGraphBlockCell[obj]
 | 
			
		||||
    return (cache.x if xtype == 0 else cache.x + cache.w - dcv.BB_PBSIZE,
 | 
			
		||||
            cache.y if index == -1 else (cache.y + dcv.BB_BOFFSET + index * (dcv.BB_PBSIZE + dcv.BB_BSPAN)))
 | 
			
		||||
 | 
			
		||||
def computLinkPTerminal(obj, ytype, index, currentGraphBlockCell):
 | 
			
		||||
    # ytype is not database type.  it have the same meaning of LinkBTerminal,
 | 
			
		||||
    # indicating the position.  0 is keep origin position(for pIn and pTarget),
 | 
			
		||||
    # 1 is consider height(for pOut)
 | 
			
		||||
    cache = currentGraphBlockCell[obj]
 | 
			
		||||
    return (cache.x if index == -1 else (cache.x + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN)), 
 | 
			
		||||
            cache.y if ytype == 0 else (cache.y + cache.h - dcv.BB_PBSIZE))
 | 
			
		||||
 | 
			
		||||
def buildInfo(exDb, deDb):
 | 
			
		||||
    exInfoCur = exDb.cursor()
 | 
			
		||||
    exQueryCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
 | 
			
		||||
    # declare tiny storage for convenient query
 | 
			
		||||
    tinyStorageKey = 0
 | 
			
		||||
    tinyStorageBB = -1
 | 
			
		||||
    tinyStorageSetting = 0
 | 
			
		||||
    tinyStorageName = ""
 | 
			
		||||
 | 
			
		||||
    # export local data (including proto bb internal data)
 | 
			
		||||
    exInfoCur.execute("SELECT * FROM pData;")
 | 
			
		||||
    for i in exInfoCur.fetchall():
 | 
			
		||||
        attachBB = -1
 | 
			
		||||
        isSetting = 0
 | 
			
		||||
        infoName = ""
 | 
			
		||||
 | 
			
		||||
        if i[2] == tinyStorageKey:
 | 
			
		||||
            attachBB = tinyStorageBB
 | 
			
		||||
            isSetting = tinyStorageSetting
 | 
			
		||||
            infotName = tinyStorageName
 | 
			
		||||
        else:
 | 
			
		||||
            # clear storage first
 | 
			
		||||
            tinyStorageBB = -1
 | 
			
		||||
            tinyStorageSetting = 0
 | 
			
		||||
            tinyStorageName = ""
 | 
			
		||||
 | 
			
		||||
            # query correspond pLocal
 | 
			
		||||
            exQueryCur.execute("SELECT [belong_to], [is_setting], [name] FROM pLocal WHERE [thisobj] = ?", (i[2], ))
 | 
			
		||||
            plocalCache = exQueryCur.fetchone()
 | 
			
		||||
            if plocalCache is not None:
 | 
			
		||||
                # add setting config
 | 
			
		||||
                tinyStorageSetting = isSetting = plocalCache[1]
 | 
			
		||||
                tinyStorageName = infoName = plocalCache[2]
 | 
			
		||||
                # query bb again
 | 
			
		||||
                exQueryCur.execute("SELECT [thisobj] FROM behavior WHERE ([thisobj] = ? AND [type] = 0)", (plocalCache[0], ))
 | 
			
		||||
                behaviorCache = exQueryCur.fetchone()
 | 
			
		||||
                if behaviorCache is not None:
 | 
			
		||||
                    tinyStorageBB = attachBB = behaviorCache[0]
 | 
			
		||||
 | 
			
		||||
        deCur.execute("INSERT INTO info VALUES (?, ?, ?, ?, ?, ?)", (i[2], attachBB, isSetting, infoName, i[0], i[1]))
 | 
			
		||||
@ -1,710 +1,93 @@
 | 
			
		||||
import sqlite3
 | 
			
		||||
import DecoratorConstValue as dcv
 | 
			
		||||
import json
 | 
			
		||||
import CustomConfig
 | 
			
		||||
import Progressbar
 | 
			
		||||
import sqlite3, json, collections
 | 
			
		||||
import CustomConfig, Progressbar
 | 
			
		||||
 | 
			
		||||
def run():
 | 
			
		||||
    exportDb = sqlite3.connect(CustomConfig.export_db)
 | 
			
		||||
    exportDb.text_factory = lambda x: x.decode(CustomConfig.database_encoding, errors="ignore")
 | 
			
		||||
    decorateDb = sqlite3.connect(CustomConfig.decorated_db)
 | 
			
		||||
class CompositionIngredients(object):
 | 
			
		||||
    def __init__(self, name: str, export_id: int, env_id: int):
 | 
			
		||||
        self.m_CompositionName: str = name
 | 
			
		||||
        self.m_ExportIndex = export_id
 | 
			
		||||
        self.m_EnvIndex = env_id
 | 
			
		||||
 | 
			
		||||
def _InitDecoratedDb(db: sqlite3.Connection):
 | 
			
		||||
    cur = db.cursor()
 | 
			
		||||
    cur.execute("CREATE TABLE [compositions] ([id] INTEGER, [name] TEXT, [export_id] INTEGER, [env_id] INTEGER);")
 | 
			
		||||
 | 
			
		||||
    cur.execute("CREATE TABLE graph([graph_ckid] INTEGER, [graph_name] TEXT, [hierarchy_ckid] TEXT, [export_id] INTEGER);")
 | 
			
		||||
    #cur.execute("CREATE TABLE info([target] INTEGER, [attach_bb] INTEGER, [is_setting] INTEGER, [name] TEXT, [field] TEXT, [data] TEXT);")
 | 
			
		||||
 | 
			
		||||
    #cur.execute("CREATE TABLE block([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [pin-ptarget] TEXT, [pin-pin] TEXT, [pin-pout] TEXT, [pin-bin] TEXT, [pin-bout] TEXT, [x] REAL, [y] REAL, [width] REAL, [height] REAL, [expandable] INTEGER);")
 | 
			
		||||
    #cur.execute("CREATE TABLE cell([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [x] REAL, [y] REAL, [type] INTEGER);")
 | 
			
		||||
    #cur.execute("CREATE TABLE link([belong_to_graph] INETGER, [delay] INTEGER, [start_interface] INTEGER, [end_interface] INTEGER, [startobj] INTEGER, [endobj] INTEGER, [start_type] INTEGER, [end_type] INTEGER, [start_index] INTEGER, [end_index] INTEGER, [x1] REAL, [y1] REAL, [x2] REAL, [y2] REAL);")
 | 
			
		||||
 | 
			
		||||
    db.commit()
 | 
			
		||||
    cur.close()
 | 
			
		||||
 | 
			
		||||
def _GenerateCompositions(cfg: CustomConfig.CustomConfig) -> tuple[tuple[CompositionIngredients], tuple[str], tuple[str]]:
 | 
			
		||||
    compositions: list[CompositionIngredients] = []
 | 
			
		||||
    exportdb: collections.OrderedDict = collections.OrderedDict()
 | 
			
		||||
    envdb: collections.OrderedDict = collections.OrderedDict()
 | 
			
		||||
 | 
			
		||||
    for entry in cfg.m_InputEntries:
 | 
			
		||||
        # check 2 database
 | 
			
		||||
        export_id = exportdb.get(entry.m_ExportDb, None)
 | 
			
		||||
        if export_id is None:
 | 
			
		||||
            export_id = len(exportdb)
 | 
			
		||||
            exportdb[entry.m_ExportDb] = export_id
 | 
			
		||||
 | 
			
		||||
        env_id = envdb.get(entry.m_EnvDb, None)
 | 
			
		||||
        if env_id is None:
 | 
			
		||||
            env_id = len(envdb)
 | 
			
		||||
            envdb[entry.m_EnvDb] = env_id
 | 
			
		||||
 | 
			
		||||
        # create record
 | 
			
		||||
        compositions.append(CompositionIngredients(entry.m_Name, export_id, env_id))
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        tuple(compositions), 
 | 
			
		||||
        tuple(exportdb.values()),
 | 
			
		||||
        tuple(envdb.values())
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
def _UploadComposition(db: sqlite3.Connection, compositions: list[CompositionIngredients]):
 | 
			
		||||
    cur = db.cursor()
 | 
			
		||||
    for idx, ingredient in enumerate(compositions):
 | 
			
		||||
        cur.execute("INSERT INTO [compositions] VALUES(?, ?, ?, ?)", 
 | 
			
		||||
            (idx, ingredient.m_CompositionName, ingredient.m_ExportIndex, ingredient.m_EnvIndex)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    db.commit()
 | 
			
		||||
    cur.close()
 | 
			
		||||
 | 
			
		||||
def Run(cfg: CustomConfig.CustomConfig):
 | 
			
		||||
    # establish target database
 | 
			
		||||
    print('Opening decorated database...')
 | 
			
		||||
    decorateDb: sqlite3.Connection = sqlite3.connect(cfg.m_DecoratedDb)
 | 
			
		||||
 | 
			
		||||
    # init table
 | 
			
		||||
    print('Init decorate database...')
 | 
			
		||||
    initDecorateDb(decorateDb)
 | 
			
		||||
    print('Initializing decorated database...')
 | 
			
		||||
    _InitDecoratedDb(decorateDb)
 | 
			
		||||
    decorateDb.commit()
 | 
			
		||||
 | 
			
		||||
    # decorate graph
 | 
			
		||||
    print('Generating gragh list...')
 | 
			
		||||
    graphList = []
 | 
			
		||||
    decorateGraph(exportDb, decorateDb, graphList)
 | 
			
		||||
    # we need know which database we need analyse first
 | 
			
		||||
    print('Generating compositions...')
 | 
			
		||||
    (compositions, exportdb, envdb) = _GenerateCompositions(cfg)
 | 
			
		||||
    _UploadComposition(decorateDb, compositions)
 | 
			
		||||
    print(f'Analysation done. {len(exportdb)} Export DB and {len(envdb)} Env DB.')
 | 
			
		||||
 | 
			
		||||
    # decorate each graph
 | 
			
		||||
    print('Generating graph...')
 | 
			
		||||
    currentGraphBlockCell = {}
 | 
			
		||||
    Progressbar.initProgressbar(len(graphList))
 | 
			
		||||
    for i in graphList:
 | 
			
		||||
        currentGraphBlockCell.clear()
 | 
			
		||||
        buildBlock(exportDb, decorateDb, i, currentGraphBlockCell)
 | 
			
		||||
        graphPIO = buildCell(exportDb, decorateDb, i, currentGraphBlockCell)
 | 
			
		||||
        buildLink(exportDb, decorateDb, i, currentGraphBlockCell, graphPIO)
 | 
			
		||||
    # process export
 | 
			
		||||
    print('Generating graphs...')
 | 
			
		||||
    progressbar: Progressbar.Prograssbar = Progressbar.Prograssbar(len(exportdb))
 | 
			
		||||
    for expid, exp in enumerate(exportdb):
 | 
			
		||||
        pass
 | 
			
		||||
    progressbar.Finish()
 | 
			
		||||
 | 
			
		||||
        Progressbar.stepProgressbar()
 | 
			
		||||
    Progressbar.finProgressbar()
 | 
			
		||||
    # process env
 | 
			
		||||
    print('Generating infos...')
 | 
			
		||||
    progressbar = Progressbar.Prograssbar(len(envdb))
 | 
			
		||||
    for envid, env in enumerate(envdb):
 | 
			
		||||
        pass
 | 
			
		||||
    progressbar.Finish()
 | 
			
		||||
 | 
			
		||||
    # export information
 | 
			
		||||
    print('Generating info...')
 | 
			
		||||
    buildInfo(exportDb, decorateDb)
 | 
			
		||||
 | 
			
		||||
    # give up all change of eexport.db (because no change)
 | 
			
		||||
    exportDb.close()
 | 
			
		||||
    # close database
 | 
			
		||||
    print('Closing decorated database...')
 | 
			
		||||
    decorateDb.commit()
 | 
			
		||||
    decorateDb.close()
 | 
			
		||||
 | 
			
		||||
def initDecorateDb(db):
 | 
			
		||||
    cur = db.cursor()
 | 
			
		||||
    cur.execute("CREATE TABLE graph([graph] INTEGER, [graph_name] TEXT, [width] INTEGER, [height] INTEGER, [index] INTEGER, [belong_to] TEXT);")
 | 
			
		||||
    cur.execute("CREATE TABLE info([target] INTEGER, [attach_bb] INTEGER, [is_setting] INTEGER, [name] TEXT, [field] TEXT, [data] TEXT);")
 | 
			
		||||
 | 
			
		||||
    cur.execute("CREATE TABLE block([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [pin-ptarget] TEXT, [pin-pin] TEXT, [pin-pout] TEXT, [pin-bin] TEXT, [pin-bout] TEXT, [x] REAL, [y] REAL, [width] REAL, [height] REAL, [expandable] INTEGER);")
 | 
			
		||||
    cur.execute("CREATE TABLE cell([belong_to_graph] INETGER, [thisobj] INTEGER, [name] TEXT, [assist_text] TEXT, [x] REAL, [y] REAL, [type] INTEGER);")
 | 
			
		||||
    cur.execute("CREATE TABLE link([belong_to_graph] INETGER, [delay] INTEGER, [start_interface] INTEGER, [end_interface] INTEGER, [startobj] INTEGER, [endobj] INTEGER, [start_type] INTEGER, [end_type] INTEGER, [start_index] INTEGER, [end_index] INTEGER, [x1] REAL, [y1] REAL, [x2] REAL, [y2] REAL);")
 | 
			
		||||
 | 
			
		||||
def decorateGraph(exDb, deDb, graph):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
    scriptMap = {}
 | 
			
		||||
 | 
			
		||||
    exCur.execute("SELECT [behavior], [index], [name] FROM script;")
 | 
			
		||||
    while True:
 | 
			
		||||
        lines = exCur.fetchone()
 | 
			
		||||
        if lines == None:
 | 
			
		||||
            break
 | 
			
		||||
        scriptMap[lines[0]] = (lines[1], lines[2])
 | 
			
		||||
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [type], [name] FROM behavior WHERE [type] != 0;")
 | 
			
		||||
    while True:
 | 
			
		||||
        lines = exCur.fetchone()
 | 
			
		||||
        if lines == None:
 | 
			
		||||
            break
 | 
			
		||||
 | 
			
		||||
        # add into global graph list
 | 
			
		||||
        graph.append(lines[0])
 | 
			
		||||
 | 
			
		||||
        # width and height will be computed by following method and use update
 | 
			
		||||
        # statement to change it
 | 
			
		||||
        if lines[1] == 1:
 | 
			
		||||
            # script
 | 
			
		||||
            deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, ?, ?)", (lines[0], lines[2], scriptMap[lines[0]][0], scriptMap[lines[0]][1]))
 | 
			
		||||
        else:
 | 
			
		||||
            # sub bb
 | 
			
		||||
            deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, -1, '')", (lines[0], lines[2]))
 | 
			
		||||
 | 
			
		||||
def buildBlock(exDb, deDb, target, currentGraphBlockCell):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
 | 
			
		||||
    # sort inner bb
 | 
			
		||||
    # use current graph input as the start point
 | 
			
		||||
    treeRoot = dcv.BBTreeNode(target, -1)
 | 
			
		||||
    processedBB = set()
 | 
			
		||||
    # layer start from 2, 0 is occupied for pLocal, 1 is occupied for pOper
 | 
			
		||||
    arrangedLayer = recursiveBuildBBTree(treeRoot, exCur, processedBB, 2, 0, target)
 | 
			
		||||
    
 | 
			
		||||
    # get no linked bb and place them.  linked bb position will be computed
 | 
			
		||||
    # following
 | 
			
		||||
    # calc each bb's x postion, as for y, calc later
 | 
			
		||||
    # flat bb tree
 | 
			
		||||
    arrangedLayer+=1
 | 
			
		||||
    singleBB = set()
 | 
			
		||||
    bbResult = {}
 | 
			
		||||
    bb_layer_map = {}
 | 
			
		||||
    baseX = dcv.GRAPH_CONTENTOFFSET_X
 | 
			
		||||
    exCur.execute('SELECT [thisobj], [name], [type], [proto_name], [pin_count] FROM behavior WHERE parent == ?', (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        pinSplit = i[4].split(',')
 | 
			
		||||
        bbCache = dcv.BBResult(i[1], i[3], pinSplit[1], pinSplit[2], pinSplit[3], pinSplit[4], (i[0] if i[2] != 0 else -1))
 | 
			
		||||
        bbCache.computSize()
 | 
			
		||||
        if i[0] not in processedBB:
 | 
			
		||||
            # single bb, process it
 | 
			
		||||
            singleBB.add(i[0])
 | 
			
		||||
            bbCache.x = baseX
 | 
			
		||||
            baseX += bbCache.width + dcv.GRAPH_BB_SPAN
 | 
			
		||||
            bb_layer_map[i[0]] = arrangedLayer
 | 
			
		||||
 | 
			
		||||
        bbResult[i[0]] = bbCache
 | 
			
		||||
 | 
			
		||||
    recursiveCalcBBX(treeRoot, dcv.GRAPH_CONTENTOFFSET_X, bbResult, bb_layer_map)
 | 
			
		||||
 | 
			
		||||
    # calc poper
 | 
			
		||||
    allBB = processedBB | singleBB
 | 
			
		||||
    processedOper = set()
 | 
			
		||||
    pluggedOper = {}
 | 
			
		||||
    occupiedLayerCountForSpecificBB = {}
 | 
			
		||||
    exCur.execute('SELECT [thisobj] FROM pOper WHERE [belong_to] == ?', (target,))
 | 
			
		||||
    newCur = exDb.cursor()
 | 
			
		||||
    newCur2 = exDb.cursor()
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[0] in processedOper:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        # check current bout, plugin into the first bb
 | 
			
		||||
        newCur.execute("SELECT [output_obj] FROM pLink WHERE ([input_obj] == ? AND [output_type] == ? AND [output_is_bb] == 1)", (i[0], dcv.dbPLinkInputOutputType.PIN))
 | 
			
		||||
        for j in newCur.fetchall():
 | 
			
		||||
            if j[0] in allBB:
 | 
			
		||||
                # can be plugin
 | 
			
		||||
                # try get tree
 | 
			
		||||
                if j[0] not in pluggedOper.keys():
 | 
			
		||||
                    pluggedOper[j[0]] = {}
 | 
			
		||||
                recursiveBuildOperTree(i[0], bb_layer_map, processedOper, occupiedLayerCountForSpecificBB, newCur2, 1, j[0], target, pluggedOper[j[0]])
 | 
			
		||||
                # exit for due to have found a proper host bb
 | 
			
		||||
                break
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
    # calc layer position
 | 
			
		||||
    layer_height = {}
 | 
			
		||||
    layer_y = {}
 | 
			
		||||
    layer_height[0] = 25
 | 
			
		||||
    layer_height[1] = 50
 | 
			
		||||
    for i in bb_layer_map.keys():
 | 
			
		||||
        curLayer = bb_layer_map[i]
 | 
			
		||||
        if curLayer not in layer_height.keys():
 | 
			
		||||
            layer_height[curLayer] = bbResult[i].height
 | 
			
		||||
        else:
 | 
			
		||||
            layer_height[curLayer] = max(layer_height.get(curLayer, 0), bbResult[i].height)
 | 
			
		||||
    layer_height[arrangedLayer] = layer_height.get(arrangedLayer, 0) # make sure misc bb height exist
 | 
			
		||||
    layer_height[2] = layer_height.get(2, 0)    # make sure at least have a bb layer (when there are no bb in a map)
 | 
			
		||||
 | 
			
		||||
    # calc bb Y
 | 
			
		||||
    baseY = dcv.GRAPH_CONTENTOFFSET_Y
 | 
			
		||||
    for i in range(arrangedLayer + 1):
 | 
			
		||||
        baseY += layer_height[i] + dcv.GRAPH_LAYER_SPAN
 | 
			
		||||
        baseY += occupiedLayerCountForSpecificBB.get(i, 0) * dcv.GRAPH_SPAN_BB_POPER    # add oper occipation
 | 
			
		||||
        layer_y[i] = baseY
 | 
			
		||||
    for i in bbResult.keys():
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        layer = bb_layer_map[i]
 | 
			
		||||
        cache.y = layer_y[layer] - layer_height[layer]
 | 
			
		||||
 | 
			
		||||
    # calc oper position
 | 
			
		||||
    # flat oper tree
 | 
			
		||||
    operResult = {}
 | 
			
		||||
    exCur.execute('SELECT [thisobj], [op] FROM pOper WHERE [belong_to] == ?', (target,))
 | 
			
		||||
    homelessOperCurrentX = dcv.GRAPH_CONTENTOFFSET_X
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[0] not in processedOper:
 | 
			
		||||
            # homeless oper
 | 
			
		||||
            cache2 = dcv.OperResult(i[1])
 | 
			
		||||
            cache2.computSize()
 | 
			
		||||
            cache2.x = homelessOperCurrentX
 | 
			
		||||
            cache2.y = layer_y[1] - cache2.height
 | 
			
		||||
            homelessOperCurrentX += cache2.width + dcv.GRAPH_BB_SPAN
 | 
			
		||||
            operResult[i[0]] = cache2
 | 
			
		||||
 | 
			
		||||
    for i in pluggedOper.keys():   # plugged oper
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        for j in pluggedOper[i]:
 | 
			
		||||
            jCache = pluggedOper[i][j]
 | 
			
		||||
            baseX = cache.x
 | 
			
		||||
            for q in jCache:
 | 
			
		||||
                exCur.execute("SELECT [op] FROM pOper WHERE [thisobj] == ?", (q,))
 | 
			
		||||
                cache2 = dcv.OperResult(exCur.fetchone()[0])
 | 
			
		||||
                cache2.computSize()
 | 
			
		||||
                cache2.x = baseX
 | 
			
		||||
                baseX += cache2.width + dcv.GRAPH_BB_SPAN
 | 
			
		||||
                cache2.y = cache.y - j * dcv.GRAPH_SPAN_BB_POPER
 | 
			
		||||
                operResult[q] = cache2
 | 
			
		||||
 | 
			
		||||
    # query bb pin's data
 | 
			
		||||
    listCache = []
 | 
			
		||||
    listItemCache = None
 | 
			
		||||
    for i in allBB:
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pTarget WHERE [belong_to] == ?;", (i,))
 | 
			
		||||
        temp = exCur.fetchone()
 | 
			
		||||
        if temp == None:
 | 
			
		||||
            cache.ptargetData = '{}'
 | 
			
		||||
        else:
 | 
			
		||||
            cache.ptargetData = json.dumps(dcv.PinInformation(temp[0], temp[1], temp[2]), cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name] FROM bIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], '')
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.binData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name] FROM bOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], '')
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.boutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.pinData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.poutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
    # query oper pin's data
 | 
			
		||||
    for i in operResult.keys():
 | 
			
		||||
        cache = operResult[i]
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.pinData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
        listCache.clear()
 | 
			
		||||
        exCur.execute("SELECT [thisobj], [name], [type] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i,))
 | 
			
		||||
        for j in exCur.fetchall():
 | 
			
		||||
            listItemCache = dcv.PinInformation(j[0], j[1], j[2])
 | 
			
		||||
            listCache.append(listItemCache)
 | 
			
		||||
        cache.poutData = json.dumps(listCache, cls = dcv.JsonCustomEncoder)
 | 
			
		||||
 | 
			
		||||
    # write to database and return
 | 
			
		||||
    for i in bbResult.keys():
 | 
			
		||||
        cache = bbResult[i]
 | 
			
		||||
        currentGraphBlockCell[i] = dcv.BlockCellItem(cache.x, cache.y, cache.width, cache.height)
 | 
			
		||||
        deCur.execute('INSERT INTO block VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
 | 
			
		||||
                      (target, i, cache.name, cache.assistName, cache.ptargetData, cache.pinData, cache.poutData, cache.binData, cache.boutData, cache.x, cache.y, cache.width, cache.height, cache.expandable))
 | 
			
		||||
    for i in operResult.keys():
 | 
			
		||||
        cache = operResult[i]
 | 
			
		||||
        currentGraphBlockCell[i] = dcv.BlockCellItem(cache.x, cache.y, cache.width, cache.height)
 | 
			
		||||
        deCur.execute("INSERT INTO block VALUES (?, ?, ?, '', '{}', ?, ?, '[]', '[]', ?, ?, ?, ?, -1)",
 | 
			
		||||
                      (target, i, cache.name, cache.pinData, cache.poutData, cache.x, cache.y, cache.width, cache.height))
 | 
			
		||||
 | 
			
		||||
def recursiveBuildBBTree(node, exCur, processedBB, layer, depth, graphId):
 | 
			
		||||
    realLinkedBB = set()
 | 
			
		||||
    # find links
 | 
			
		||||
    exCur.execute("SELECT [output_obj] FROM bLink WHERE ([input_obj] == ? AND [input_type] == ? AND [belong_to] = ?) ORDER BY [input_index] ASC;",
 | 
			
		||||
                  (node.bb, (dcv.dbBLinkInputOutputType.INPUT if depth == 0 else dcv.dbBLinkInputOutputType.OUTPUT), graphId))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[0] != graphId: # omit self
 | 
			
		||||
            realLinkedBB.add(i[0])
 | 
			
		||||
 | 
			
		||||
    if (len(realLinkedBB) == 0):
 | 
			
		||||
        return layer
 | 
			
		||||
 | 
			
		||||
    # ignore duplicated bb
 | 
			
		||||
    # calc need processed bb first
 | 
			
		||||
    # and register all gotten bb.  for preventing infinity resursive func and
 | 
			
		||||
    # keep bb tree structure
 | 
			
		||||
    realLinkedBB = realLinkedBB - processedBB
 | 
			
		||||
    processedBB.update(realLinkedBB)
 | 
			
		||||
 | 
			
		||||
    # iterate each bb
 | 
			
		||||
    for i in realLinkedBB:
 | 
			
		||||
        # recursive execute this method
 | 
			
		||||
        newNode = dcv.BBTreeNode(i, layer)
 | 
			
		||||
        layer = recursiveBuildBBTree(newNode, exCur, processedBB, layer, depth + 1, graphId)
 | 
			
		||||
        # add new node into list and ++layer
 | 
			
		||||
        layer+=1
 | 
			
		||||
        node.nodes.append(newNode)
 | 
			
		||||
 | 
			
		||||
    # minus extra ++ due to for
 | 
			
		||||
    if (len(realLinkedBB) != 0):
 | 
			
		||||
        layer-=1
 | 
			
		||||
    
 | 
			
		||||
    return layer
 | 
			
		||||
 | 
			
		||||
def recursiveCalcBBX(node, baseX, resultList, layerMap):
 | 
			
		||||
    maxExpand = 0
 | 
			
		||||
    for i in node.nodes:
 | 
			
		||||
        layerMap[i.bb] = i.layer
 | 
			
		||||
        resultList[i.bb].x = baseX
 | 
			
		||||
        maxExpand = max(maxExpand, resultList[i.bb].width)
 | 
			
		||||
 | 
			
		||||
    for i in node.nodes:
 | 
			
		||||
        recursiveCalcBBX(i, baseX + maxExpand + dcv.GRAPH_BB_SPAN, resultList, layerMap)
 | 
			
		||||
 | 
			
		||||
def recursiveBuildOperTree(oper, bb_layer_map, processedOper, occupiedLayerMap, exCur, sublayer, bb, graphId, subLayerColumnMap):
 | 
			
		||||
    if oper in processedOper:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # for avoid fucking export parameter feature.  check whether self is
 | 
			
		||||
    # current graph's memeber
 | 
			
		||||
    exCur.execute("SELECT [belong_to] FROM pOper WHERE [thisobj] == ?;", (oper,))
 | 
			
		||||
    if (exCur.fetchone()[0] != graphId):
 | 
			
		||||
        # fuck export param, exit
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    # make sure sub layer column map is ok
 | 
			
		||||
    if sublayer not in subLayerColumnMap.keys():
 | 
			
		||||
        subLayerColumnMap[sublayer] = []
 | 
			
		||||
 | 
			
		||||
    # register self
 | 
			
		||||
    # mark processed
 | 
			
		||||
    processedOper.add(oper)
 | 
			
		||||
    subLayerColumnMap[sublayer].append(oper)
 | 
			
		||||
 | 
			
		||||
    # record layer occupation
 | 
			
		||||
    layer = bb_layer_map[bb]
 | 
			
		||||
    occupiedLayerMap[layer] = max(occupiedLayerMap.get(layer, -1), sublayer)
 | 
			
		||||
 | 
			
		||||
    # iterate sub item
 | 
			
		||||
    exCur.execute("SELECT [input_obj] FROM pLink WHERE ([output_obj] == ? AND [input_type] == ? AND [input_is_bb] == 0) ORDER BY [output_index];", (oper, dcv.dbPLinkInputOutputType.POUT))
 | 
			
		||||
    res = []
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        res.append(i[0])
 | 
			
		||||
 | 
			
		||||
    for i in res:
 | 
			
		||||
        recursiveBuildOperTree(i, bb_layer_map, processedOper, occupiedLayerMap, exCur, sublayer + 1, bb, graphId, subLayerColumnMap)
 | 
			
		||||
 | 
			
		||||
def buildCell(exDb, deDb, target, currentGraphBlockCell):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
    # prepare block set
 | 
			
		||||
    blockSet = set()
 | 
			
		||||
    for i in currentGraphBlockCell.keys():
 | 
			
		||||
        blockSet.add(i)
 | 
			
		||||
 | 
			
		||||
    # find current graph's pio bio
 | 
			
		||||
    boutx = set()
 | 
			
		||||
    pouty = set()
 | 
			
		||||
    graphPIO = set()
 | 
			
		||||
 | 
			
		||||
    # bOut.x and pOut.y data is not confirmed, when graph size was confirmed,
 | 
			
		||||
    # update it
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index] FROM bIn WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = 0
 | 
			
		||||
        y = dcv.GRAPH_BOFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_BSPAN)
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, '', ?, ?, ?)", (target, i[0], i[1], x, y, dcv.CellType.BIO))
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index] FROM bOut WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = 0
 | 
			
		||||
        y = dcv.GRAPH_BOFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_BSPAN)
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, '', ?, ?, ?)", (target, i[0], i[1], x, y, dcv.CellType.BIO))
 | 
			
		||||
        boutx.add(i[0])
 | 
			
		||||
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index], [type] FROM pIn WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = dcv.GRAPH_POFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_PSPAN)
 | 
			
		||||
        y = 0
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)", (target, i[0], i[1], i[3], x, y, dcv.CellType.PIO))
 | 
			
		||||
        graphPIO.add(i[0])
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [index], [type] FROM pOut WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        x = dcv.GRAPH_POFFSET + i[2] * (dcv. BB_PBSIZE + dcv.GRAPH_PSPAN)
 | 
			
		||||
        y = 0
 | 
			
		||||
        currentGraphBlockCell[i[0]] = dcv.BlockCellItem(x, y, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)", (target, i[0], i[1], i[3], x, y, dcv.CellType.PIO))
 | 
			
		||||
        graphPIO.add(i[0])
 | 
			
		||||
        pouty.add(i[0])
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [type] FROM pTarget WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    cache = exCur.fetchone()
 | 
			
		||||
    if cache != None:
 | 
			
		||||
        currentGraphBlockCell[cache[0]] = dcv.BlockCellItem(0, 0, dcv.BB_PBSIZE, dcv.BB_PBSIZE)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, 0, 0, ?)", (target, i[0], i[1], i[2], dcv.CellType.PTARGET))
 | 
			
		||||
        graphPIO.add(cache[0])
 | 
			
		||||
 | 
			
		||||
    # query all plocal
 | 
			
		||||
    allLocal = set()
 | 
			
		||||
    localUsageCounter = {}
 | 
			
		||||
    exCur.execute("SELECT [thisobj], [name], [type] FROM pLocal WHERE [belong_to] == ?;", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        allLocal.add(i[0])
 | 
			
		||||
        localUsageCounter[i[0]] = dcv.LocalUsageItem(0, False, dcv.LocalUsageType.PLOCAL)
 | 
			
		||||
 | 
			
		||||
    # query all links(don't need to consider export pIO, due to it will not add
 | 
			
		||||
    # any shortcut)
 | 
			
		||||
    # !!  the same if framework in pLink generator function !!  SHARED
 | 
			
		||||
    createdShortcut = set()
 | 
			
		||||
    exCur.execute("SELECT * FROM pLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
 | 
			
		||||
        # analyse 5 chancee one by one
 | 
			
		||||
        if (i[7] == dcv.dbPLinkInputOutputType.PTARGET or i[7] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
            if (i[3] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                if i[2] in allLocal or i[2] in createdShortcut:
 | 
			
		||||
                    cache = localUsageCounter[i[2]]
 | 
			
		||||
                else:
 | 
			
		||||
                    cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PLOCAL)
 | 
			
		||||
                    localUsageCounter[i[2]] = cache
 | 
			
		||||
                    createdShortcut.add(i[2])
 | 
			
		||||
 | 
			
		||||
                cache.count += 1
 | 
			
		||||
                cache.lastUse = i[6]
 | 
			
		||||
                cache.lastDirection = 0
 | 
			
		||||
                cache.lastIndex = i[9]
 | 
			
		||||
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
                if i[2] == target:
 | 
			
		||||
                    continue    # ignore self pIn/pOut.  it doesn't need any shortcut
 | 
			
		||||
                if i[2] not in blockSet:
 | 
			
		||||
                    if i[0] not in createdShortcut:
 | 
			
		||||
                        cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PIN)
 | 
			
		||||
                        localUsageCounter[i[0]] = cache
 | 
			
		||||
                        createdShortcut.add(i[0])
 | 
			
		||||
                    else:
 | 
			
		||||
                        cache = localUsageCounter[i[0]]
 | 
			
		||||
 | 
			
		||||
                    cache.count+=1
 | 
			
		||||
                    cache.lastUse = i[6]
 | 
			
		||||
                    cache.lastDirection = 0
 | 
			
		||||
                    cache.lastIndex = i[9]
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PATTR):    # for attribute using
 | 
			
		||||
                if i[2] not in createdShortcut:
 | 
			
		||||
                    cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PATTR)
 | 
			
		||||
                    localUsageCounter[i[2]] = cache
 | 
			
		||||
                    createdShortcut.add(i[2])
 | 
			
		||||
                else:
 | 
			
		||||
                    cache = localUsageCounter[i[2]]
 | 
			
		||||
 | 
			
		||||
                    cache.count+=1
 | 
			
		||||
                    cache.lastUse = i[6]
 | 
			
		||||
                    cache.lastDirection = 0
 | 
			
		||||
                    cache.lastIndex = i[9]
 | 
			
		||||
            else:
 | 
			
		||||
                if i[2] not in blockSet:
 | 
			
		||||
                    if i[0] not in createdShortcut:
 | 
			
		||||
                        cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.POUT)
 | 
			
		||||
                        localUsageCounter[i[0]] = cache
 | 
			
		||||
                        createdShortcut.add(i[0])
 | 
			
		||||
                    else:
 | 
			
		||||
                        cache = localUsageCounter[i[0]]
 | 
			
		||||
 | 
			
		||||
                    cache.count+=1
 | 
			
		||||
                    cache.lastUse = i[6]
 | 
			
		||||
                    cache.lastDirection = 1
 | 
			
		||||
                    cache.lastIndex = i[9]
 | 
			
		||||
        else:
 | 
			
		||||
            if (i[7] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                if i[6] in allLocal or i[6] in createdShortcut:
 | 
			
		||||
                    cache = localUsageCounter[i[6]]
 | 
			
		||||
                else:
 | 
			
		||||
                    cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.PLOCAL)
 | 
			
		||||
                    localUsageCounter[i[6]] = cache
 | 
			
		||||
                    createdShortcut.add(i[6])
 | 
			
		||||
 | 
			
		||||
                cache.count += 1
 | 
			
		||||
                cache.lastUse = i[2]
 | 
			
		||||
                cache.lastDirection = 1
 | 
			
		||||
                cache.lastIndex = i[5]
 | 
			
		||||
            else:
 | 
			
		||||
                if i[6] == target:
 | 
			
		||||
                    continue    # ignore self pIn/pOut.  it doesn't need any shortcut
 | 
			
		||||
                if i[6] not in blockSet:
 | 
			
		||||
                    if i[1] not in createdShortcut:
 | 
			
		||||
                        cache = dcv.LocalUsageItem(0, True, dcv.LocalUsageType.POUT)
 | 
			
		||||
                        localUsageCounter[i[1]] = cache
 | 
			
		||||
                        createdShortcut.add(i[1])
 | 
			
		||||
                    else:
 | 
			
		||||
                        cache = localUsageCounter[i[1]]
 | 
			
		||||
 | 
			
		||||
                    cache.count += 1
 | 
			
		||||
                    cache.lastUse = i[2]
 | 
			
		||||
                    cache.lastDirection = 1
 | 
			
		||||
                    cache.lastIndex = i[5]
 | 
			
		||||
 | 
			
		||||
    # apply all cells
 | 
			
		||||
    defaultCellIndex = 0
 | 
			
		||||
    for i in localUsageCounter.keys():
 | 
			
		||||
        cache = localUsageCounter[i]
 | 
			
		||||
        # comput x,y
 | 
			
		||||
        if (cache.count == 1):
 | 
			
		||||
            # attachable
 | 
			
		||||
            attachTarget = currentGraphBlockCell[cache.lastUse]
 | 
			
		||||
            (x, y) = computCellPosition(attachTarget.x, attachTarget.y, attachTarget.h, cache.lastDirection, cache.lastIndex)
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            # place it in default area
 | 
			
		||||
            y = dcv.GRAPH_CONTENTOFFSET_Y
 | 
			
		||||
            x = dcv.GRAPH_CONTENTOFFSET_X + defaultCellIndex * (dcv.CELL_WIDTH + dcv.GRAPH_BB_SPAN)
 | 
			
		||||
            defaultCellIndex += 1
 | 
			
		||||
        # get information
 | 
			
		||||
        if (cache.internal_type == dcv.LocalUsageType.PIN):
 | 
			
		||||
            tableName = 'pIn'
 | 
			
		||||
        elif (cache.internal_type == dcv.LocalUsageType.POUT):
 | 
			
		||||
            tableName = 'pOut'
 | 
			
		||||
        elif (cache.internal_type == dcv.LocalUsageType.PATTR):
 | 
			
		||||
            tableName = 'pAttr'
 | 
			
		||||
        else:
 | 
			
		||||
            tableName = 'pLocal'
 | 
			
		||||
        exCur.execute("SELECT [name], [type] FROM {} WHERE [thisobj] == ?".format(tableName), (i,))
 | 
			
		||||
        temp = exCur.fetchone()
 | 
			
		||||
 | 
			
		||||
        # submit to database and map
 | 
			
		||||
        currentGraphBlockCell[i] = dcv.BlockCellItem(x, y, dcv.CELL_WIDTH, dcv.CELL_HEIGHT)
 | 
			
		||||
        deCur.execute("INSERT INTO cell VALUES (?, ?, ?, ?, ?, ?, ?)",
 | 
			
		||||
                      (target, i, temp[0], temp[1], x, y, (dcv.CellType.SHORTCUT if cache.isshortcut else dcv.CellType.PLOCAL)))
 | 
			
		||||
 | 
			
		||||
    # comput size and update database and currentGraphBlockCell
 | 
			
		||||
    graphX = 0
 | 
			
		||||
    graphY = 0
 | 
			
		||||
    for key, values in currentGraphBlockCell.items():
 | 
			
		||||
        graphX = max(graphX, values.x + values.w)
 | 
			
		||||
        graphY = max(graphY, values.y + values.h)
 | 
			
		||||
    graphX += dcv.GRAPH_POFFSET
 | 
			
		||||
    graphY += dcv.GRAPH_BOFFSET
 | 
			
		||||
 | 
			
		||||
    deCur.execute("UPDATE graph SET [width] = ?, [height] = ? WHERE [graph] == ?", (graphX, graphY, target))
 | 
			
		||||
 | 
			
		||||
    # update bOut.x and pOut.y data
 | 
			
		||||
    for i in boutx:
 | 
			
		||||
        deCur.execute("UPDATE cell SET [x] = ? WHERE ([thisobj] == ? AND [belong_to_graph] == ?)", (graphX - dcv.BB_PBSIZE, i, target))
 | 
			
		||||
        currentGraphBlockCell[i].x = graphX - dcv.BB_PBSIZE
 | 
			
		||||
    for i in pouty:
 | 
			
		||||
        deCur.execute("UPDATE cell SET [y] = ? WHERE ([thisobj] == ? AND [belong_to_graph] == ?)", (graphY - dcv.BB_PBSIZE, i, target))
 | 
			
		||||
        currentGraphBlockCell[i].y = graphY - dcv.BB_PBSIZE
 | 
			
		||||
 | 
			
		||||
    return graphPIO
 | 
			
		||||
 | 
			
		||||
def computCellPosition(baseX, baseY, height, direction, index):
 | 
			
		||||
    if (index == -1):
 | 
			
		||||
        return (baseX, baseY - dcv.GRAPH_SPAN_BB_PLOCAL)
 | 
			
		||||
 | 
			
		||||
    if (direction == 0):
 | 
			
		||||
        return (baseX + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN), baseY - dcv.GRAPH_SPAN_BB_PLOCAL)
 | 
			
		||||
    else:
 | 
			
		||||
        return (baseX + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN), baseY + height + dcv.GRAPH_SPAN_BB_PLOCAL)
 | 
			
		||||
 | 
			
		||||
def buildLink(exDb, deDb, target, currentGraphBlockCell, graphPIO):
 | 
			
		||||
    exCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
 | 
			
		||||
    # prepare block set
 | 
			
		||||
    blockSet = set()
 | 
			
		||||
    for i in currentGraphBlockCell.keys():
 | 
			
		||||
        blockSet.add(i)
 | 
			
		||||
 | 
			
		||||
    # bLink
 | 
			
		||||
    exCur.execute("SELECT * FROM bLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        if i[3] == target:
 | 
			
		||||
            (x1, y1) = computLinkBTerminal(i[0], 0, -1 ,currentGraphBlockCell)
 | 
			
		||||
            bStartObj = i[0]
 | 
			
		||||
            bStartType = 0
 | 
			
		||||
            bStartIndex = -1
 | 
			
		||||
        else:
 | 
			
		||||
            (x1, y1) = computLinkBTerminal(i[3], i[4], i[5], currentGraphBlockCell)
 | 
			
		||||
            bStartObj = i[3]
 | 
			
		||||
            bStartType = i[4]
 | 
			
		||||
            bStartIndex = i[5]
 | 
			
		||||
        if i[6] == target:
 | 
			
		||||
            (x2, y2) = computLinkBTerminal(i[1], 0, -1,currentGraphBlockCell)
 | 
			
		||||
            bEndObj = i[1]
 | 
			
		||||
            bEndType = 0
 | 
			
		||||
            bEndIndex = -1
 | 
			
		||||
        else:
 | 
			
		||||
            (x2, y2) = computLinkBTerminal(i[6], i[7], i[8],currentGraphBlockCell)
 | 
			
		||||
            bEndObj = i[6]
 | 
			
		||||
            bEndType = i[7]
 | 
			
		||||
            bEndIndex = i[8]
 | 
			
		||||
 | 
			
		||||
        deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                      (target, i[2], i[0], i[1], bStartObj, bEndObj, bStartType, bEndType, bStartIndex, bEndIndex, x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
    # pLink
 | 
			
		||||
    # !!  the same if framework in cell generator function !!  SHARED
 | 
			
		||||
    exCur.execute("SELECT * FROM pLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        # analyse 5 chancee one by one
 | 
			
		||||
        if (i[7] == dcv.dbPLinkInputOutputType.PTARGET or i[7] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
            if (i[3] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PIN):
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                if i[2] == target:
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[0], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
 | 
			
		||||
                else:
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[2], 0, i[5], currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[2], i[6], 0, 0, i[5], i[9], x1, y1, x2, y2))
 | 
			
		||||
            elif (i[3] == dcv.dbPLinkInputOutputType.PATTR):
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 0, 0, -1, i[9], x1, y1, x2, y2))
 | 
			
		||||
            else:
 | 
			
		||||
                if i[2] in blockSet:    # process protencial pOut(shortcut) (because plocal input/input_obj
 | 
			
		||||
                                        # output/output_obj is same, so don't need add for them)
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                else:
 | 
			
		||||
                    (x1, y1) = computLinkPTerminal(i[0], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[6], 0, i[9], currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 1, 0, i[5], i[9], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            if (i[7] == dcv.dbPLinkInputOutputType.PLOCAL):
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                (x2, y2) = computLinkPTerminal(i[1], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                              (target, -1, i[0], i[1], i[2], i[6], 1, 0, i[5], -1, x1, y1, x2, y2))
 | 
			
		||||
            else:
 | 
			
		||||
                (x1, y1) = computLinkPTerminal(i[2], 1, i[5], currentGraphBlockCell)
 | 
			
		||||
                if i[6] == target:
 | 
			
		||||
                    (x2, y2) = computLinkPTerminal(i[1], 0, -1, currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[2], i[1], 1, 0, i[5], -1, x1, y1, x2, y2))
 | 
			
		||||
                else:
 | 
			
		||||
                    (x2, y2) = computLinkPTerminal(i[6], 1, i[9], currentGraphBlockCell)
 | 
			
		||||
                    deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                                  (target, -1, i[0], i[1], i[2], i[6], 1, 1, i[5], i[9], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
    # eLink
 | 
			
		||||
    exCur.execute("SELECT * FROM eLink WHERE [belong_to] == ?", (target,))
 | 
			
		||||
    for i in exCur.fetchall():
 | 
			
		||||
        (x1, y1) = computLinkPTerminal(i[0], 0, -1, currentGraphBlockCell)
 | 
			
		||||
        (x2, y2) = computLinkPTerminal(i[1], 0 if i[2] == 1 else 1, i[3], currentGraphBlockCell)
 | 
			
		||||
        deCur.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
 | 
			
		||||
                        (target, -2, i[0], i[0], target, i[1], 0, 0 if i[2] == 1 else 1, -1, i[3], x1, y1, x2, y2))
 | 
			
		||||
 | 
			
		||||
def computLinkBTerminal(obj, xtype, index, currentGraphBlockCell):
 | 
			
		||||
    # index = -1 mean no offset, it will connect to graph io
 | 
			
		||||
    cache = currentGraphBlockCell[obj]
 | 
			
		||||
    return (cache.x if xtype == 0 else cache.x + cache.w - dcv.BB_PBSIZE,
 | 
			
		||||
            cache.y if index == -1 else (cache.y + dcv.BB_BOFFSET + index * (dcv.BB_PBSIZE + dcv.BB_BSPAN)))
 | 
			
		||||
 | 
			
		||||
def computLinkPTerminal(obj, ytype, index, currentGraphBlockCell):
 | 
			
		||||
    # ytype is not database type.  it have the same meaning of LinkBTerminal,
 | 
			
		||||
    # indicating the position.  0 is keep origin position(for pIn and pTarget),
 | 
			
		||||
    # 1 is consider height(for pOut)
 | 
			
		||||
    cache = currentGraphBlockCell[obj]
 | 
			
		||||
    return (cache.x if index == -1 else (cache.x + dcv.BB_POFFSET + index * (dcv.BB_PBSIZE + dcv.BB_PSPAN)), 
 | 
			
		||||
            cache.y if ytype == 0 else (cache.y + cache.h - dcv.BB_PBSIZE))
 | 
			
		||||
 | 
			
		||||
def buildInfo(exDb, deDb):
 | 
			
		||||
    exInfoCur = exDb.cursor()
 | 
			
		||||
    exQueryCur = exDb.cursor()
 | 
			
		||||
    deCur = deDb.cursor()
 | 
			
		||||
 | 
			
		||||
    # declare tiny storage for convenient query
 | 
			
		||||
    tinyStorageKey = 0
 | 
			
		||||
    tinyStorageBB = -1
 | 
			
		||||
    tinyStorageSetting = 0
 | 
			
		||||
    tinyStorageName = ""
 | 
			
		||||
 | 
			
		||||
    # export local data (including proto bb internal data)
 | 
			
		||||
    exInfoCur.execute("SELECT * FROM pData;")
 | 
			
		||||
    for i in exInfoCur.fetchall():
 | 
			
		||||
        attachBB = -1
 | 
			
		||||
        isSetting = 0
 | 
			
		||||
        infoName = ""
 | 
			
		||||
 | 
			
		||||
        if i[2] == tinyStorageKey:
 | 
			
		||||
            attachBB = tinyStorageBB
 | 
			
		||||
            isSetting = tinyStorageSetting
 | 
			
		||||
            infotName = tinyStorageName
 | 
			
		||||
        else:
 | 
			
		||||
            # clear storage first
 | 
			
		||||
            tinyStorageBB = -1
 | 
			
		||||
            tinyStorageSetting = 0
 | 
			
		||||
            tinyStorageName = ""
 | 
			
		||||
 | 
			
		||||
            # query correspond pLocal
 | 
			
		||||
            exQueryCur.execute("SELECT [belong_to], [is_setting], [name] FROM pLocal WHERE [thisobj] = ?", (i[2], ))
 | 
			
		||||
            plocalCache = exQueryCur.fetchone()
 | 
			
		||||
            if plocalCache is not None:
 | 
			
		||||
                # add setting config
 | 
			
		||||
                tinyStorageSetting = isSetting = plocalCache[1]
 | 
			
		||||
                tinyStorageName = infoName = plocalCache[2]
 | 
			
		||||
                # query bb again
 | 
			
		||||
                exQueryCur.execute("SELECT [thisobj] FROM behavior WHERE ([thisobj] = ? AND [type] = 0)", (plocalCache[0], ))
 | 
			
		||||
                behaviorCache = exQueryCur.fetchone()
 | 
			
		||||
                if behaviorCache is not None:
 | 
			
		||||
                    tinyStorageBB = attachBB = behaviorCache[0]
 | 
			
		||||
 | 
			
		||||
        deCur.execute("INSERT INTO info VALUES (?, ?, ?, ?, ?, ?)", (i[2], attachBB, isSetting, infoName, i[0], i[1]))
 | 
			
		||||
							
								
								
									
										109
									
								
								SuperScriptDecorator/DecoratorData.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								SuperScriptDecorator/DecoratorData.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
import typing, collections, sqlite3
 | 
			
		||||
 | 
			
		||||
class Vector(object):
 | 
			
		||||
    def __init__(self, x: float, y: float):
 | 
			
		||||
        self.X: float = x
 | 
			
		||||
        self.Y: float = y
 | 
			
		||||
    def __add__(self, other):
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        return Vector(self.X + other.X, self.Y + other.Y)
 | 
			
		||||
    def __sub__(self, other):
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        return Vector(self.X - other.X, self.Y - other.Y)
 | 
			
		||||
 | 
			
		||||
    def __radd__(self, other):
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        return Vector(self.X + other.X, self.Y + other.Y)
 | 
			
		||||
    def __rsub__(self, other):
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        return Vector(self.X - other.X, self.Y - other.Y)
 | 
			
		||||
 | 
			
		||||
    def __iadd__(self, other):
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        self.X += other.X
 | 
			
		||||
        self.Y += other.Y
 | 
			
		||||
        return self
 | 
			
		||||
    def __isub__(self, other):
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        self.X -= other.X
 | 
			
		||||
        self.Y -= other.Y
 | 
			
		||||
        return self
 | 
			
		||||
 | 
			
		||||
    def __eq__(self, other) -> bool:
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        return (self.X == other.X and self.Y == other.Y)
 | 
			
		||||
    def __ne__(self, other) -> bool:
 | 
			
		||||
        if not isinstance(other, Vector): return NotImplemented
 | 
			
		||||
        return (self.X != other.X or self.Y != other.Y)
 | 
			
		||||
 | 
			
		||||
class ICanComputeSize(object):
 | 
			
		||||
    '''
 | 
			
		||||
    This class is served for TreeLayout class.
 | 
			
		||||
 | 
			
		||||
    All classes inherit this class will have ability to calculate the size of self,
 | 
			
		||||
    and report to TreeLayout. TreeLayout will use these data to distribute position.
 | 
			
		||||
 | 
			
		||||
    The functions declared in this class have unique name meaning. 
 | 
			
		||||
    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.
 | 
			
		||||
    '''
 | 
			
		||||
    def GetLeavesDirLength() -> float:
 | 
			
		||||
        '''
 | 
			
		||||
        Get the length of the direction where leaves grow up.
 | 
			
		||||
        '''
 | 
			
		||||
        raise NotImplementedError()
 | 
			
		||||
    def GetRootDirLength() -> float:
 | 
			
		||||
        '''
 | 
			
		||||
        Get the length of the direction where the tree planted.
 | 
			
		||||
        
 | 
			
		||||
        '''
 | 
			
		||||
        raise NotImplementedError()
 | 
			
		||||
 | 
			
		||||
TNode = typing.TypeVar('TNode')
 | 
			
		||||
class TreeLayout(typing.Generic[TNode]):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
SqlTableProto_Behavior = collections.namedtuple('Behavior', 'thisobj, name, type, proto_name, proto_guid, flags, priority, version, pin_count, parent')
 | 
			
		||||
 | 
			
		||||
class BBDataPayload(object):
 | 
			
		||||
    def __init__(self, sql_data: tuple):
 | 
			
		||||
        v = SqlTableProto_Behavior._make(sql_data)
 | 
			
		||||
 | 
			
		||||
        self.m_CKID: int = v.thisobj
 | 
			
		||||
        self.m_Name: str = v.name
 | 
			
		||||
        self.m_Type: int = v.type
 | 
			
		||||
        self.m_ProtoName: str = v.proto_name
 | 
			
		||||
        self.m_ProtoGUID: str = v.proto_guid
 | 
			
		||||
        self.m_Flags: int = v.flags
 | 
			
		||||
        self.m_Priority: int = v.priority
 | 
			
		||||
        self.m_Version: int = v.version
 | 
			
		||||
        self.m_Parent: int = v.parent
 | 
			
		||||
 | 
			
		||||
        div_pin_count = v.pin_count.split(',')
 | 
			
		||||
        self.m_pTargetExisting: bool = int(div_pin_count[0] == 1)
 | 
			
		||||
        self.m_pInCount: int = int(div_pin_count[1])
 | 
			
		||||
        self.m_pOutCount: int = int(div_pin_count[2])
 | 
			
		||||
        self.m_bInCount: int = int(div_pin_count[3])
 | 
			
		||||
        self.m_bOutCount: int = int(div_pin_count[4])
 | 
			
		||||
 | 
			
		||||
class OperTreeNode(ICanComputeSize):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
class BBTreeNode(ICanComputeSize):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.m_UpperOper: TreeLayout[OperTreeNode] = TreeLayout()
 | 
			
		||||
        self.m_LowerOper: TreeLayout[OperTreeNode] = TreeLayout()
 | 
			
		||||
        self.m_Upperval: collections.deque = collections.deque()
 | 
			
		||||
        self.m_LowerVal: collections.deque = collections.deque()
 | 
			
		||||
        self.m_Payload: BBDataPayload = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GraphWork(ICanComputeSize):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.m_PassiveVal: collections.deque = collections.deque()
 | 
			
		||||
        self.m_PassiveOper: TreeLayout[OperTreeNode] = TreeLayout()
 | 
			
		||||
        self.m_ActiveBB: TreeLayout[BBTreeNode] = TreeLayout()
 | 
			
		||||
        self.m_PassiveBB: TreeLayout[BBTreeNode] = TreeLayout()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,6 @@ class Prograssbar(object):
 | 
			
		||||
            percentage_bar * '#',
 | 
			
		||||
            (self.__PbarFullChar - percentage_bar) * '=', 
 | 
			
		||||
            percentage_full * 100,
 | 
			
		||||
            self.__CurFileName
 | 
			
		||||
            self.__CurFileName if self.__CurFileName else ''
 | 
			
		||||
        ))
 | 
			
		||||
        sys.stdout.flush()
 | 
			
		||||
 | 
			
		||||
@ -38,10 +38,10 @@ if not cfg.Regulate():
 | 
			
		||||
# if in debug mode, run directly
 | 
			
		||||
# otherwise, run with a try wrapper.
 | 
			
		||||
if cfg.m_DebugMode:
 | 
			
		||||
    DecoratorCore.run(cfg)
 | 
			
		||||
    DecoratorCore.Run(cfg)
 | 
			
		||||
else:
 | 
			
		||||
    try:
 | 
			
		||||
        DecoratorCore.run(cfg)
 | 
			
		||||
        DecoratorCore.Run(cfg)
 | 
			
		||||
    except Exception as ex:
 | 
			
		||||
        print("!!! An error occurs. Please report follwoing error output and reproduce file to developer. !!!")
 | 
			
		||||
        logging.exception(ex)
 | 
			
		||||
 | 
			
		||||
@ -44,14 +44,21 @@ namespace SSMaterializer {
 | 
			
		||||
			;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sqlite3_stmt* SSMaterializerDatabase::CreateStmt(const char* str_stmt) {
 | 
			
		||||
		sqlite3_stmt* SSMaterializerDatabase::GetStmt(const char* str_stmt) {
 | 
			
		||||
			// try find first
 | 
			
		||||
			auto probe = mStmtCache.find(reinterpret_cast<const uintptr_t>(str_stmt));
 | 
			
		||||
			if (probe != mStmtCache.end()) {
 | 
			
		||||
				return probe->second;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// no found. create one
 | 
			
		||||
			int result;
 | 
			
		||||
			sqlite3_stmt* stmt = NULL;
 | 
			
		||||
			result = sqlite3_prepare_v2(mDb, str_stmt, -1, &stmt, NULL);
 | 
			
		||||
			if (result != SQLITE_OK) return NULL;
 | 
			
		||||
 | 
			
		||||
			// append new one
 | 
			
		||||
			mStmtCache.push_back(stmt);
 | 
			
		||||
			mStmtCache.emplace(reinterpret_cast<const uintptr_t>(str_stmt), stmt);
 | 
			
		||||
			return stmt;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -92,8 +99,8 @@ namespace SSMaterializer {
 | 
			
		||||
 | 
			
		||||
			//free all cached stmts and commit job
 | 
			
		||||
			for (auto it = mStmtCache.begin(); it != mStmtCache.end(); it++) {
 | 
			
		||||
				if (*it != NULL) {
 | 
			
		||||
					result = sqlite3_finalize(*it);
 | 
			
		||||
				if (it->second != NULL) {
 | 
			
		||||
					result = sqlite3_finalize(it->second);
 | 
			
		||||
					if (result != SQLITE_OK) goto fail;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@ -255,18 +262,12 @@ if (result != SQLITE_OK) { return FALSE; }
 | 
			
		||||
 | 
			
		||||
#pragma endregion
 | 
			
		||||
 | 
			
		||||
#define TryGetStmtCache(str_sql) static sqlite3_stmt* stmt = NULL; \
 | 
			
		||||
if (stmt == NULL) { \
 | 
			
		||||
	stmt = CreateStmt(str_sql); \
 | 
			
		||||
	if (stmt == NULL) return; \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#pragma region document database
 | 
			
		||||
 | 
			
		||||
		void DocumentDatabase::write_script(DataStruct::dbdoc_script& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -279,7 +280,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_behavior(DataStruct::dbdoc_script_behavior& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_behavior] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_behavior] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -299,7 +300,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_pTarget(DataStruct::dbdoc_script_pTarget& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pTarget] VALUES (?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pTarget] VALUES (?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -315,7 +316,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_pIn(DataStruct::dbdoc_script_pIn& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pIn] VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pIn] VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -332,7 +333,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_pOut(DataStruct::dbdoc_script_pOut& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pOut] VALUES (?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pOut] VALUES (?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -347,7 +348,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_bIn(DataStruct::dbdoc_script_bIn& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_bIn] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_bIn] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -360,7 +361,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_bOut(DataStruct::dbdoc_script_bOut& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_bOut] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_bOut] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -373,7 +374,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_bLink(DataStruct::dbdoc_script_bLink& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_bLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_bLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.input);
 | 
			
		||||
@ -392,7 +393,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_pLocal(DataStruct::dbdoc_script_pLocal& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pLocal] VALUES (?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pLocal] VALUES (?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -407,7 +408,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_pLink(DataStruct::dbdoc_script_pLink& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.input);
 | 
			
		||||
@ -427,7 +428,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_pOper(DataStruct::dbdoc_script_pOper& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pOper] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pOper] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -440,7 +441,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_script_eLink(DataStruct::dbdoc_script_eLink& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_eLink] VALUES (?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_eLink] VALUES (?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.export_obj);
 | 
			
		||||
@ -455,7 +456,7 @@ if (stmt == NULL) { \
 | 
			
		||||
			// then check database validation
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [script_pAttr] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [script_pAttr] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.thisobj);
 | 
			
		||||
@ -470,7 +471,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_msg(DataStruct::dbdoc_msg& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [msg] VALUES (?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [msg] VALUES (?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.index);
 | 
			
		||||
@ -481,7 +482,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_obj(DataStruct::dbdoc_obj& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [obj] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [obj] VALUES (?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.id);
 | 
			
		||||
@ -494,7 +495,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void DocumentDatabase::write_data(DataStruct::dbdoc_data& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [data] VALUES (?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [data] VALUES (?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_text(stmt, 1, data.field.c_str(), -1, SQLITE_TRANSIENT);
 | 
			
		||||
@ -510,7 +511,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void EnvironmentDatabase::write_op(DataStruct::dbenv_op& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [op] VALUES (?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [op] VALUES (?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, (int)data.funcPtr);
 | 
			
		||||
@ -526,7 +527,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void EnvironmentDatabase::write_param(DataStruct::dbenv_param& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [param] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [param] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.index);
 | 
			
		||||
@ -553,7 +554,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void EnvironmentDatabase::write_attr(DataStruct::dbenv_attr& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [attr] VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [attr] VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.index);
 | 
			
		||||
@ -570,7 +571,7 @@ if (stmt == NULL) { \
 | 
			
		||||
		void EnvironmentDatabase::write_plugin(DataStruct::dbenv_plugin& data) {
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [plugin] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [plugin] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_int(stmt, 1, data.dll_index);
 | 
			
		||||
@ -592,7 +593,7 @@ if (stmt == NULL) { \
 | 
			
		||||
			if (mDb == NULL) return;
 | 
			
		||||
 | 
			
		||||
#if !defined(VIRTOOLS_21)
 | 
			
		||||
			TryGetStmtCache("INSERT INTO [variable] VALUES (?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_stmt* stmt = GetStmt("INSERT INTO [variable] VALUES (?, ?, ?, ?, ?, ?)");
 | 
			
		||||
			sqlite3_reset(stmt);
 | 
			
		||||
 | 
			
		||||
			sqlite3_bind_text(stmt, 1, data.name.c_str(), -1, SQLITE_TRANSIENT);
 | 
			
		||||
@ -607,7 +608,5 @@ if (stmt == NULL) { \
 | 
			
		||||
 | 
			
		||||
#pragma endregion
 | 
			
		||||
 | 
			
		||||
#undef TryGetStmtCache
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
#include "stdafx.h"
 | 
			
		||||
#include "virtools_compatible.hpp"
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <set>
 | 
			
		||||
 | 
			
		||||
namespace SSMaterializer {
 | 
			
		||||
@ -290,14 +290,14 @@ namespace SSMaterializer {
 | 
			
		||||
			virtual ~SSMaterializerDatabase();
 | 
			
		||||
 | 
			
		||||
		protected:
 | 
			
		||||
			sqlite3_stmt* CreateStmt(const char* stmt);
 | 
			
		||||
			sqlite3_stmt* GetStmt(const char* stmt);
 | 
			
		||||
			void FakeConstructor(const char* file);
 | 
			
		||||
			void FakeDeconstructor();
 | 
			
		||||
			virtual BOOL Init();
 | 
			
		||||
			virtual BOOL Finalize();
 | 
			
		||||
 | 
			
		||||
			sqlite3* mDb;
 | 
			
		||||
			std::vector<sqlite3_stmt*> mStmtCache;
 | 
			
		||||
			std::unordered_map<uintptr_t, sqlite3_stmt*> mStmtCache;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		class DocumentDatabase : public SSMaterializerDatabase {
 | 
			
		||||
 | 
			
		||||
@ -1,2 +1,2 @@
 | 
			
		||||
Ballance/vt2obj "example.nmo" "export.db" "env.db"
 | 
			
		||||
"Ballance/vt2obj mirror" Gameplay.nmo export.db env.db
 | 
			
		||||
"Ballance/vt2obj mirror" Gameplay.nmo export2.db env.db
 | 
			
		||||
		Reference in New Issue
	
	Block a user