diff --git a/SuperScriptViewer/DecoratorConstValue.py b/SuperScriptViewer/DecoratorConstValue.py index 82789f7..fe00f77 100644 --- a/SuperScriptViewer/DecoratorConstValue.py +++ b/SuperScriptViewer/DecoratorConstValue.py @@ -1,24 +1,24 @@ FONT_SIZE = 12 -GRAPH_POFFSET = 40 -GRAPH_BOFFSET = 40 -GRAPH_PSPAN = 20 -GRAPH_BSPAN = 20 -GRAPH_LAYER_SPAN = 50 -GRAPH_BB_SPAN = 25 +GRAPH_POFFSET = 40 # 主体bb的p距离左边框距离 +GRAPH_BOFFSET = 40 # 主体bb的b距离上边框距离 +GRAPH_PSPAN = 20 # 主体bb的每个p之间的水平间距 +GRAPH_BSPAN = 20 # 主体bb的每个b之间的垂直间距 +GRAPH_LAYER_SPAN = 50 # 绘图中各个bb层之间的间距 +GRAPH_BB_SPAN = 25 # 绘图中每个bb之间的距离 +GRAPH_SPAN_BB_POPER = 60 # 每个bb上面挂载的oper和被挂载bb之间的垂直距离 和 每个bb上面挂载的oper的各层之间的垂直距离 +GRAPH_CONTENTOFFSET_X = 40 # 绘图内容原点到左边框的距离 +GRAPH_CONTENTOFFSET_Y = 40 # 绘图内容原点到顶边框的距离 -BB_POFFSET = 20 -BB_BOFFSET = 10 -BB_PSPAN = 20 -BB_BSPAN = 20 -BB_PBSIZE = 6 +BB_POFFSET = 20 # bb框中的p距离左边框距离 +BB_BOFFSET = 10 # bb框中的b距离上边框距离 +BB_PSPAN = 20 # bb框每个p之间的水平间距 +BB_BSPAN = 20 # bb框每个b之间的垂直间距 +BB_PBSIZE = 6 # bb框中o和b的正方形符号的边长 CELL_WIDTH = 15 CELL_HEIGHT = 5 -GRAPH_CONTENTOFFSET_X = 40 -GRAPH_CONTENTOFFSET_Y = 40 - class dbPLinkInputOutputType(object): PIN = 0 POUT = 1 @@ -60,31 +60,28 @@ class BBResult(object): self.expandable = expandable def computSize(self): - wText = max(len(self.name), len(self.assistName)) * FONT_SIZE - hText = FONT_SIZE * 4 + wText = max(len(self.name), len(self.assistName)) * FONT_SIZE / 2 + hText = FONT_SIZE * 3 - wp = 2 * BB_POFFSET + max(self.pin, self.pout) * (BB_PBSIZE + BB_PSPAN) - hb = 2 * BB_BOFFSET + max(self.bin, self.bout) * (BB_PBSIZE + BB_BSPAN) + wp = max(self.pin, self.pout) * (BB_PBSIZE + BB_PSPAN) + hb = max(self.bin, self.bout) * (BB_PBSIZE + BB_BSPAN) - self.width = max(wp, wText) - self.height = max(hb, hText) - -class pOperArrangement(object): - def __init__(self, attachedBB, sublayer): - self.attachedBB = attachedBB - self.sublayer = sublayer + self.width = 2 * BB_POFFSET + max(wp, wText) + self.height = 2 * BB_BOFFSET + max(hb, hText) class OperResult(object): - def __init__(self, name, x): + def __init__(self, name): self.name = name - self.x = x + self.x = 0.0 self.y = 0.0 + self.pinData = [] + self.poutData = [] self.height = 0.0 self.width = 0.0 def computSize(self): - wText = len(self.name) * FONT_SIZE - hText = FONT_SIZE * 4 + wText = len(self.name) * FONT_SIZE / 2 + hText = FONT_SIZE * 3 wp = 2 * BB_POFFSET + 2 * (BB_PBSIZE + BB_PSPAN) hb = 2 * BB_BOFFSET + 0 * (BB_PBSIZE + BB_BSPAN) diff --git a/SuperScriptViewer/DecoratorCore.py b/SuperScriptViewer/DecoratorCore.py index d3e763e..c6c6424 100644 --- a/SuperScriptViewer/DecoratorCore.py +++ b/SuperScriptViewer/DecoratorCore.py @@ -5,28 +5,27 @@ import queue def run(): exportDb = sqlite3.connect('export.db') decorateDb = sqlite3.connect('decorate.db') - exportCur = exportDb.cursor() - decorateCur = decorateDb.cursor() # init table print('Init decorate.dll') - initDecorateDb(decorateCur) + initDecorateDb(decorateDb) decorateDb.commit() # decorate graph graphList = [] - decorateGraph(exportCur, decorateCur, graphList) + decorateGraph(exportDb, decorateDb, graphList) # decorate each graph for i in graphList: - (plocal_layer, bbMap, operMap) = buildBlock(exportCur, decorateCur, i) + (plocal_layer, bbMap, operMap) = buildBlock(exportDb, decorateDb, i) # give up all change of eexport.db (because no change) exportDb.close() decorateDb.commit() decorateDb.close() -def initDecorateDb(cur): +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, [field] TEXT, [data] TEXT);") @@ -34,7 +33,9 @@ def initDecorateDb(cur): 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, [thisobj] INTEGER, [delay] INTEGER, [startobj] INTEGER, [endobj] INTEGER, [start_index] INTEGER, [end_index] INTEGER, [x1] REAL, [y1] REAL, [x2] REAL, [y2] REAL);") -def decorateGraph(exCur, deCur, graph): +def decorateGraph(exDb, deDb, graph): + exCur = exDb.cursor() + deCur = deDb.cursor() scriptMap = {} exCur.execute("SELECT [behavior], [index], [name] FROM script;") @@ -62,7 +63,10 @@ def decorateGraph(exCur, deCur, graph): # sub bb deCur.execute("INSERT INTO graph VALUES(?, ?, 0, 0, -1, '')", (lines[0], lines[2])) -def buildBlock(exCur, deCur, target): +def buildBlock(exDb, deDb, target): + exCur = exDb.cursor() + deCur = deDb.cursor() + # sort inner bb # use current graph input as the start point treeRoot = dcv.BBTreeNode(target, -1) @@ -72,6 +76,7 @@ def buildBlock(exCur, deCur, 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 = {} @@ -93,7 +98,32 @@ def buildBlock(exCur, deCur, target): recursiveCalcBBX(treeRoot, dcv.GRAPH_CONTENTOFFSET_X, bbResult, bb_layer_map) - # calc bb y + # 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 @@ -105,6 +135,10 @@ def buildBlock(exCur, deCur, target): 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 + for i in occupiedLayerCountForSpecificBB.keys(): # add oper occipation + layer_height[i] += occupiedLayerCountForSpecificBB[i] * dcv.GRAPH_SPAN_BB_POPER + + # calc bb Y baseY = dcv.GRAPH_CONTENTOFFSET_Y for i in range(arrangedLayer + 1): baseY += layer_height[i] + dcv.GRAPH_LAYER_SPAN @@ -112,28 +146,72 @@ def buildBlock(exCur, deCur, target): for i in bbResult.keys(): cache = bbResult[i] layer = bb_layer_map[i] - cache.y = layer_y[layer] - layer_height[layer] + cache.height + cache.y = layer_y[layer] - layer_height[layer] - # calc poper + # calc oper position + # flat oper tree operResult = {} - baseX = dcv.GRAPH_CONTENTOFFSET_X exCur.execute('SELECT [thisobj], [op] FROM pOper WHERE [belong_to] == ?', (target, )) + homelessOperCurrentX = dcv.GRAPH_CONTENTOFFSET_X for i in exCur.fetchall(): - cache = dcv.OperResult(i[1], baseX) - cache.computSize() - baseX += cache.width + dcv.GRAPH_BB_SPAN - cache.y = layer_y[1] - cache.height - operResult[i[0]] = cache + 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 + for i in allBB: + cache = bbResult[i] + exCur.execute("SELECT [thisobj] FROM bIn WHERE [belong_to] == ? ORDER BY [index];", (i, )) + for j in exCur.fetchall(): + cache.binData.append(str(j[0])) + exCur.execute("SELECT [thisobj] FROM bOut WHERE [belong_to] == ? ORDER BY [index];", (i, )) + for j in exCur.fetchall(): + cache.boutData.append(str(j[0])) + exCur.execute("SELECT [thisobj] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i, )) + for j in exCur.fetchall(): + cache.pinData.append(str(j[0])) + exCur.execute("SELECT [thisobj] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i, )) + for j in exCur.fetchall(): + cache.poutData.append(str(j[0])) + + # query oper pin's data + for i in operResult.keys(): + cache = operResult[i] + exCur.execute("SELECT [thisobj] FROM pIn WHERE [belong_to] == ? ORDER BY [index];", (i, )) + for j in exCur.fetchall(): + cache.pinData.append(str(j[0])) + exCur.execute("SELECT [thisobj] FROM pOut WHERE [belong_to] == ? ORDER BY [index];", (i, )) + for j in exCur.fetchall(): + cache.poutData.append(str(j[0])) # write to database and return for i in bbResult.keys(): cache = bbResult[i] deCur.execute('INSERT INTO block VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - (target, i, cache.name, cache.assistName, cache.pin, cache.pout, cache.bin, cache.bout, cache.x, cache.y, cache.width, cache.height, cache.expandable)) + (target, i, cache.name, cache.assistName, ','.join(cache.pinData), ','.join(cache.poutData), ','.join(cache.binData), ','.join(cache.boutData), cache.x, cache.y, cache.width, cache.height, cache.expandable)) for i in operResult.keys(): cache = operResult[i] - deCur.execute("INSERT INTO block VALUES (?, ?, ?, '', 2, 1, 0, 0, ?, ?, ?, ?, -1)", - (target, i, cache.name, cache.x, cache.y, cache.width, cache.height)) + deCur.execute("INSERT INTO block VALUES (?, ?, ?, '', ?, ?, '', '', ?, ?, ?, ?, -1)", + (target, i, cache.name, ','.join(cache.pinData), ','.join(cache.poutData), cache.x, cache.y, cache.width, cache.height)) return (layer_y[0] - dcv.CELL_HEIGHT, bbResult, operResult) @@ -143,9 +221,10 @@ def recursiveBuildBBTree(node, exCur, processedBB, layer, depth, graphId): 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(): - realLinkedBB.add(i[0]) + if i[0] != graphId: # omit self + realLinkedBB.add(i[0]) - if (len(cache) == 0): + if (len(realLinkedBB) == 0): return layer # ignore duplicated bb @@ -158,7 +237,7 @@ def recursiveBuildBBTree(node, exCur, processedBB, layer, depth, graphId): for i in realLinkedBB: # recursive execute this method newNode = dcv.BBTreeNode(i, layer) - layer = recursiveBuildBBTree(newNode, exCur, deCur, processedBB, layer, depth + 1, graphId) + layer = recursiveBuildBBTree(newNode, exCur, processedBB, layer, depth + 1, graphId) # add new node into list and ++layer layer+=1 node.nodes.append(newNode) @@ -178,3 +257,35 @@ def recursiveCalcBBX(node, baseX, resultList, layerMap): 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) diff --git a/SuperScriptViewer/ServerCore.py b/SuperScriptViewer/ServerCore.py index 0049ca6..bea3789 100644 --- a/SuperScriptViewer/ServerCore.py +++ b/SuperScriptViewer/ServerCore.py @@ -4,7 +4,9 @@ from flask import render_template from flask import url_for from flask import request +from functools import reduce import sqlite3 +import json import ServerStruct as ss app = Flask(__name__) @@ -21,6 +23,13 @@ def close_connection(exception): if db is not None: db.close() +@app.template_global(name = 'pinDecoder') +def block_pin_filter(target): + if target == '': + return [] + # return json.loads(target) + return target.split(',') + @app.route('/', methods=['GET']) def indexHandle(): cur = get_db().cursor() @@ -43,19 +52,21 @@ def scriptHandle(scriptPath): hamburgerMap = {} hamburger = [] for i in cur.fetchall(): - hamburgerMap[i[0]] = i[1] - for i in pathSlice: - hamburger.append(hamburgerMap[int(i)]) - currentHamburger = hamburger.pop() + hamburgerMap[str(i[0])] = i[1] + currentHamburger = hamburgerMap[pathSlice[-1]] + + for i in range(len(pathSlice) - 1): + hamburger.append(ss.HamburgerItem(hamburgerMap[pathSlice[i]], reduce(lambda x,y: x + '/' + y, pathSlice[0:i + 1], ''))) # get blocks - cur.execute('SELECT * FROM block WHERE [belong_to_graph] = ?', (pathSlice[-1],)) + cur.execute('SELECT * FROM block WHERE [belong_to_graph] = ?', (pathSlice[-1], )) dbBlocks = cur.fetchall() # todo:xxxxx # render return render_template('viewer.html', + currentPath = scriptPath, hamburgerHistory = hamburger, static_css = url_for('static', filename='site.css'), static_js = url_for('static', filename='site.js'), diff --git a/SuperScriptViewer/ServerStruct.py b/SuperScriptViewer/ServerStruct.py index 6b6a49f..0219d06 100644 --- a/SuperScriptViewer/ServerStruct.py +++ b/SuperScriptViewer/ServerStruct.py @@ -2,3 +2,8 @@ class ScriptItem(object): def __init__(self, name, id): self.name = name self.id = id + +class HamburgerItem(object): + def __init__(self, name, path): + self.name = name + self.path = path \ No newline at end of file diff --git a/SuperScriptViewer/SuperScriptViewer.py b/SuperScriptViewer/SuperScriptViewer.py index 2b94a16..bd898c7 100644 --- a/SuperScriptViewer/SuperScriptViewer.py +++ b/SuperScriptViewer/SuperScriptViewer.py @@ -4,7 +4,7 @@ import os import sys # debug use -os.remove('decorate.db') +# os.remove('decorate.db') print('Super Script View') if not os.path.isfile("decorate.db"): @@ -18,4 +18,4 @@ if not os.path.isfile("decorate.db"): print('Decorated database generating done.') # todo: start flask -# ServerCore.run() +ServerCore.run() diff --git a/SuperScriptViewer/static/site.css b/SuperScriptViewer/static/site.css index d30a61f..c86a378 100644 --- a/SuperScriptViewer/static/site.css +++ b/SuperScriptViewer/static/site.css @@ -17,6 +17,24 @@ p.block-text { position: absolute; margin: 0; padding: 0; + font-size: 12px; + color: black; +} + +p.block-expandable-text { + position: absolute; + margin: 0; + padding: 0; + font-size: 12px; + color: #5f5f5f; +} + +p.block-asstext { + position: absolute; + margin: 0; + padding: 0; + font-size: 9px; + color: white } div.block-body { diff --git a/SuperScriptViewer/templates/viewer.html b/SuperScriptViewer/templates/viewer.html index 3a2fd0c..2dcdcea 100644 --- a/SuperScriptViewer/templates/viewer.html +++ b/SuperScriptViewer/templates/viewer.html @@ -16,7 +16,7 @@ {% for i in hamburgerHistory %}

>>

-

{{ i|e }}

+

{{ i.name|e }}

{% endfor %}

>>

@@ -24,36 +24,40 @@
- +
- {% for i in blocks %} -
- {% for pin in range(i[4]) %} -
- {% endfor %} - {% for pout in range(i[5]) %} -
- {% endfor %} - {% for bin in range(i[6]) %} -
- {% endfor %} - {% for bout in range(i[6]) %} -
- {% endfor %} - -

{{ i[2]|e }}

-

{{ i[3]|e }}

-
- {% endfor %} 0 + {% for i in blocks %} +
+ {% for pin in pinDecoder(i[4]) %} +
+ {% endfor %} + {% for pout in pinDecoder(i[5]) %} +
+ {% endfor %} + {% for bin in pinDecoder(i[6]) %} +
+ {% endfor %} + {% for bout in pinDecoder(i[6]) %} +
+ {% endfor %} + + {% if i[12] != -1 %} +

{{ i[2]|e }}

+ {% else %} +

{{ i[2]|e }}

+ {% endif %} +

{{ i[3]|e }}

+
+ {% endfor %}