diff --git a/SuperScriptDecorator/DecoratorBB.py b/SuperScriptDecorator/DecoratorBB.py new file mode 100644 index 0000000..e69de29 diff --git a/SuperScriptDecorator/DecoratorCore.old.py b/SuperScriptDecorator/DecoratorCore.old.py new file mode 100644 index 0000000..24ddda8 --- /dev/null +++ b/SuperScriptDecorator/DecoratorCore.old.py @@ -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])) \ No newline at end of file diff --git a/SuperScriptDecorator/DecoratorCore.py b/SuperScriptDecorator/DecoratorCore.py index 24ddda8..afc451a 100644 --- a/SuperScriptDecorator/DecoratorCore.py +++ b/SuperScriptDecorator/DecoratorCore.py @@ -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])) \ No newline at end of file + decorateDb.close() \ No newline at end of file diff --git a/SuperScriptDecorator/DecoratorData.py b/SuperScriptDecorator/DecoratorData.py new file mode 100644 index 0000000..3e5bf3e --- /dev/null +++ b/SuperScriptDecorator/DecoratorData.py @@ -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() + + diff --git a/SuperScriptDecorator/Progressbar.py b/SuperScriptDecorator/Progressbar.py index d4134b6..cb2b33c 100644 --- a/SuperScriptDecorator/Progressbar.py +++ b/SuperScriptDecorator/Progressbar.py @@ -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() diff --git a/SuperScriptDecorator/SuperScriptDecorator.py b/SuperScriptDecorator/SuperScriptDecorator.py index d873718..3f92b3d 100644 --- a/SuperScriptDecorator/SuperScriptDecorator.py +++ b/SuperScriptDecorator/SuperScriptDecorator.py @@ -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) diff --git a/SuperScriptMaterializer/database.cpp b/SuperScriptMaterializer/database.cpp index e264932..f8fd194 100644 --- a/SuperScriptMaterializer/database.cpp +++ b/SuperScriptMaterializer/database.cpp @@ -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(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(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 - } } \ No newline at end of file diff --git a/SuperScriptMaterializer/database.hpp b/SuperScriptMaterializer/database.hpp index 90aee18..9c474a8 100644 --- a/SuperScriptMaterializer/database.hpp +++ b/SuperScriptMaterializer/database.hpp @@ -4,7 +4,7 @@ #include "stdafx.h" #include "virtools_compatible.hpp" #include -#include +#include #include 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 mStmtCache; + std::unordered_map mStmtCache; }; class DocumentDatabase : public SSMaterializerDatabase { diff --git a/example.txt b/example.txt index d50b73f..4dcd3cc 100644 --- a/example.txt +++ b/example.txt @@ -1,2 +1,2 @@ Ballance/vt2obj "example.nmo" "export.db" "env.db" -"Ballance/vt2obj mirror" Gameplay.nmo export.db env.db \ No newline at end of file +"Ballance/vt2obj mirror" Gameplay.nmo export2.db env.db \ No newline at end of file