main.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import matplotlib
  2. matplotlib.use("TkAgg")
  3. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
  4. from matplotlib.figure import Figure
  5. from Tkinter import *
  6. import tkSimpleDialog
  7. import urllib
  8. import urllib2
  9. JUMP = 40
  10. MAX_WIDTH = 20 * JUMP
  11. MAX_HEIGHT = 20 * JUMP
  12. address = "http://127.0.0.1:8001"
  13. root = Tk()
  14. canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white")
  15. canvas.pack()
  16. name = 0
  17. class FakeLayer():
  18. def __init__(self, address):
  19. self.types = {}
  20. self.sources = {}
  21. self.targets = {}
  22. self.attrs = {}
  23. def read_available_attributes(self, name):
  24. if self.types[name] == "const":
  25. return ["value"]
  26. else:
  27. return []
  28. def read_attribute(self, name, attr):
  29. return self.attr.get(name, {}).get(attr, None)
  30. def set_attribute(self, name, attr, value):
  31. self.attrs[name][attr] = value
  32. def instantiate_block(self, name, block_type):
  33. self.types[name] = block_type
  34. def instantiate_link(self, name, link_type, source, target):
  35. self.types[name] = link_type
  36. self.sources[name] = source
  37. self.targets[name] = target
  38. self.attrs[name] = {}
  39. def simulate(self):
  40. pass
  41. def step(self):
  42. pass
  43. def pause(self):
  44. pass
  45. attribute = []
  46. available_attrs = []
  47. simulation = []
  48. #simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
  49. def poll(address):
  50. working_available_attrs = []
  51. working_simulation = None
  52. while 1:
  53. returnvalue = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": "CBD_env"}))).read()
  54. print("Process " + str(returnvalue))
  55. if (returnvalue.startswith("AVAILABLE_ATTR_VALUE")):
  56. working_available_attrs.append((returnvalue.split(" ", 1)[1], None))
  57. elif (returnvalue.startswith("AVAILABLE_ATTR_TYPE")):
  58. working_available_attrs[-1][1] = returnvalue.split(" ", 1)[1]
  59. elif (returnvalue.startswith("AVAILABLE_ATTR_END")):
  60. available_attrs.append(working_available)
  61. working_available = []
  62. elif (returnvalue.startswith("ATTR_VALUE")):
  63. attribute.append(returnvalue.split(" ", 1)[1])
  64. elif (returnvalue.startswith("SIM_TIME")):
  65. working_simulation = (float(returnvalue.split(" ", 1)[1]), {})
  66. elif (returnvalue.startswith("SIM_PROBE")):
  67. blockname, blockvalue = returnvalue.split(" ", 1)[1].rsplit(" ", 1)
  68. working_simulation[1][blockname] = blockvalue
  69. elif (returnvalue.startswith("SIM_END")):
  70. simulation.append(working_simulation)
  71. working_simulation = None
  72. class MvLayer():
  73. def __init__(self, address):
  74. import threading
  75. self.address = address
  76. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"CBD_env"', "username": "user_manager"}))).read()
  77. threading.Thread(target=poll, args=[address])
  78. def read_available_attributes(self, name):
  79. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"read_available_attributes"', "username": "CBD_env"}))).read()
  80. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": "CBD_env"}))).read()
  81. while not available_attrs:
  82. time.sleep(0.1)
  83. return available_attrs.pop(0)
  84. def read_attribute(self, name, attr):
  85. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"read_attribute"', "username": "CBD_env"}))).read()
  86. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": "CBD_env"}))).read()
  87. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % attr, "username": "CBD_env"}))).read()
  88. while not attribute:
  89. time.sleep(0.1)
  90. return attribute.pop(0)
  91. def set_attribute(self, name, attr, value):
  92. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"set_attribute"', "username": "CBD_env"}))).read()
  93. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": "CBD_env"}))).read()
  94. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % attr, "username": "CBD_env"}))).read()
  95. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % value, "username": "CBD_env"}))).read()
  96. def instantiate_block(self, name, block_type):
  97. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"instantiate_node"', "username": "CBD_env"}))).read()
  98. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (block_type), "username": "CBD_env"}))).read()
  99. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (name), "username": "CBD_env"}))).read()
  100. def instantiate_link(self, name, link_type, source, target):
  101. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"instantiate_association"', "username": "CBD_env"}))).read()
  102. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (link_type), "username": "CBD_env"}))).read()
  103. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (name), "username": "CBD_env"}))).read()
  104. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (source), "username": "CBD_env"}))).read()
  105. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (target), "username": "CBD_env"}))).read()
  106. def simulate(self):
  107. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"simulate"', "username": "CBD_env"}))).read()
  108. def step(self):
  109. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"step"', "username": "CBD_env"}))).read()
  110. def pause(self):
  111. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"pause"', "username": "CBD_env"}))).read()
  112. def lower(value):
  113. return value / JUMP * JUMP
  114. def upper(value):
  115. return (value / JUMP + 1) * JUMP
  116. def avg(a, b):
  117. return float(a + b) / 2
  118. class InterfaceCore():
  119. mode = ""
  120. drawn = set()
  121. refs = dict()
  122. mappings = {"+": "AdditionBlock",
  123. "-": "NegationBlock",
  124. }
  125. #mv = MvLayer(address)
  126. mv = FakeLayer(address)
  127. def set_mode(self, mode):
  128. self.mode = mode
  129. def clicked(self, event):
  130. if self.mode not in ["+", "-"]:
  131. print("Cannot create something not guaranteed to be block type!")
  132. else:
  133. if self.find((event.x, event.y)):
  134. # Something already there, so don't add, but modify
  135. lname = self.find((event.x, event.y))
  136. attrs = self.mv.read_available_attributes(lname)
  137. if not attrs:
  138. print("No attrs to manage!")
  139. for attr in attrs:
  140. old_value = self.mv.read_attribute(lname, attr)
  141. new_value = float(tkSimpleDialog.askstring("Attribute modification", attr, initialvalue=old_value))
  142. self.mv.set_attribute(lname, attr, new_value)
  143. else:
  144. global name
  145. x = event.x
  146. y = event.y
  147. self.mv.instantiate_block(str(name), self.mappings[self.mode])
  148. r = canvas.create_rectangle(lower(x), lower(y), upper(x), upper(y), fill="white")
  149. t = canvas.create_text(avg(lower(x), upper(x)), avg(lower(y), upper(y)), text=self.mode, fill="black")
  150. b = (lower(x), lower(y), upper(x), upper(y), str(name))
  151. self.drawn.add(b)
  152. self.refs[str(name)] = [r, t]
  153. name += 1
  154. def find(self, location):
  155. x, y = location
  156. for e in self.drawn:
  157. if (e[0] <= x and
  158. e[1] <= y and
  159. e[2] >= x and
  160. e[3] >= y):
  161. return e[4]
  162. print("Found nothing at that location!")
  163. return []
  164. def draw(self, start, end):
  165. source = self.find(start)
  166. target = self.find(end)
  167. print("Connect from %s to %s" % (source, target))
  168. if source and target:
  169. if self.mode not in ["Link", "IC"]:
  170. print("Cannot create something not guaranteed to be link type!")
  171. else:
  172. global name
  173. self.mv.instantiate_link(str(name), self.mode, source, target)
  174. self.refs[str(name)] = [canvas.create_line(start[0], start[1], end[0], end[1], fill="black", arrow=LAST)]
  175. name += 1
  176. core = InterfaceCore()
  177. def addition():
  178. core.set_mode("+")
  179. def negation():
  180. core.set_mode("-")
  181. def link():
  182. core.set_mode("Link")
  183. def clicked(event):
  184. core.clicked(event)
  185. def draw(event):
  186. global start_location
  187. start_location = (event.x, event.y)
  188. def release(event):
  189. core.draw(start_location, (event.x, event.y))
  190. def simulate():
  191. core.mv.simulate()
  192. def step():
  193. core.mv.step()
  194. def pause():
  195. core.mv.pause()
  196. Button(root, text="+", command=addition).pack()
  197. Button(root, text="-", command=negation).pack()
  198. Button(root, text="Link", command=link).pack()
  199. Button(root, text="SIM", command=simulate).pack()
  200. Button(root, text="STEP", command=step).pack()
  201. Button(root, text="PAUSE", command=pause).pack()
  202. core.canvas = canvas
  203. for i in range(JUMP, MAX_HEIGHT, JUMP):
  204. canvas.create_line(0, i, MAX_HEIGHT, i, fill="grey")
  205. for i in range(JUMP, MAX_WIDTH, JUMP):
  206. canvas.create_line(i, 0, i, MAX_WIDTH, fill="grey")
  207. canvas.bind("<Button-1>", clicked)
  208. canvas.bind("<Button-3>", draw)
  209. canvas.bind("<ButtonRelease-3>", release)
  210. visual = Toplevel(root)
  211. probes = {}
  212. values = {}
  213. #simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
  214. def update_graphs():
  215. while simulation:
  216. t, results = simulation.pop(0)
  217. for k, v in results.items():
  218. if k in probes:
  219. fcanvas, a = probes[k]
  220. else:
  221. f = Figure(figsize=(5,5), dpi=100)
  222. a = f.add_subplot(111)
  223. a.plot([], [])
  224. fcanvas = FigureCanvasTkAgg(f, visual)
  225. fcanvas.show()
  226. fcanvas.get_tk_widget().pack()
  227. probes[k] = (fcanvas, a)
  228. values[k] = ([], [])
  229. values[k][0].append(t)
  230. values[k][1].append(v)
  231. a.clear()
  232. a.plot(values[k][0], values[k][1], linestyle="none", marker="o")
  233. fcanvas.draw()
  234. root.after(50, update_graphs)
  235. root.after(50, update_graphs)
  236. root.mainloop()