summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Seguin <guillaume@segu.in>2008-12-10 18:51:06 +0100
committerGuillaume Seguin <guillaume@segu.in>2008-12-10 18:51:06 +0100
commitb69bd2c0445fba72e34dbea9860c777b3693b5c7 (patch)
tree0cafabc723e3e72048acb0b0e6415755bc20b017
parentdb31e6558492a5d64aa3e9c36479e76428a99afe (diff)
parentc9176fffe77acc381624ea0702cb59692b7c5232 (diff)
downloadsysdigit-master.tar.gz
sysdigit-master.tar.bz2
Merge branch 'master' of git+ssh://ulminfo.aulo.in/home/ixce/sysdigitmaster
-rw-r--r--circuitbuilder/app.py49
-rw-r--r--circuitbuilder/builder.py205
-rw-r--r--circuitbuilder/builder_widget.py147
-rw-r--r--circuitbuilder/circuitbuilder.glade266
-rw-r--r--circuitbuilder/components.py250
-rw-r--r--circuitbuilder/constants.py15
-rw-r--r--circuitbuilder/dialogs.py23
-rw-r--r--circuitbuilder/scriptingwrapper.py20
-rw-r--r--circuitbuilder/scripts/link-base2
-rw-r--r--circuitbuilder/undoredo.py2
-rw-r--r--circuitbuilder/viewer_widget.py27
-rw-r--r--circuitbuilder/xmlhandling.py20
-rw-r--r--simul/Makefile15
-rw-r--r--simul/compil.ml96
-rw-r--r--simul/fulladder.xnl33
-rw-r--r--simul/lexerPaths.ml127
-rw-r--r--simul/lexerPaths.mll17
-rw-r--r--simul/main.ml35
-rwxr-xr-xsimul/maketest7
-rw-r--r--simul/paths2
-rwxr-xr-xutils/tick.c14
-rw-r--r--utils/tick.cpp60
22 files changed, 1205 insertions, 227 deletions
diff --git a/circuitbuilder/app.py b/circuitbuilder/app.py
new file mode 100644
index 0000000..0d4a90e
--- /dev/null
+++ b/circuitbuilder/app.py
@@ -0,0 +1,49 @@
+import glob
+import os.path
+import xmlhandling
+from dialogs import open_dialog
+
+class CircuitApp(object):
+
+ def open_circuit_internal(self, file = None):
+ if not file:
+ file = open_dialog(self.window)
+ if not file:
+ return None, None
+ f = open(file)
+ data = xmlhandling.parse_xml(f, self.component_factory)
+ f.close()
+ return file, data
+
+ def load_all_components(self, paths):
+ for path in paths:
+ components = glob.glob(os.path.join(path, "*.xnl"))
+ for component in components:
+ f = open(component)
+ data = xmlhandling.parse_component_head(f)
+ f.close()
+ self.load_component_real(data)
+
+ def load_component(self, *args):
+ data = self.load_component_internal()
+ if not data:
+ self.push_status("Impossible de charger ce composant")
+ return
+ self.load_component_real(data)
+
+ def load_component_internal(self, searched_name = None):
+ if searched_name:
+ dialog_title = "Charger le composant %s..." % searched_name
+ else:
+ dialog_title = "Charger un composant..."
+ file = open_dialog(self.window, title = dialog_title)
+ if not file:
+ return
+ f = open(file)
+ data = xmlhandling.parse_component_head(f)
+ f.close()
+ return data
+
+ def load_component_real(self, data):
+ component_type = self.component_factory.create_component_type(*data)
+ self.component_factory.register_component_type(component_type)
diff --git a/circuitbuilder/builder.py b/circuitbuilder/builder.py
index 910adfe..d1e2d15 100644
--- a/circuitbuilder/builder.py
+++ b/circuitbuilder/builder.py
@@ -27,6 +27,8 @@ pygtk.require ('2.0')
import gobject
import gtk
import gtk.glade
+import pango
+import gtksourceview2
import sys
import os.path
@@ -36,6 +38,7 @@ from builder_widget import CircuitBuilderWidget
from selector_widget import ComponentSelector
from status_handler import StatusHandler
from undoredo import UndoRedoStack, UndoRedoAction
+from scriptingwrapper import ScriptingWrapper
from constants import *
@@ -43,10 +46,11 @@ import components
from link import Link
from dialogs import open_dialog, save_dialog
import xmlhandling
+from app import CircuitApp
from shared import autoconnect
-class CircuitBuilder(object):
+class CircuitBuilder(CircuitApp):
glade = None
@@ -56,6 +60,8 @@ class CircuitBuilder(object):
status_handler = None
undo_redo_stack = None
+ script_buffer = None
+
component_factory = None
__toolbar_toggles_group = None
@@ -96,6 +102,7 @@ class CircuitBuilder(object):
self.__fill_toolbar_toggles_group()
self.__add_dialogs_buttons()
self.__init_select_link_treeview()
+ self.__init_script_dialog()
self.can_undo = False
self.can_redo = False
@@ -108,12 +115,52 @@ class CircuitBuilder(object):
column = gtk.TreeViewColumn("Lien", text_renderer, text = 1)
treeview.append_column(column)
+ def __init_script_dialog(self):
+ language_manager = gtksourceview2.language_manager_get_default()
+ language = language_manager.get_language(EDITOR_LANGUAGE)
+ style_manager = gtksourceview2.style_scheme_manager_get_default()
+ style_scheme = style_manager.get_scheme(EDITOR_STYLE)
+ self.script_buffer = gtksourceview2.Buffer()
+ self.script_buffer.set_language(language)
+ self.script_buffer.set_style_scheme(style_scheme)
+ sourceview = gtksourceview2.View(self.script_buffer)
+ sourceview.set_auto_indent(True)
+ sourceview.set_indent_on_tab(True)
+ sourceview.set_indent_width(4)
+ sourceview.set_tab_width(4)
+ sourceview.set_insert_spaces_instead_of_tabs(True)
+ sourceview.set_wrap_mode(gtk.WRAP_WORD)
+ font_desc = pango.FontDescription("Monospace 10")
+ sourceview.modify_font(font_desc)
+ sourceview.show()
+ window = self.glade.get_widget("scriptSourceViewWindow")
+ window.add(sourceview)
+ model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+ treeview = self.glade.get_widget("scriptsTreeView")
+ treeview.set_model(model)
+ text_renderer = gtk.CellRendererText ()
+ column = gtk.TreeViewColumn("Script", text_renderer, text = 1)
+ treeview.append_column(column)
+ self.__load_scripts()
+
+ def __load_scripts(self):
+ treeview = self.glade.get_widget("scriptsTreeView")
+ model = treeview.get_model()
+ model.clear()
+ if not os.path.exists("scripts"):
+ return
+ files = os.listdir("scripts")
+ for file in files:
+ path = os.path.join("scripts", file)
+ f = open(path)
+ script = f.read()
+ f.close()
+ model.append((script, file))
+
def reset(self):
- components.Component.auto_id = 1
- components.Input.auto_input_id = 1
- components.Output.auto_output_id = 1
self.__toolbar_toggle_others(None)
self.__switch_select_boxes_visibility(PROPERTIES_COMPONENT_MODE)
+ self.component_factory.reset()
self.builder_widget.reset()
self.selector_widget.reset()
self.undo_redo_stack.reset()
@@ -178,7 +225,8 @@ class CircuitBuilder(object):
saved = property(_get_saved, _set_saved)
def __fill_toolbar_toggles_group(self):
- widgets = ["select", "addGate", "delGate", "addLink", "delLink"]
+ widgets = ["select", "addGate", "moveGate", "scriptGates", "delGate",
+ "addLink", "delLink"]
self.__toolbar_toggles_group = [self.glade.get_widget(w + "Button") \
for w in widgets]
@@ -189,7 +237,8 @@ class CircuitBuilder(object):
dialog.ok_button = dialog.add_button(gtk.STOCK_OK,
gtk.RESPONSE_OK)
for dialog in ("setComponentDialog", "setLinkDialog", "resizeDialog",
- "defineCircuitDialog", "selectLinkDialog"):
+ "defineCircuitDialog", "selectLinkDialog",
+ "scriptDialog"):
dialog = self.glade.get_widget(dialog)
process_dialog(dialog)
@@ -214,28 +263,34 @@ class CircuitBuilder(object):
inputs_hbox.hide()
if hasattr(component, "input_id"):
input_id_hbox.show()
- input_id_spin.set_range(1, component.max_input_id)
+ input_id_spin.set_range(1, component.pool.max_input_id)
input_id_spin.set_value(component.input_id)
else:
input_id_hbox.hide()
if hasattr(component, "output_id"):
output_id_hbox.show()
- output_id_spin.set_range(1, component.max_output_id)
+ output_id_spin.set_range(1, component.pool.max_output_id)
output_id_spin.set_value(component.output_id)
else:
output_id_hbox.hide()
dialog.ok_button.grab_default()
response = dialog.run()
- self.hide_widget(dialog)
+ dialog.hide()
if response != gtk.RESPONSE_OK:
return None
component.id = id_entry.get_text()
if not component.fixed_inputs:
- component.inputs = inputs_spin.get_value()
+ component.inputs = int(inputs_spin.get_value())
if hasattr(component, "input_id"):
- component.input_id = input_id_spin.get_value()
+ new_input_id = int(input_id_spin.get_value())
+ if new_input_id != component.input_id:
+ component.input_id = new_input_id
+ self.builder_widget.redraw_surface()
if hasattr(component, "output_id"):
- component.output_id = output_id_spin.get_value()
+ new_output_id = int(output_id_spin.get_value())
+ if new_output_id != component.output_id:
+ component.output_id = new_output_id
+ self.builder_widget.redraw_surface()
self.saved = False
return component
@@ -254,7 +309,7 @@ class CircuitBuilder(object):
return None
else:
output_id_spin.set_range(1, start.outputs)
- output_id_spin.set_value(1)
+ output_id_spin.set_value(start.first_available_output)
output_id_hbox.show()
if end.inputs == 1:
input_id = 1
@@ -263,19 +318,27 @@ class CircuitBuilder(object):
# FIXME : verbose me!
return None
else:
+ default_input_id = end.first_available_input
+ if default_input_id == -1:
+ # FIXME : verbose me!
+ return None
input_id_spin.set_range(1, end.inputs)
- input_id_spin.set_value(1)
+ input_id_spin.set_value(default_input_id)
input_id_hbox.show()
if not output_id or not input_id:
dialog.ok_button.grab_default()
response = dialog.run()
- self.hide_widget(dialog)
+ dialog.hide()
if response != gtk.RESPONSE_OK:
return None
if start.outputs != 1:
output_id = output_id_spin.get_value()
if end.inputs != 1:
input_id = input_id_spin.get_value()
+ used_inputs = [link.input_id for link in end.parent_links]
+ if input_id in used_inputs:
+ # FIXME : verbose me!
+ return None
link = Link(start, output_id, end, input_id)
self.saved = False
return link
@@ -310,12 +373,9 @@ class CircuitBuilder(object):
self.reset()
def open_circuit(self, *args):
- file = open_dialog(self.window)
- if not file:
+ file, data = self.open_circuit_internal()
+ if data == False:
return
- f = open(file)
- data = xmlhandling.parse_xml(f, self.component_factory)
- f.close()
if not data:
self.push_status("Impossible de charger ce circuit")
return
@@ -329,39 +389,6 @@ class CircuitBuilder(object):
min_height)
self.builder_widget.components = components
- def load_all_components(self, paths):
- for path in paths:
- components = glob.glob(os.path.join(path, "*.xnl"))
- for component in components:
- f = open(component)
- data = xmlhandling.parse_component_head(f)
- f.close()
- self.load_component_real(data)
-
- def load_component(self, *args):
- data = self.load_component_internal()
- if not data:
- self.push_status("Impossible de charger ce composant")
- return
- self.load_component_real(data)
-
- def load_component_internal(self, searched_name = None):
- if searched_name:
- dialog_title = "Charger le composant %s..." % searched_name
- else:
- dialog_title = "Charger un composant..."
- file = open_dialog(self.window, title = dialog_title)
- if not file:
- return
- f = open(file)
- data = xmlhandling.parse_component_head(f)
- f.close()
- return data
-
- def load_component_real(self, data):
- component_type = self.component_factory.create_component_type(*data)
- self.component_factory.register_component_type(component_type)
-
def save_circuit(self, *args):
if not self.__filename:
self.save_circuit_as()
@@ -391,7 +418,7 @@ class CircuitBuilder(object):
symbol_entry.set_text("")
dialog.ok_button.grab_default()
response = dialog.run()
- self.hide_widget(dialog)
+ dialog.hide()
if response != gtk.RESPONSE_OK:
return None
self.name = name_entry.get_text()
@@ -420,7 +447,7 @@ class CircuitBuilder(object):
heightSpin.set_value(self.builder_widget.height)
dialog.ok_button.grab_default()
response = dialog.run()
- self.hide_widget(dialog)
+ dialog.hide()
if response != gtk.RESPONSE_OK:
return None
self.builder_widget.width = int(widthSpin.get_value())
@@ -450,6 +477,9 @@ class CircuitBuilder(object):
PROPERTIES_LINK_MODE)
def choose_link(self, links):
+ def link_cmp(l1, l2):
+ return cmp(str(l1), str(l2))
+ links.sort(cmp = link_cmp)
dialog = self.glade.get_widget("selectLinkDialog")
treeview = self.glade.get_widget("selectLinkDialogTreeView")
model = treeview.get_model()
@@ -458,7 +488,7 @@ class CircuitBuilder(object):
model.append((link, str(link)))
dialog.ok_button.grab_default()
response = dialog.run()
- self.hide_widget(dialog)
+ dialog.hide()
if response != gtk.RESPONSE_OK:
return None
_, iter = treeview.get_selection().get_selected()
@@ -574,6 +604,49 @@ class CircuitBuilder(object):
output_spin.set_value(link.output_id)
self.selected_link = link
+ def script(self):
+ components = self.builder_widget.scripted_components
+ dialog = self.glade.get_widget("scriptDialog")
+ components_label = self.glade.get_widget("componentsCountValueLabel")
+ components_label.set_text("%d" % len(components))
+ dialog.ok_button.grab_default()
+ response = dialog.run()
+ dialog.hide()
+ if response != gtk.RESPONSE_OK:
+ return None
+ script = self.script_buffer.get_text(*self.script_buffer.get_bounds())
+ script = script.strip()
+ if not script:
+ return None
+ compiled_script = compile(script, "<string>", "exec")
+ exec compiled_script in {"components": components,
+ "builder": ScriptingWrapper(self)}
+
+ def save_script(self, *args):
+ filename = save_dialog(self.window, ext = "")
+ if not filename:
+ return
+ f = open(filename, "w")
+ data = self.script_buffer.get_text(*self.script_buffer.get_bounds())
+ f.write(data)
+ f.close()
+ self.__load_scripts()
+
+ def select_script(self, treeview, path, view_column):
+ model = treeview.get_model()
+ iter = model.get_iter(path)
+ data = model.get_value(iter, 0)
+ self.script_buffer.set_text(data)
+
+ def launch_script_dialog(self, *args):
+ self.script()
+
+ def reset_selections(self, *args):
+ self.builder_widget.reset_add_link()
+ self.builder_widget.reset_move_gate()
+ self.builder_widget.reset_script_gates()
+ self.builder_widget.queue_draw()
+
def set_select_mode(self, widget, *args):
if widget.get_active():
self.__toolbar_toggle_others(widget)
@@ -589,6 +662,20 @@ class CircuitBuilder(object):
self.__toolbar_toggle_others(widget)
self.builder_widget.action = BUILDER_ACTION_ADD_GATE
+ def set_move_gate_mode(self, widget, *args):
+ if widget.get_active():
+ self.__toolbar_toggle_others(widget)
+ self.builder_widget.action = BUILDER_ACTION_MOVE_GATE
+ else:
+ self.builder_widget.reset_move_gate()
+
+ def set_script_gates_mode(self, widget, *args):
+ if widget.get_active():
+ self.__toolbar_toggle_others(widget)
+ self.builder_widget.action = BUILDER_ACTION_SCRIPT_GATES
+ else:
+ self.builder_widget.reset_script_gates()
+
def set_del_gate_mode(self, widget, *args):
if widget.get_active():
self.__toolbar_toggle_others(widget)
@@ -612,6 +699,12 @@ class CircuitBuilder(object):
def toggle_add_gate_mode(self, *args):
self.glade.get_widget("addGateButton").set_active(True)
+ def toggle_move_gate_mode(self, *args):
+ self.glade.get_widget("moveGateButton").set_active(True)
+
+ def toggle_script_gates_mode(self, *args):
+ self.glade.get_widget("scriptGatesButton").set_active(True)
+
def toggle_del_gate_mode(self, *args):
self.glade.get_widget("delGateButton").set_active(True)
diff --git a/circuitbuilder/builder_widget.py b/circuitbuilder/builder_widget.py
index 6b70ca9..ba42fa6 100644
--- a/circuitbuilder/builder_widget.py
+++ b/circuitbuilder/builder_widget.py
@@ -30,16 +30,36 @@ import cairo
from constants import *
from undoredo import UndoRedoAction
-from viewer_widget import CircuitViewerWidget
+from viewer_widget import CircuitViewerWidget, dist
class CircuitBuilderWidget(CircuitViewerWidget):
__first_link_component = None
+ __moving_component_surface = None
+ __moving_component = None
+ scripted_components = None
def __init__(self, parent, *args, **kwargs):
super(CircuitBuilderWidget, self).__init__(parent, *args, **kwargs)
+ self.__moving_component_surface = \
+ cairo.ImageSurface(cairo.FORMAT_ARGB32, PART_SIZE, PART_SIZE)
self.connect("motion-notify-event", self.__motion_notify_cb)
self.connect("button-press-event", self.__button_press_cb)
+ self.scripted_components = []
+
+ def __can_move(self, x, y):
+ (c_x, c_y) = self.__moving_component.x, self.__moving_component.y
+ for (i, j) in self._components_keys:
+ if (i, j) == (c_x, c_y):
+ continue
+ if i > x + PART_SIZE:
+ return True
+ if i < x - PART_SIZE or abs(j - y) > PART_SIZE:
+ continue
+ if dist(i, j, x, y) > PART_SIZE:
+ continue
+ return False
+ return True
def __can_add(self, x, y):
for (i, j) in self._components_keys:
@@ -47,6 +67,8 @@ class CircuitBuilderWidget(CircuitViewerWidget):
return True
if i < x - PART_SIZE or abs(j - y) > PART_SIZE:
continue
+ if dist(i, j, x, y) > PART_SIZE:
+ continue
return False
return True
@@ -63,6 +85,7 @@ class CircuitBuilderWidget(CircuitViewerWidget):
def restore_component(self, component):
self.add_component(component)
+ component.add_to_pool()
restored_links = component.restore_links()
for link in restored_links:
self.add_link(link)
@@ -77,6 +100,7 @@ class CircuitBuilderWidget(CircuitViewerWidget):
component.x = x
component.y = y
if not self._parent.set_component(component):
+ component.drop_from_pool()
self._parent.push_status("Création du composant annulée")
return
self.add_component(component)
@@ -85,16 +109,48 @@ class CircuitBuilderWidget(CircuitViewerWidget):
self._parent.undo_redo_stack.add_to_stack(action)
self._parent.push_status("Composant ajouté")
+ def __move_component_at(self, x, y):
+ if not self.__moving_component:
+ component = self._get_component_at(x, y)
+ if component:
+ self.__moving_component = component
+ self._make_component_surface(self.__moving_component_surface,
+ self.__moving_component)
+ return
+ x, y = self._translate_middle_coords(x, y)
+ if self.__can_move(x, y):
+ component = self.__moving_component
+ x0, y0 = component.x, component.y
+ component.x, component.y = x, y
+ del self._components[x0, y0]
+ self._components_keys.remove((x0, y0))
+ self._components[(x, y)] = component
+ self._components_keys.append((x, y))
+ self._components_keys.sort()
+ for link in component.parent_links + component.child_links:
+ del self._links_squares[link]
+ start = link.output_gate
+ end = link.input_gate
+ self._links_squares[link] = self._get_link_square(start, end)
+ self.redraw_surface()
+ self.__moving_component = None
+
+ def __script_component_at(self, x, y):
+ component = self._get_component_at(x, y)
+ if not component:
+ return
+ self.scripted_components.append(component)
+
def del_component(self, component):
x, y = component.x, component.y
self._components_keys.remove((x, y))
del self._components[(x, y)]
component.destroy_links()
+ component.drop_from_pool()
for link in self._links_squares.keys():
if component in (link.output_gate, link.input_gate):
del self._links_squares[link]
- self._redraw_surface()
- self.queue_draw()
+ self.redraw_surface()
def __del_component_at(self, x, y):
component = self._get_component_at(x, y)
@@ -139,18 +195,20 @@ différents''')
if not link:
self._parent.push_status("Création du lien annulée")
return
- self.add_link(link)
- action = UndoRedoAction(action = ACTION_ADD_LINK, link = link)
- self._parent.undo_redo_stack.add_to_stack(action)
+ self.add_link_internal(link)
# Reset add link process
self.reset_add_link()
self._parent.push_status("Lien ajouté")
+ def add_link_internal(self, link):
+ self.add_link(link)
+ action = UndoRedoAction(action = ACTION_ADD_LINK, link = link)
+ self._parent.undo_redo_stack.add_to_stack(action)
+
def del_link(self, link):
link.destroy()
del self._links_squares[link]
- self._redraw_surface()
- self.queue_draw()
+ self.redraw_surface()
def __del_link_at(self, x, y):
link = self._get_link_at(x, y)
@@ -163,6 +221,32 @@ différents''')
self._parent.push_status("Lien supprimé")
def _update_overlay(self, cr):
+ def draw_gate_op_attempt(x0, y0, surface, color):
+ cr.save()
+ cr.rectangle(x0, y0, PART_SIZE, PART_SIZE)
+ cr.clip()
+ cr.set_source_rgb(*color)
+ cr.mask_surface(surface, x0, y0)
+ cr.set_operator(cairo.OPERATOR_OVER)
+ cr.stroke()
+ cr.restore()
+ def draw_gate_add_attempt():
+ x0, y0 = self._translate_middle_coords(self._current_x,
+ self._current_y)
+ if self.__can_add(x0, y0):
+ color = OK_COLOR
+ else:
+ color = NOTOK_COLOR
+ draw_gate_op_attempt(x0, y0, self._component_surface, color)
+ def draw_gate_move_attempt():
+ x0, y0 = self._translate_middle_coords(self._current_x,
+ self._current_y)
+ if self.__can_move(x0, y0):
+ color = OK_COLOR
+ else:
+ color = NOTOK_COLOR
+ draw_gate_op_attempt(x0, y0, self.__moving_component_surface,
+ color)
if self._current_x == -1:
return
x0 = self._current_x
@@ -186,18 +270,31 @@ différents''')
for link in links:
self._overlay_link(cr, link, AUDIT_COLOR)
elif self.action == BUILDER_ACTION_ADD_GATE:
- x0, y0 = self._translate_middle_coords(x0, y0)
- cr.save()
- cr.rectangle(x0, y0, PART_SIZE, PART_SIZE)
- cr.clip()
- if self.__can_add(x0, y0):
- color = OK_COLOR
+ draw_gate_add_attempt()
+ elif self.action == BUILDER_ACTION_MOVE_GATE:
+ if self.__moving_component:
+ cr.save()
+ self._overlay_component(cr, self.__moving_component, OK_COLOR)
+ cr.restore()
+ draw_gate_move_attempt()
else:
- color = NOTOK_COLOR
- cr.set_source_rgb(*color)
- cr.mask_surface(self._component_surface, x0, y0)
- cr.set_operator(cairo.OPERATOR_OVER)
- cr.stroke()
+ component = self._get_component_at(x0, y0)
+ if not component:
+ return
+ cr.save()
+ self._overlay_component(cr, component, OK_COLOR)
+ cr.restore()
+ elif self.action == BUILDER_ACTION_SCRIPT_GATES:
+ if self.scripted_components:
+ for component in self.scripted_components:
+ cr.save()
+ self._overlay_component(cr, component, OK_COLOR)
+ cr.restore()
+ component = self._get_component_at(x0, y0)
+ if not component:
+ return
+ cr.save()
+ self._overlay_component(cr, component, OK_COLOR)
cr.restore()
elif self.action == BUILDER_ACTION_DEL_GATE:
component = self._get_component_at(x0, y0)
@@ -230,6 +327,12 @@ différents''')
def reset_add_link(self):
self.__first_link_component = None
+ def reset_move_gate(self):
+ self.__moving_component = None
+
+ def reset_script_gates(self):
+ self.scripted_components = []
+
def __button_press_cb(self, widget, event):
if self.action == BUILDER_ACTION_SELECT:
x0, y0 = event.x, event.y
@@ -237,6 +340,12 @@ différents''')
elif self.action == BUILDER_ACTION_ADD_GATE:
x0, y0 = self._translate_middle_coords(event.x, event.y)
self.__add_component_at(x0, y0)
+ elif self.action == BUILDER_ACTION_MOVE_GATE:
+ x0, y0 = event.x, event.y
+ self.__move_component_at(x0, y0)
+ elif self.action == BUILDER_ACTION_SCRIPT_GATES:
+ x0, y0 = event.x, event.y
+ self.__script_component_at(x0, y0)
elif self.action == BUILDER_ACTION_DEL_GATE:
x0, y0 = event.x, event.y
self.__del_component_at(x0, y0)
diff --git a/circuitbuilder/circuitbuilder.glade b/circuitbuilder/circuitbuilder.glade
index 8a0e739..8ba4c1f 100644
--- a/circuitbuilder/circuitbuilder.glade
+++ b/circuitbuilder/circuitbuilder.glade
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.5 on Mon Nov 3 04:09:08 2008 -->
+<!--Generated with glade3 3.4.5 on Sat Nov 8 01:38:09 2008 -->
<glade-interface>
<widget class="GtkWindow" id="mainWindow">
<property name="title" translatable="yes">Logic Circuit Builder</property>
<property name="window_position">GTK_WIN_POS_CENTER</property>
- <property name="default_width">700</property>
- <property name="default_height">500</property>
+ <property name="default_width">800</property>
+ <property name="default_height">600</property>
<signal name="delete_event" handler="gtk_main_quit"/>
<child>
<widget class="GtkVBox" id="mainVBox">
@@ -128,7 +128,7 @@
<child>
<widget class="GtkImageMenuItem" id="selectMenuItem">
<property name="visible">True</property>
- <property name="label" translatable="yes">gtk-properties</property>
+ <property name="label" translatable="yes">gtk-info</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="toggle_select_mode"/>
@@ -151,6 +151,36 @@
</widget>
</child>
<child>
+ <widget class="GtkImageMenuItem" id="moveMenuItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Déplacer</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="toggle_move_gate_mode"/>
+ <accelerator key="M" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image4">
+ <property name="visible">True</property>
+ <property name="stock">gtk-jump-to</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="scriptGatesMenuItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Scripter des portes</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="toggle_script_gates_mode"/>
+ <accelerator key="W" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image5">
+ <property name="visible">True</property>
+ <property name="stock">gtk-index</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
<widget class="GtkImageMenuItem" id="delGateMenuItem">
<property name="visible">True</property>
<property name="label" translatable="yes">gtk-remove</property>
@@ -195,6 +225,41 @@
</widget>
</child>
<child>
+ <widget class="GtkImageMenuItem" id="scriptMenuItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Scripter</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="launch_script_dialog"/>
+ <accelerator key="X" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image6">
+ <property name="visible">True</property>
+ <property name="stock">gtk-edit</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkImageMenuItem" id="resetMenuItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Réinitialiser la sélection</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="reset_selections"/>
+ <accelerator key="Escape" modifiers="" signal="activate"/>
+ <child internal-child="image">
+ <widget class="GtkImage" id="menu-item-image7">
+ <property name="visible">True</property>
+ <property name="stock">gtk-cancel</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="editMenuSeparator5">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
<widget class="GtkImageMenuItem" id="resizeMenuItem">
<property name="visible">True</property>
<property name="label" translatable="yes">Élargir le circuit</property>
@@ -280,7 +345,7 @@
<property name="visible">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text">Sélectionner un composant ou un lien</property>
- <property name="stock_id">gtk-properties</property>
+ <property name="stock_id">gtk-info</property>
<signal name="toggled" handler="set_select_mode"/>
</widget>
<packing>
@@ -308,6 +373,30 @@
</packing>
</child>
<child>
+ <widget class="GtkToggleToolButton" id="moveGateButton">
+ <property name="visible">True</property>
+ <property name="tooltip_text">Déplacer un composant</property>
+ <property name="label" translatable="yes">Déplacer</property>
+ <property name="stock_id">gtk-jump-to</property>
+ <signal name="toggled" handler="set_move_gate_mode"/>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToggleToolButton" id="scriptGatesButton">
+ <property name="visible">True</property>
+ <property name="tooltip_text">Scripter des composants</property>
+ <property name="label" translatable="yes">Scripter des portes</property>
+ <property name="stock_id">gtk-index</property>
+ <signal name="toggled" handler="set_script_gates_mode"/>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkToggleToolButton" id="delGateButton">
<property name="visible">True</property>
<property name="has_tooltip">True</property>
@@ -351,6 +440,25 @@
<property name="homogeneous">True</property>
</packing>
</child>
+ <child>
+ <widget class="GtkSeparatorToolItem" id="toolbarSeparator4">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkToolButton" id="scriptButton">
+ <property name="visible">True</property>
+ <property name="tooltip_text">Scripter</property>
+ <property name="stock_id">gtk-edit</property>
+ <signal name="clicked" handler="launch_script_dialog"/>
+ </widget>
+ <packing>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
@@ -361,7 +469,7 @@
<widget class="GtkHPaned" id="mainPaned">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="position">500</property>
+ <property name="position">600</property>
<child>
<widget class="GtkScrolledWindow" id="builderWindow">
<property name="visible">True</property>
@@ -1286,4 +1394,150 @@
</widget>
</child>
</widget>
+ <widget class="GtkDialog" id="scriptDialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Sélection du script</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="default_width">700</property>
+ <property name="default_height">500</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox11">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkHPaned" id="scriptDialogHPaned">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">520</property>
+ <child>
+ <widget class="GtkVBox" id="scriptDialogVBox">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkHBox" id="componentsCountHBox">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="componentsCountLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Portes sélectionnées : </property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="componentsCountValueLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scriptSourceViewWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="scriptSaveAlignment">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">5</property>
+ <property name="right_padding">5</property>
+ <child>
+ <widget class="GtkButton" id="scriptSaveButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-save</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="save_script"/>
+ <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="scriptsVBox">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="scriptsLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Scripts disponibles :</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTreeView" id="scriptsTreeView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <signal name="row_activated" handler="select_script"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area11">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/circuitbuilder/components.py b/circuitbuilder/components.py
index d0accad..5eff5de 100644
--- a/circuitbuilder/components.py
+++ b/circuitbuilder/components.py
@@ -23,7 +23,7 @@ class Component(object):
auto_id = 1
- id = ""
+ _id = None
symbol = ""
outputs = 1
@@ -45,8 +45,10 @@ class Component(object):
outputs_status = None
- def __init__(self):
- self.id = "g%d" % Component.auto_id
+ pool = None
+
+ def __init__(self, **kwargs):
+ self._id = "g%d" % Component.auto_id
Component.auto_id += 1
self.parent_links = []
self.child_links = []
@@ -54,10 +56,58 @@ class Component(object):
self.outputs_status = {}
if self.fixed_inputs:
self.min_inputs = self.max_inputs = self.inputs
+ for attr in kwargs:
+ setattr(self, attr, kwargs[attr])
+ self.add_to_pool()
def __str__(self):
return "[%s %s]" % (self.__class__.__name__, self.id)
+ def _set_component_id(self, id):
+ old_id, self._id = self._id, id
+ self.pool.set_component_id(self, old_id)
+
+ def _get_component_id(self):
+ return self._id
+
+ id = property(_get_component_id, _set_component_id)
+
+ def add_to_pool(self):
+ self.pool.register_component(self)
+
+ def drop_from_pool(self):
+ self.pool.unregister_component(self)
+
+ def links_to(self, end):
+ def check_end(link):
+ return link.input_gate == end
+ return filter(check_end, self.child_links)
+
+ def links_from(self, start):
+ def check_start(link):
+ return link.output_gate == end
+ return filter(check_start, self.parent_links)
+
+ def _get_first_available_input(self):
+ used_inputs = [link.input_id for link in self.parent_links]
+ r = range(1, self.inputs + 1)
+ free_inputs = filter(lambda i: i not in used_inputs, r)
+ if not free_inputs:
+ return -1
+ return free_inputs[0]
+
+ first_available_input = property(_get_first_available_input)
+
+ def _get_first_available_output(self):
+ used_outputs = [link.output_id for link in self.child_links]
+ r = range(1, self.outputs + 1)
+ free_outputs = filter(lambda i: i not in used_outputs, r)
+ if not free_outputs:
+ return 1
+ return free_outputs[0]
+
+ first_available_output = property(_get_first_available_output)
+
def add_link(self, link):
if (link.output_gate == self):
self.child_links.append(link)
@@ -112,34 +162,54 @@ class Xor(Component):
class Input(Component):
symbol = "i"
- auto_input_id = 1
- input_id = 0
- max_input_id = 128
+ _input_id = 0
fixed_inputs = True
inputs = 0
outputs = 1
- def __init__(self):
- super(Input, self).__init__()
- self.input_id = Input.auto_input_id
- Input.auto_input_id += 1
+ def add_to_pool(self):
+ super(Input, self).add_to_pool()
+ self.pool.register_input(self)
+
+ def drop_from_pool(self):
+ super(Input, self).drop_from_pool()
+ self.pool.unregister_input(self)
+
+ def set_input_id(self, id):
+ self.pool.set_input_id(self, id)
+ self._input_id = id
+
+ def get_input_id(self):
+ return self._input_id
+
+ input_id = property(get_input_id, set_input_id)
class Output(Component):
symbol = "o"
- auto_output_id = 1
- output_id = 0
- max_output_id = 128
+ _output_id = 0
fixed_inputs = True
inputs = 1
outputs = 0
- def __init__(self):
- super(Output, self).__init__()
- self.output_id = Output.auto_output_id
- Output.auto_output_id += 1
+ def add_to_pool(self):
+ super(Output, self).add_to_pool()
+ self.pool.register_output(self)
+
+ def drop_from_pool(self):
+ super(Output, self).drop_from_pool()
+ self.pool.unregister_output(self)
+
+ def _set_output_id(self, id):
+ self.pool.set_output_id(self, id)
+ self._output_id = id
+
+ def _get_output_id(self):
+ return self._output_id
+
+ output_id = property(_get_output_id, _set_output_id)
class Reg(Component):
@@ -185,32 +255,168 @@ class Zero(Component):
fixed_inputs = True
inputs = 0
+class RAMR(Component):
+
+ symbol = "RAMR"
+
+ fixed_inputs = True
+ inputs = 16
+
+ outputs = 8
+
+class RAMW(Component):
+
+ symbol = "RAMW"
+
+ fixed_inputs = True
+ inputs = 24
+
+ outputs = 0
+
+class ROMR(Component):
+
+ symbol = "ROMR"
+
+ fixed_inputs = True
+ inputs = 16
+
+ outputs = 8
+
DEFAULT_COMPONENT_TYPES = [Not, And, Or, Nand, Nor, Xor, Input, Output,
- Reg, RegInput, RegOutput, Mux, One, Zero]
+ Reg, RegInput, RegOutput, Mux, One, Zero,
+ RAMR, RAMW, ROMR]
+
+class ComponentsPool(object):
+
+ components = None
+
+ inputs = None
+ outputs = None
+
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ self.components = {}
+ self.inputs = {}
+ self.outputs = {}
+
+ def register_component(self, component):
+ id = component.id
+ if id not in self.components:
+ self.components[id] = component
+ return
+ i = 1
+ id = "%ss%d" % (component.id, i)
+ while id in self.components:
+ i += 1
+ id = "%ss%d" % (component.id, i)
+ component._id = id
+ self.components[id] = component
+
+ def register_input(self, input):
+ id = self.min_free_input_id
+ if input.input_id == 0:
+ input._input_id = id
+ self.inputs[id] = input
+
+ def register_output(self, output):
+ id = self.min_free_output_id
+ if output.output_id == 0:
+ output._output_id = id
+ self.outputs[id] = output
+
+ def unregister_component(self, component):
+ del self.components[component.id]
+
+ def unregister_input(self, input):
+ del self.inputs[input.input_id]
+
+ def unregister_output(self, output):
+ del self.outputs[output.output_id]
+
+ def set_component_id(self, component, old_id):
+ del self.components[old_id]
+ self.register_component(component)
+
+ def set_input_id(self, input, id):
+ if input.input_id == id:
+ return
+ if id in self.inputs:
+ old_input = self.inputs[id]
+ old_input._input_id = input.input_id
+ self.inputs[input.input_id] = old_input
+ self.inputs[id] = input
+
+ def set_output_id(self, output, id):
+ if output.output_id == id:
+ return
+ if id in self.outputs:
+ old_output = self.outputs[id]
+ old_output._output_id = output.output_id
+ self.outputs[output.output_id] = old_output
+ self.outputs[id] = output
+
+ def get_min_free_input_id(self):
+ ids = self.inputs.keys()
+ r = range(1, max(self.max_input_id + 1, len(ids) + 1) + 1)
+ free_ids = filter(lambda i: i not in ids, r)
+ return min(free_ids)
+
+ min_free_input_id = property(get_min_free_input_id)
+
+ def get_min_free_output_id(self):
+ ids = self.outputs.keys()
+ r = range(1, max(self.max_output_id + 1, len(ids) + 1) + 1)
+ free_ids = filter(lambda i: i not in ids, r)
+ return min(free_ids)
+
+ min_free_output_id = property(get_min_free_output_id)
+
+ def get_max_input_id(self):
+ if not self.inputs:
+ return 0
+ return max(self.inputs.keys())
+
+ max_input_id = property(get_max_input_id)
+
+ def get_max_output_id(self):
+ if not self.outputs:
+ return 0
+ return max(self.outputs.keys())
+
+ max_output_id = property(get_max_output_id)
class ComponentFactory(object):
component_types = None
+ pool = None
+
__register_cb = None
__component_loader = None
def __init__(self, register_cb, component_loader):
self.component_types = {}
+ self.pool = ComponentsPool()
self.__register_cb = register_cb
self.__component_loader = component_loader
self.__register_default_types()
+ def reset(self):
+ self.pool.reset()
+
def __register_default_types(self):
for component_type in DEFAULT_COMPONENT_TYPES:
self.register_component_type(component_type)
def register_component_type(self, component_type):
+ component_type.pool = self.pool
self.component_types[component_type.__name__] = component_type
if self.__register_cb:
self.__register_cb(component_type)
- def create_component(self, component_type):
+ def create_component(self, component_type, initial_data = None):
if component_type not in self.component_types:
data = self.__component_loader(searched_name = component_type)
if not data:
@@ -220,10 +426,14 @@ class ComponentFactory(object):
return None
component_type_class = self.create_component_type(*data)
self.register_component_type(component_type_class)
- return self.component_types[component_type]()
+ if initial_data:
+ return self.component_types[component_type](**initial_data)
+ else:
+ return self.component_types[component_type]()
def create_component_type(self, circuit, name, symbol, inputs, outputs):
component_type = type(name, (Component,), {"is_simple": False})
+ component_type.pool = self.pool
component_type.circuit = circuit
component_type.symbol = symbol
component_type.fixed_inputs = True
diff --git a/circuitbuilder/constants.py b/circuitbuilder/constants.py
index 121e3f8..c768273 100644
--- a/circuitbuilder/constants.py
+++ b/circuitbuilder/constants.py
@@ -41,11 +41,13 @@ LINK_ARROW_RAD = radians(35.0)
BUILDER_MAX_WIDTH = 2000
BUILDER_MAX_HEIGHT = 2000
-BUILDER_ACTION_SELECT = 0
-BUILDER_ACTION_ADD_GATE = 1
-BUILDER_ACTION_DEL_GATE = 2
-BUILDER_ACTION_ADD_LINK = 3
-BUILDER_ACTION_DEL_LINK = 4
+BUILDER_ACTION_SELECT = 0
+BUILDER_ACTION_ADD_GATE = 1
+BUILDER_ACTION_MOVE_GATE = 2
+BUILDER_ACTION_SCRIPT_GATES = 3
+BUILDER_ACTION_DEL_GATE = 4
+BUILDER_ACTION_ADD_LINK = 5
+BUILDER_ACTION_DEL_LINK = 6
ACTION_ADD_GATE = 0
ACTION_DEL_GATE = 1
@@ -58,3 +60,6 @@ PROPERTIES_COMPONENT_MODE = 0
PROPERTIES_IN_MODE = 1
PROPERTIES_OUT_MODE = 2
PROPERTIES_LINK_MODE = 3
+
+EDITOR_LANGUAGE = "python"
+EDITOR_STYLE = "kate"
diff --git a/circuitbuilder/dialogs.py b/circuitbuilder/dialogs.py
index 0464036..6dea982 100644
--- a/circuitbuilder/dialogs.py
+++ b/circuitbuilder/dialogs.py
@@ -1,12 +1,13 @@
import gtk
-def get_file_filters(all_files = False):
+def get_file_filters(all_files = False, ext = ""):
filters = []
- filter = gtk.FileFilter()
- filter.set_name('.xnl')
- filter.add_pattern('*.xnl')
- filters.append(filter)
+ if ext:
+ filter = gtk.FileFilter()
+ filter.set_name(ext)
+ filter.add_pattern('*%s' % ext)
+ filters.append(filter)
if all_files:
filter = gtk.FileFilter()
filter.set_name("Tous les fichiers")
@@ -14,13 +15,13 @@ def get_file_filters(all_files = False):
filters.append(filter)
return filters
-def file_dialog(name, action, button, parent):
+def file_dialog(name, action, button, parent, ext):
dialog = gtk.FileChooserDialog(name, None, action,
(gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
button,
gtk.RESPONSE_OK))
- map(dialog.add_filter, get_file_filters(all_files = True))
+ map(dialog.add_filter, get_file_filters(all_files = True, ext = ext))
dialog.set_default_size(500, 300)
dialog.set_position(gtk.WIN_POS_CENTER)
dialog.set_icon(parent.get_icon())
@@ -32,12 +33,12 @@ def file_dialog(name, action, button, parent):
dialog.destroy()
return file
-def open_dialog(parent, title = "Ouvrir..."):
+def open_dialog(parent, title = "Ouvrir un circuit...", ext = ".xnl"):
action = gtk.FILE_CHOOSER_ACTION_OPEN
button = gtk.STOCK_OPEN
- return file_dialog(title, action, button, parent)
+ return file_dialog(title, action, button, parent, ext)
-def save_dialog(parent):
+def save_dialog(parent, ext = ".xnl"):
action = gtk.FILE_CHOOSER_ACTION_SAVE
button = gtk.STOCK_SAVE
- return file_dialog("Enregistrer sous...", action, button, parent)
+ return file_dialog("Enregistrer sous...", action, button, parent, ext)
diff --git a/circuitbuilder/scriptingwrapper.py b/circuitbuilder/scriptingwrapper.py
new file mode 100644
index 0000000..4679679
--- /dev/null
+++ b/circuitbuilder/scriptingwrapper.py
@@ -0,0 +1,20 @@
+from link import Link
+
+class ScriptingWrapper(object):
+
+ builder_widget = None
+ component_factory = None
+
+ def __init__(self, app):
+ self.builder_widget = app.builder_widget
+ self.component_factory = app.component_factory
+
+ def add_link(self, output_gate, output_id, input_gate, input_id):
+ link = Link(output_gate, output_id, input_gate, input_id)
+ self.builder_widget.add_link_internal(link)
+
+ def get_component(self, id):
+ try:
+ return self.component_factory.pool.components[id]
+ except KeyError:
+ return None
diff --git a/circuitbuilder/scripts/link-base b/circuitbuilder/scripts/link-base
new file mode 100644
index 0000000..4d23124
--- /dev/null
+++ b/circuitbuilder/scripts/link-base
@@ -0,0 +1,2 @@
+for i in range(components[0].outputs):
+ builder.add_link(components[0], i, components[1], i)
diff --git a/circuitbuilder/undoredo.py b/circuitbuilder/undoredo.py
index 5548fe3..4afbe3b 100644
--- a/circuitbuilder/undoredo.py
+++ b/circuitbuilder/undoredo.py
@@ -36,7 +36,7 @@ class UndoRedoAction(object):
def redo(self, builder_widget):
if self.__action == ACTION_ADD_GATE:
- builder_widget.add_component(self.__component)
+ builder_widget.restore_component(self.__component)
elif self.__action == ACTION_DEL_GATE:
builder_widget.del_component(self.__component)
elif self.__action == ACTION_ADD_LINK:
diff --git a/circuitbuilder/viewer_widget.py b/circuitbuilder/viewer_widget.py
index 4c52d45..2c1dfa8 100644
--- a/circuitbuilder/viewer_widget.py
+++ b/circuitbuilder/viewer_widget.py
@@ -26,16 +26,22 @@ pygtk.require ('2.0')
import gtk
import cairo
+import pango
import pangocairo
import math
from math import pi
+import components
+
from constants import *
+FONT_DESC = pango.FontDescription("Monospace 10")
+
def prepare_text(cr, text):
pcr = pangocairo.CairoContext(cr)
layout = pcr.create_layout()
+ layout.set_font_description(FONT_DESC)
layout.set_text(text)
return pcr, layout
@@ -125,8 +131,7 @@ class CircuitViewerWidget(gtk.DrawingArea):
end = link.input_gate
link_square = self._get_link_square(start, end)
self._links_squares[link] = link_square
- self._redraw_surface()
- self.queue_draw()
+ self.redraw_surface()
def _get_components(self):
return self._components
@@ -186,21 +191,21 @@ class CircuitViewerWidget(gtk.DrawingArea):
height = property(_get_height, _set_height)
- def __update_component_surface(self):
- cr = cairo.Context(self._component_surface)
+ def _make_component_surface(self, surface, component_type):
+ cr = cairo.Context(surface)
cr.set_operator(cairo.OPERATOR_CLEAR)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
cr.arc(PART_SIZE / 2, PART_SIZE / 2, (PART_SIZE / 2) - 1, 0, 2 * pi)
cr.stroke()
cr.set_source_rgb(0, 0, 0)
- text = self._component_type.symbol
- if hasattr(self._component_type, "input_id"):
- input_id = self._component_type.input_id
+ text = component_type.symbol
+ if isinstance(component_type, components.Input):
+ input_id = component_type.input_id
if input_id > 0:
text = "%s %d" % (text, input_id)
- if hasattr(self._component_type, "output_id"):
- output_id = self._component_type.output_id
+ if isinstance(component_type, components.Output):
+ output_id = component_type.output_id
if output_id > 0:
text = "%s %d" % (text, output_id)
pcr, layout = prepare_text(cr, text)
@@ -211,6 +216,10 @@ class CircuitViewerWidget(gtk.DrawingArea):
pcr.move_to(x0, y0)
pcr.show_layout(layout)
+ def __update_component_surface(self):
+ self._make_component_surface(self._component_surface,
+ self._component_type)
+
def _set_component_type(self, component_type):
if self._component_type != component_type:
self._component_type = component_type
diff --git a/circuitbuilder/xmlhandling.py b/circuitbuilder/xmlhandling.py
index df5cbfd..a826c09 100644
--- a/circuitbuilder/xmlhandling.py
+++ b/circuitbuilder/xmlhandling.py
@@ -54,21 +54,23 @@ def parse_circuit(circuit, component_factory, id_prefix = None):
components = {}
components_list = []
for gate in circuit:
+ initial_data = {}
gate_type = gate.tag
id = gate.attrib["id"]
- component = component_factory.create_component(gate_type)
- if not component:
- return None
if id_prefix:
id = id_prefix + id
- component.id = id
- component.x = int(gate.attrib["x"])
- component.y = int(gate.attrib["y"])
- component.inputs = int(gate.attrib["inputs"])
+ initial_data["_id"] = id
+ initial_data["x"] = int(gate.attrib["x"])
+ initial_data["y"] = int(gate.attrib["y"])
+ initial_data["inputs"] = int(gate.attrib["inputs"])
if "input_id" in gate.attrib:
- component.input_id = int(gate.attrib["input_id"])
+ initial_data["_input_id"] = int(gate.attrib["input_id"])
if "output_id" in gate.attrib:
- component.output_id = int(gate.attrib["output_id"])
+ initial_data["_output_id"] = int(gate.attrib["output_id"])
+ component = component_factory.create_component(gate_type,
+ initial_data)
+ if not component:
+ return None
components[id] = component
components_list.append(component)
for gate in circuit:
diff --git a/simul/Makefile b/simul/Makefile
index d756157..1173a0c 100644
--- a/simul/Makefile
+++ b/simul/Makefile
@@ -1,8 +1,13 @@
-CMO=scheme.cmo compil.cmo reader.cmo main.cmo
+CMO=scheme.cmo compil.cmo reader.cmo lexerPaths.cmo main.cmo
CC=ocamlfind ocamlc -package libxml2 -linkpkg
+LEX=ocamllex
+GENERATED=lexerPaths.ml
BIN=generator
-.SUFFIXES: .ml .cmo .cmi
+.SUFFIXES: .ml .mll .cmo .cmi
+
+.mll.ml:
+ $(LEX) $<
.ml.cmo:
$(CC) -c $<
@@ -13,15 +18,15 @@ $(BIN): $(CMO)
all: $(BIN)
clean:
- rm -f $(BIN) *.cm[io] .depend
+ rm -f $(GENERATED) $(BIN) *.cm[io] .depend
test: $(BIN)
./generator FullAdder > test.cpp
g++ -o test test.cpp
./test
-.depend:
+.depend: $(GENERATED)
rm -f .depend
ocamldep *.ml > .depend
-include .depend
+include .depend \ No newline at end of file
diff --git a/simul/compil.ml b/simul/compil.ml
index bf23bb8..1826328 100644
--- a/simul/compil.ml
+++ b/simul/compil.ml
@@ -311,10 +311,6 @@ let triTopo gg = (*si on doit améliorer qqc, c'est ca*)
génération de code
***************************************************************)
-(******************id dans gates*************)
-let cbTblId = Hashtbl.create 42
-let cbIdEC = ref 0
-
(*********************classes utilisees**********)
let cbTblCU = Hashtbl.create 17
@@ -350,6 +346,11 @@ let cbRegReg id idGate =
let cbIdRegIToO s =
(String.sub s 0 (String.length s - 2)) ^ "_o"
+(********************ram/rom********************)
+let cbLgrAdrRAM = 16
+let cbLgrAdrROM = 16
+let cbLgrMotRAM = 8
+let cbLgrMotROM = 8
(**************fonctions action*******************)
let cbIdEntree = "Input"
@@ -364,19 +365,22 @@ let cbIdNor = "Nor"
let cbIdOr = "Or"
let cbIdAnd = "And"
let cbIdMux = "Mux"
+let cbIdRAMW = "RAMW"
+let cbIdRAMR = "RAMR"
+let cbIdROMR = "ROMR"
let cbTblFcts = Hashtbl.create 17
let cbTblFctsSpe = Hashtbl.create 17
let _ =
Hashtbl.add cbTblFctsSpe cbIdSortie
- "sortie = gates[parents[0]]->sortie;\ntabOutputs[idS] = sortie";
+ "sortie = gates[parents[0]]->sortie;\ntabOutputs[idS] = sortie + 48";
Hashtbl.add cbTblFctsSpe cbIdEntree
- "sortie = tabInputs[idE]";
+ "sortie = (tabInputs[idE] - 48)";
Hashtbl.add cbTblFctsSpe cbIdNot
"sortie = !(gates[parents[0]]->sortie)";
Hashtbl.add cbTblFctsSpe cbIdRegI
- (Printf.sprintf "reinterpret_cast<%s>(gates[idO])->next = gates[parents[0]]->sortie" (cbIdRegO ^ "000*"));
+ (Printf.sprintf "reinterpret_cast<%s000*>(gates[idO])->next = gates[parents[0]]->sortie" cbIdRegO);
Hashtbl.add cbTblFctsSpe cbIdRegO
"sortie = next";
Hashtbl.add cbTblFctsSpe cbIdOne
@@ -384,7 +388,26 @@ let _ =
Hashtbl.add cbTblFctsSpe cbIdZero
"sortie = false";
Hashtbl.add cbTblFctsSpe cbIdMux
- "sortie = (gates[parents[0]]->sortie) ? gates[parents[2]]->sortie : gates[parents[1]]->sortie"
+ "sortie = (gates[parents[0]]->sortie) ? gates[parents[2]]->sortie : gates[parents[1]]->sortie";
+
+ let binToInt typemem ofs =
+ let str = ref "0" in
+ for i = 0 to (match typemem with |"RAM" -> cbLgrAdrRAM |"ROM" -> cbLgrAdrROM |_ -> failwith "mauvais type de mem") do
+ str := Printf.sprintf "%s+(gates[parents[%d]]->sortie << %d)" !str (i+ofs) i
+ done;
+ !str
+ in
+ for i = 0 to cbLgrMotRAM do
+ Hashtbl.add cbTblFctsSpe (Printf.sprintf "%s%d" cbIdRAMR i)
+ (Printf.sprintf "sortie = tabRAM[%s] & (1 << %d)" (binToInt "RAM" 0) i)
+ done;
+ for i = 0 to cbLgrMotRAM do
+ Hashtbl.add cbTblFctsSpe (Printf.sprintf "%s%d" cbIdROMR i)
+ (Printf.sprintf "sortie = tabROM[%s] & (1 << %d)" (binToInt "ROM" 0) i)
+ done;
+ Hashtbl.add cbTblFctsSpe cbIdRAMW
+ (Printf.sprintf "tabRAM[%s] = %s" (binToInt "RAM" 0) (binToInt "RAM" cbLgrAdrRAM))
+
let cbConvertitOper = function
@@ -436,8 +459,9 @@ struct gate {
gate ()
:sortie(false) {};
};
-bool tabInputs[%d];
-bool tabOutputs[%d];\n\n" nEntrees nSorties
+char tabInputs[%d];
+char tabOutputs[%d] = \"%s\";
+\n" (nEntrees + 1) (nSorties + 1) (String.make nSorties '0')
(**************classes*********************)
@@ -479,19 +503,20 @@ let cbClasses () =
(***************portes*****************************)
-let cbPortes g (mapentrees : int Smap.t) (mapsorties : int Smap.t) =
- let cbRegPorte id =
- Hashtbl.add cbTblId id (!cbIdEC);
- incr cbIdEC
- in
- let cbGetPorteIdC id =
- try
- Hashtbl.find cbTblId id
- with
- |Not_found -> failwith "generation de code : id C non trouvee"
- in
+let cbPortes g (mapentrees : int Smap.t) (mapsorties : int Smap.t) nPortes =
+ let cbTblId = Hashtbl.create 42 in
+ let cbIdEC = ref (nPortes - 1) in
+ let cbGetIdGate id =
+ try
+ Hashtbl.find cbTblId id
+ with
+ |Not_found -> failwith (Printf.sprintf "cbPortes : id %s non trouvee" id)
+ in
+ let cbRegIdGate id = Hashtbl.add cbTblId id !cbIdEC; decr cbIdEC
+ in
+
let cbFormatePorte id kind parents =
- cbRegPorte id;
+ cbRegIdGate id;
(*ici les cas spéciaux*)
try
let k = cbGetKind kind in
@@ -499,14 +524,14 @@ let cbPortes g (mapentrees : int Smap.t) (mapsorties : int Smap.t) =
|a when a = cbIdEntree ->
[string_of_int (Smap.find id mapentrees)]
|a when a = cbIdSortie ->
- (string_of_int (Smap.find id mapsorties))::(List.map (fun (i1, n1) -> string_of_int (cbGetPorteIdC i1)) parents)
+ (string_of_int (Smap.find id mapsorties))::(List.map (fun (i1, n1) -> string_of_int (cbGetIdGate i1)) parents)
|a when a = cbIdRegO ->
- cbRegReg id (!cbIdEC - 1);
- List.map (fun (i1, n1) -> string_of_int (cbGetPorteIdC i1)) parents
+ cbRegReg id (!cbIdEC + 1);
+ List.map (fun (i1, n1) -> string_of_int (cbGetIdGate i1)) parents
|a when a = cbIdRegI ->
- (string_of_int (Hashtbl.find cbTblRegs (cbIdRegIToO id)))::(List.map (fun (i1, n1) -> string_of_int (cbGetPorteIdC i1)) parents)
+ (string_of_int (Hashtbl.find cbTblRegs (cbIdRegIToO id)))::(List.map (fun (i1, n1) -> string_of_int (cbGetIdGate i1)) parents)
|_ ->
- List.map (fun (i1, n1) -> string_of_int (cbGetPorteIdC i1)) parents
+ List.map (fun (i1, n1) -> string_of_int (cbGetIdGate i1)) parents
)
in
kind ^ " " ^ id ^ (if args = [] then "" else "(" ^ (cbFormateArgs args) ^ ")") ^ ";\n"
@@ -519,7 +544,7 @@ let cbPortes g (mapentrees : int Smap.t) (mapsorties : int Smap.t) =
(***********************tab************************)
let cbTab g =
- let tab = (List.fold_left (fun l (i, k) -> l ^ "&" ^ i ^ ", ") "{" g.sommets) ^ "}" in
+ let tab = (List.fold_left (fun l (i, k) -> l ^ "&" ^ i ^ ", ") "{" (List.rev g.sommets)) ^ "}" in
Printf.printf "gate* gates[] = %s;\n" tab
@@ -537,18 +562,13 @@ let cbActions () =
let cbMain nPortes nEntrees nSorties =
Printf.printf
"int main () {
- char temp[%d];
while(true) {
- scanf(\"%%s\", temp);
- for (int i = 0; i < %d; i++)
- tabInputs[i] = temp[i] - 48;
- for (int i = 0; i < %d; i++)
+ scanf(\"%%s\", tabInputs);
+ for (int i = %d - 1; i >= 0; i--)
gates[i]->action();
- for (int i = 0; i < %d; i++)
- printf(\"%%d\", tabOutputs[i]);
- printf(\"\\n\");
+ puts(tabOutputs);
};
-}" (nEntrees+2) nEntrees nPortes nSorties
+}" nPortes
(**********************genere code****************)
@@ -564,7 +584,7 @@ let cbGenereCode g (mapentrees : int Smap.t) (mapsorties : int Smap.t) =
cbRegCU g;
cbDebut nentrees nsorties;
cbClasses ();
- cbPortes g mapentrees mapsorties;
+ cbPortes g mapentrees mapsorties (List.length g.sommets);
cbTab g;
cbActions ();
cbMain (List.length g.sommets) nentrees nsorties
diff --git a/simul/fulladder.xnl b/simul/fulladder.xnl
deleted file mode 100644
index c39292d..0000000
--- a/simul/fulladder.xnl
+++ /dev/null
@@ -1,33 +0,0 @@
-<circuit inputs="3" name="FullAdder" outputs="2" symbol="fa" min_height="268" min_width="457">
- <Input y="164" inputs="0" input_id="3" id="inC" x="28">
- <outputlink output_id="1" input_gate="xorB" input_id="2"/>
- <outputlink output_id="1" input_gate="andA" input_id="2"/>
- </Input>
- <And y="228" inputs="2" id="andB" x="267">
- <outputlink output_id="1" input_gate="orA" input_id="2"/>
- </And>
- <Or y="189" inputs="2" id="orA" x="337">
- <outputlink output_id="1" input_gate="Cout" input_id="1"/>
- </Or>
- <Input y="63" inputs="0" input_id="1" id="inA" x="29">
- <outputlink output_id="1" input_gate="xorA" input_id="1"/>
- <outputlink output_id="1" input_gate="andB" input_id="1"/>
- </Input>
- <Output y="119" inputs="1" output_id="1" id="S" x="415"/>
- <Output y="220" inputs="1" output_id="2" id="Cout" x="417"/>
- <Xor y="85" inputs="2" id="xorA" x="139">
- <outputlink output_id="1" input_gate="xorB" input_id="1"/>
- <outputlink output_id="1" input_gate="andA" input_id="1"/>
- </Xor>
- <Input y="114" inputs="0" input_id="2" id="inB" x="29">
- <outputlink output_id="1" input_gate="xorA" input_id="2"/>
- <outputlink output_id="1" input_gate="andB" input_id="2"/>
- </Input>
- <Xor y="119" inputs="2" id="xorB" x="249">
- <outputlink output_id="1" input_gate="S" input_id="1"/>
- </Xor>
- <And y="173" inputs="2" id="andA" x="267">
- <outputlink output_id="1" input_gate="orA" input_id="1"/>
- </And>
-</circuit>
-
diff --git a/simul/lexerPaths.ml b/simul/lexerPaths.ml
new file mode 100644
index 0000000..cde4366
--- /dev/null
+++ b/simul/lexerPaths.ml
@@ -0,0 +1,127 @@
+# 1 "lexerPaths.mll"
+
+ let tblPaths = Hashtbl.create 17
+
+# 6 "lexerPaths.ml"
+let __ocaml_lex_tables = {
+ Lexing.lex_base =
+ "\000\000\253\255\001\000\002\000";
+ Lexing.lex_backtrk =
+ "\001\000\255\255\001\000\000\000";
+ Lexing.lex_default =
+ "\002\000\000\000\002\000\255\255";
+ Lexing.lex_trans =
+ "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\003\000\255\255\003\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
+ \001\000\255\255\000\000";
+ Lexing.lex_check =
+ "\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\000\000\002\000\003\000\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\
+ \000\000\002\000\255\255";
+ Lexing.lex_base_code =
+ "";
+ Lexing.lex_backtrk_code =
+ "";
+ Lexing.lex_default_code =
+ "";
+ Lexing.lex_trans_code =
+ "";
+ Lexing.lex_check_code =
+ "";
+ Lexing.lex_code =
+ "";
+}
+
+let rec readWord lexbuf =
+ __ocaml_lex_readWord_rec lexbuf 0
+and __ocaml_lex_readWord_rec lexbuf __ocaml_lex_state =
+ match Lexing.engine __ocaml_lex_tables __ocaml_lex_state lexbuf with
+ | 0 ->
+# 9 "lexerPaths.mll"
+ (readWord lexbuf)
+# 103 "lexerPaths.ml"
+
+ | 1 ->
+let
+# 10 "lexerPaths.mll"
+ word
+# 109 "lexerPaths.ml"
+= Lexing.sub_lexeme lexbuf lexbuf.Lexing.lex_start_pos lexbuf.Lexing.lex_curr_pos in
+# 10 "lexerPaths.mll"
+ (Hashtbl.add tblPaths word (); readWord lexbuf)
+# 113 "lexerPaths.ml"
+
+ | 2 ->
+# 11 "lexerPaths.mll"
+ ( () )
+# 118 "lexerPaths.ml"
+
+ | __ocaml_lex_state -> lexbuf.Lexing.refill_buff lexbuf; __ocaml_lex_readWord_rec lexbuf __ocaml_lex_state
+
+;;
+
+# 15 "lexerPaths.mll"
+
+ let read ch = Hashtbl.clear tblPaths; readWord (Lexing.from_channel ch); tblPaths
+
+# 128 "lexerPaths.ml"
diff --git a/simul/lexerPaths.mll b/simul/lexerPaths.mll
new file mode 100644
index 0000000..ce8b605
--- /dev/null
+++ b/simul/lexerPaths.mll
@@ -0,0 +1,17 @@
+{
+ let tblPaths = Hashtbl.create 17
+}
+
+(*let letter = ['a'-'z' 'A'-'Z' '0'-'9' '.' '/' '#' '~']*)
+let blank = [' ' '\t' '\n']
+
+rule readWord = parse
+ |'\n'+ {readWord lexbuf}
+ |[^ '\n']* as word {Hashtbl.add tblPaths word (); readWord lexbuf}
+ |eof { () }
+
+
+
+{
+ let read ch = Hashtbl.clear tblPaths; readWord (Lexing.from_channel ch); tblPaths
+}
diff --git a/simul/main.ml b/simul/main.ml
index 42a2e6f..f35823b 100644
--- a/simul/main.ml
+++ b/simul/main.ml
@@ -1,5 +1,7 @@
open Scheme
+let pathfilename = "paths"
+
let estXNL a =
if (String.length a < 4) then
false
@@ -19,16 +21,27 @@ let printsimap s =
Printf.printf "\n"
let _ =
- let files = Sys.readdir "." in
+ let pathfile = open_in pathfilename in
+ let paths = LexerPaths.read pathfile in
+
+ Hashtbl.iter (fun path _ -> Printf.fprintf stderr "%s\n" path;
+ let files = Sys.readdir path in
for i = 0 to Array.length files - 1 do
- if estXNL files.(i) then
- Compil.regCircuit (Reader.parse_file files.(i))
- done;
- let schMain = Compil.findSchema (Sys.argv.(1) ^ "XXX") in
- let schMain2 = delesscheme schMain in
- let t = Compil.triTopo (Compil.completeGraphe
- schMain2 ""
- Imap.empty
- Imap.empty) in
- Compil.cbGenereCode t (simap_to_ismap schMain.entrees) (simap_to_ismap schMain.sorties)
+ if estXNL files.(i) then begin
+ Compil.regCircuit (Reader.parse_file (path ^ files.(i)));
+ Printf.fprintf stderr "Circuit ouvert : %s\n" (path ^ files.(i))
+ end
+ done
+ ) paths;
+ let schMain = Compil.findSchema (Sys.argv.(1) ^ "XXX") in
+ let schMain2 = delesscheme schMain in
+ Printf.fprintf stderr "Compilation : %f\n" (Sys.time());
+ let t = Compil.completeGraphe
+ schMain2 ""
+ Imap.empty
+ Imap.empty in
+ Printf.fprintf stderr "Tritopo %f\n" (Sys.time());
+ let t = Compil.triTopo t in
+ Printf.fprintf stderr "Fin %f\n" (Sys.time());
+ Compil.cbGenereCode t (simap_to_ismap schMain.entrees) (simap_to_ismap schMain.sorties)
diff --git a/simul/maketest b/simul/maketest
index 2c600fc..94bf024 100755
--- a/simul/maketest
+++ b/simul/maketest
@@ -1,2 +1,7 @@
#!/bin/bash
-echo "Generating & compiling C++ source" && cp ../components/*.xnl . && ./generator $1 > $1.cpp && g++ -o $1 $1.cpp && echo "Testing..." && ./$1
+echo "Generating & compiling C++ source" &&
+make &&
+./generator $1 > $1.cpp &&
+g++ -O5 -o $1 $1.cpp &&
+echo "Testing..." &&
+./$1
diff --git a/simul/paths b/simul/paths
new file mode 100644
index 0000000..cda7dcf
--- /dev/null
+++ b/simul/paths
@@ -0,0 +1,2 @@
+.
+../components/ \ No newline at end of file
diff --git a/utils/tick.c b/utils/tick.c
index 2b6c91d..223f131 100755
--- a/utils/tick.c
+++ b/utils/tick.c
@@ -7,12 +7,20 @@ int main(int argc, char **argv)
{
struct timeval time;
struct timespec req;
- int last_sec = 0;
- int nsecs = 1000000000 / atoi(argv[1]);
+ gettimeofday(&time, NULL);
+ long int last_usec = time.tv_usec;
+ long int usecs_delta;
+ unsigned int max_usecs = 1000000 / atoi(argv[1]);
req.tv_sec = 0;
for (;;)
{
- req.tv_nsec = nsecs;
+ gettimeofday(&time, NULL);
+ //printf("%d %d\n", usecs_delta, req.tv_nsec);
+ usecs_delta = time.tv_usec - last_usec;
+ if (usecs_delta < 0)
+ usecs_delta = time.tv_usec - last_usec + 1000000;
+ req.tv_nsec = (2 * max_usecs - usecs_delta) * 1000;
+ last_usec = time.tv_usec;
nanosleep(&req, NULL);
printf("1\n");
fflush(stdout);
diff --git a/utils/tick.cpp b/utils/tick.cpp
new file mode 100644
index 0000000..6155bfd
--- /dev/null
+++ b/utils/tick.cpp
@@ -0,0 +1,60 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+struct timeC {
+ int u;
+ long s;
+ timeC operator + (const timeC & a) {
+ timeC ret;
+ ret.u = u + a.u;
+ ret.s = s + a.s;
+ if (ret.u > 1000000) {
+ ret.u -= 1000000;
+ ret.s++;
+ };
+ return ret;
+ };
+ timeC operator - (const timeC & a) {
+ timeC ret;
+ ret.u = u - a.u;
+ ret.s = s - a.s;
+ if (ret.u < 0) {
+ ret.u += 1000000;
+ ret.s--;
+ };
+ return ret;
+ };
+ timeC ()
+ :u(0), s(0) {};
+ timeC (const timeval & t)
+ :u(t.tv_usec), s(t.tv_sec) {};
+ operator timespec () const {
+ timespec ret;
+ ret.tv_sec = s;
+ ret.tv_nsec = u * 1000;
+ return ret;
+ };
+};
+
+int main(int argc, char **argv)
+{
+ struct timeval time;
+ struct timespec req;
+ gettimeofday(&time, NULL);
+ timeC max_nsecs;
+ max_nsecs.u = 1000000 / atoi(argv[1]);
+ timeC next = max_nsecs + time;
+ for (;;)
+ {
+ gettimeofday(&time, NULL);
+ req = next - time;
+ next = next + max_nsecs;
+ nanosleep(&req, NULL);
+ printf("1\n");
+ fflush(stdout);
+ }
+ return 0;
+}