diff --git a/Container.py b/Container.py index 34410adc..37317948 100644 --- a/Container.py +++ b/Container.py @@ -2151,9 +2151,9 @@ def OnPaste(self, event): ### adding model self.AddShape(newShape) - ### adding connectionShape - for cs in L: - cs.input = (D[cs.input[0]],cs.input[1]) + ### adding connectionShape only if the connection is connected on the two side with blocks. + for cs in [ a for a in L if a.input[0] in D and a.output[0] in D]: + cs.input = (D[cs.input[0]],cs.input[1]) cs.output = (D[cs.output[0]],cs.output[1]) self.AddShape(cs) @@ -3981,7 +3981,8 @@ def __getattr__(self, name): """ if name == 'dump_attributes': - return ['shapes', 'priority_list', 'constants_dico', 'model_path', 'python_path','args'] + self.GetAttributes() + #return ['shapes', 'priority_list', 'constants_dico', 'model_path', 'python_path','args'] + self.GetAttributes() + return ['shapes', 'priority_list', 'constants_dico','args'] + self.GetAttributes() #======================================================================= elif name == 'dump_abstr_attributes': return Abstractable.DUMP_ATTR if hasattr(self, 'layers') and hasattr(self, 'current_level') else [] diff --git a/LibraryTree.py b/LibraryTree.py index 373a2091..bf8ee9af 100644 --- a/LibraryTree.py +++ b/LibraryTree.py @@ -1117,10 +1117,10 @@ def OnLibDocumentation(self, evt): dlg.CenterOnParent(wx.BOTH) dlg.ShowModal() else: - wx.MessageBox(_("No documentation!\n Please define the documentation of the model %s in the header of its python file.")%name, _("%s Documentation")%name, wx.OK|wx.ICON_INFORMATION) + wx.MessageBox(_("No documentation!\nPlease define the documentation of the model %s in the header of its python file.")%name, _("%s Documentation")%name, wx.OK|wx.ICON_INFORMATION) ### def OnInfo(self, event): """ """ - wx.MessageBox(_('Libraries Import Manager.\nYou can import, refresh or upgrade libraries using right options.\nDefault libraries directory is %s.')%(DOMAIN_PATH)) + wx.MessageBox(_('Libraries Import Manager.\nYou can import, refresh or upgrade libraries.\nDefault libraries directory is %s.')%(DOMAIN_PATH)) diff --git a/Menu.py b/Menu.py index 6a7c37f6..4ed70c4d 100644 --- a/Menu.py +++ b/Menu.py @@ -513,16 +513,16 @@ def __init__(self, parent): helpModel = wx.MenuItem(self, ID_HELP, _('&DEVSimPy Help\tF1'), _("Help for DEVSimPy user")) apiModel = wx.MenuItem(self, ID_API_HELP, _('&DEVSimPy API\tF2'), _("API for DEVSimPy user")) - updatePipPackage = wx.MenuItem(self, ID_UPDATE_PIP_PACKAGE, _('Dependencies (PIP Packages)\tF3'), _("Update of dependant pip packages")) - updateFromGitArchive = wx.MenuItem(self, ID_UPDATE_FROM_GIT_ARCHIVE, _('From Git Archive (zip)'), _("Update of DEVSimPy from Git archive")) - updateFromGitRepo = wx.MenuItem(self, ID_UPDATE_FROM_GIT_REPO, _('From Git Repository (Pull)'), _("Update of DEVSimPy from its Git repo")) + updatePipPackage = wx.MenuItem(self, ID_UPDATE_PIP_PACKAGE, _('All Dependencies (PIP Packages)\tF3'), _("Update of dependant pip packages")) + updateFromGitArchive = wx.MenuItem(self, ID_UPDATE_FROM_GIT_ARCHIVE, _('DEVSimPy From Git Archive (zip)'), _("Update of DEVSimPy from Git archive")) + updateFromGitRepo = wx.MenuItem(self, ID_UPDATE_FROM_GIT_REPO, _('DEVSimPy From Git Repository (Pull)'), _("Update of DEVSimPy from its Git repo")) contactModel = wx.MenuItem(self, ID_CONTACT, _('Contact the Author...'), _("Send mail to the author")) aboutModel = wx.MenuItem(self, ID_ABOUT, _('About DEVSimPy...'), _("About DEVSimPy")) helpModel.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'search.png'))) updatePipPackage.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'update.png'))) - updateFromGitArchive.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'update.png'))) - updateFromGitRepo.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'update.png'))) + updateFromGitArchive.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'zip.png'))) + updateFromGitRepo.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'git.png'))) apiModel.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'api.png'))) contactModel.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'mail.png'))) aboutModel.SetBitmap(wx.Bitmap(os.path.join(ICON_PATH,'info.png'))) diff --git a/Mixins/Abstractable.py b/Mixins/Abstractable.py index c5c35b3a..a35561dd 100644 --- a/Mixins/Abstractable.py +++ b/Mixins/Abstractable.py @@ -29,8 +29,8 @@ #--------------------------------------------------------- class Abstractable: - """ Mixin class for the abstraction hierarchy - Adds dynamically the 'layers' attribute. This one contains the list of diagrams associated with one level + """ Mixin class for the abstraction hierarchy. + Adds dynamically the 'layers' attribute. This one contains the list of diagrams associated with one level. """ DUMP_ATTR = ['layers', 'current_level', 'DAM', 'UAM'] @@ -59,7 +59,7 @@ def __init__(self, dia): #=============================================================================== ### def SetDiagram(self, diagram): - """ Set the diagram + """ Set the diagram. """ ### if diagram has layers attribute and layer exist, then load it @@ -75,7 +75,7 @@ def SetDiagram(self, diagram): ### def GetDiagram(self): - """ Return Diagram instance + """ Return Diagram instance. """ return self.diagram #=============================================================================== @@ -84,36 +84,36 @@ def GetDiagram(self): ### def GetDiagramByLevel(self, l): - """ Return layer form level l - if layer dosen't exist, None is returned + """ Return layer form level l. + if layer dosen't exist, None is returned. """ return self.layers.get(l, None) ### def SetDiagramByLevel(self, d, l): - """ Update the layers form diagram d at level l + """ Update the layers form diagram d at level l. """ self.layers.update({l:d}) ### def GetLayers(self): - """ Get layers dico + """ Get layers dico. """ return self.layers ### def GetCurrentLevel(self): - """ Return the current layer viewed in the canvas + """ Return the current layer viewed in the canvas. """ return self.current_level def GetUAM(self): - """ Return the dictionary of the code of Upward Atomic Model + """ Return the dictionary of the code of Upward Atomic Model. """ return self.UAM def GetDAM(self): - """ Return the dictionary of the code of Downward Atomic Model + """ Return the dictionary of the code of Downward Atomic Model. """ return self.DAM @@ -128,25 +128,25 @@ def SetUAM(self, cl, val): self.UAM[cl] = val def SetCurrentLevel(self, l): - """ Set the current level viewed in the canvas + """ Set the current level viewed in the canvas. """ self.current_level = l ### def NextLevel(self): - """ return the last depth abstract level + """ return the last depth abstract level. """ return self.GetLevelLenght() ### def GetLevelLenght(self): - """ Get the number of layers defined in the canvas + """ Get the number of layers defined in the canvas. """ return len(self.GetLayers()) ### def AddLayer(self, d, l): - """ Add the diagram d at level l + """ Add the diagram d at level l/ """ if l in self.layers: self.SetDiagramByLevel(d, l) @@ -162,9 +162,8 @@ def AddLayer(self, d, l): ### def LoadDiagram(self, l): - """ Load diagram at the level l in the current canvas + """ Load diagram at the level l in the current canvas. """ - layers = self.GetLayers() canvas = self @@ -186,7 +185,7 @@ def LoadDiagram(self, l): canvas.SetCurrentLevel(l) #canvas.SetDiagram(dia) - print("New diagram at level %s"%l, self.layers) + sys.stdout.write("New diagram at level %s"%l, self.layers) ### add new or update new attributes layers and current_layer to diagram setattr(dia, 'layers', canvas.GetLayers()) diff --git a/Mixins/Achievable.py b/Mixins/Achievable.py index 6d065a30..1d5552fb 100644 --- a/Mixins/Achievable.py +++ b/Mixins/Achievable.py @@ -24,12 +24,12 @@ #------------------------------------------------------------------------------- class Achievable(Components.DEVSComponent): - """ Achievable mixin to create corresponding behavioral model (DEVS) of block + """ Achievable mixin to create corresponding behavioral model (DEVS) of block. """ ### def __init__(self): - """ Constructor + """ Constructor. """ Components.DEVSComponent.__init__(self) diff --git a/Mixins/Attributable.py b/Mixins/Attributable.py index 529ec760..77461145 100644 --- a/Mixins/Attributable.py +++ b/Mixins/Attributable.py @@ -22,7 +22,7 @@ #--------------------------------------------------------- class Attributable: - """ AttributeEditor mixin class to edit shape properties + """ AttributeEditor mixin class to edit shape properties. """ ### Static variable for default graphical properties display @@ -44,7 +44,7 @@ def __init__(self): ### def AddAttribute(self, name, typ=""): - """ Add attribute if not exist + """ Add attribute if not exist. """ if not hasattr(self, name): @@ -54,34 +54,28 @@ def AddAttribute(self, name, typ=""): ### def GetAttributes(self): - """ Return attributes attribute + """ Return attributes attribute. """ return self.attributes ### def SetAttributes(self, L): - """ Set attributes list + """ Set attributes list. """ assert(isinstance(L,list)) - ### set attribute - for name in L: - if not hasattr(self, name): - setattr(self, name, '') - ### set attributes list - self.attributes = L + self.attributes = [setattr(self, name, '') for name in L if not hasattr(self, name)] ### def AddAttributes(self, attrs): - """ Extend attributes list + """ Extend attributes list. """ - for attr in [a for a in attrs if a not in self.attributes]: - self.attributes.append(attr) + self.attributes.extend([a for a in attrs if a not in self.attributes]) ### def RemoveAttribute(self, name): - """ Remove attribute name + """ Remove attribute name. """ ### delete the attribute if hasattr(self,name): diff --git a/Mixins/Connectable.py b/Mixins/Connectable.py index ae31887b..dae1954c 100644 --- a/Mixins/Connectable.py +++ b/Mixins/Connectable.py @@ -20,16 +20,14 @@ # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## -#--------------------------------------------------------- class Connectable: - """ Mixin to create connectable nodes or ports + """ Mixin to create connectable nodes or ports. """ ### def __init__(self, nb_in = 1, nb_out = 3): """ Constructor. """ - self.input = nb_in self.output = nb_out diff --git a/Mixins/Plugable.py b/Mixins/Plugable.py index 0f95f4af..4fd216e2 100644 --- a/Mixins/Plugable.py +++ b/Mixins/Plugable.py @@ -29,15 +29,14 @@ import Decorators -#--------------------------------------------------------- class Plugable: - """ Plugable Mixin + """ Plugable Mixin. """ @staticmethod - def Load_Module(fileName): - """ Load module without load_module from importer. \ - In this way, we can change the name of module in the built-in. + def Load_Module(fileName:str): + """ Load module without load_module from importer. + In this way, we can change the name of module in the built-in. """ ### import zipfile model @@ -66,10 +65,10 @@ def Load_Module(fileName): return None @Decorators.BuzyCursorNotification - def LoadPlugins(self, fileName): - """ Method which load plug-ins from zip - Used for define or redefine method of amd. and .cmd model - The name of plug-in file must be "plugins.py" + def LoadPlugins(self, fileName:str): + """ Method which load plug-ins from zip. + Used for define or redefine method of amd. and .cmd model. + The name of plug-in file must be "plugins.py". """ ### if list of activated plug-ins is not empty diff --git a/Mixins/Resizeable.py b/Mixins/Resizeable.py index 362341b4..5e4b86ee 100644 --- a/Mixins/Resizeable.py +++ b/Mixins/Resizeable.py @@ -22,10 +22,12 @@ #--------------------------------------------------------- class Resizeable: - """ Mixin that creates resizable nodes that can be drug around the canvas\ - to alter the shape or size of the Shape. + """ Mixin that creates resizable nodes that can be drug around the canvas + to alter the shape or size of the Shape. """ def __init__(self): + """ Constructor. + """ pass def main(): diff --git a/Mixins/Rotatable.py b/Mixins/Rotatable.py index f9a74af9..feae0e7f 100644 --- a/Mixins/Rotatable.py +++ b/Mixins/Rotatable.py @@ -31,61 +31,61 @@ def __init__(self): """ Constructor. """ - self.dir = ['ouest', 'nord', 'est', 'sud'] + self.dir = ('ouest', 'nord', 'est', 'sud') - self.input_direction = "ouest" - self.output_direction = "est" + self.input_direction = 'ouest' + self.output_direction = 'est' + + def __SetDirection(self, direction, val): + """ Private method to set the direction attribute. + """ + if direction == self.input_direction: + self.input_direction = val + else: + self.output_direction = val ### - def OnRotateInputR(self, event): - """ Rotate on the right for input ports. + def __Rotate(self, direction:str, way:str): + """ Private method to rotate the block depending on the direction and the way. """ - index = self.dir.index(self.input_direction) - n = index + 1 - self.input_direction = self.dir[n%len(self.dir)] + assert direction in (self.input_direction, self.output_direction) + assert way in ('right','left') + + index = self.dir.index(direction) + gap = 1 if way == 'right'else -1 + n = index + gap + + self.__SetDirection(direction, self.dir[n%len(self.dir)]) ### test if there is layering between input and output if self.input_direction == self.output_direction: - n+=1 - self.input_direction = self.dir[n%len(self.dir)] + n = n + gap + self.__SetDirection(direction, self.dir[n%len(self.dir)]) + + ### + def OnRotateInputR(self, event): + """ Rotate on the right for input ports. + """ + + self.__Rotate(self.input_direction,'right') ### def OnRotateInputL(self, event): """ Rotate on the left for input ports. """ - index = self.dir.index(self.input_direction) - n = index - 1 - self.input_direction = self.dir[n%len(self.dir)] + self.__Rotate(self.input_direction,'left') - ### test if there is layering between input and output - if self.input_direction == self.output_direction: - n-=1 - self.input_direction = self.dir[n%len(self.dir)] ### def OnRotateOutputR(self, event): """ Rotate on the right for output ports. """ - index = self.dir.index(self.output_direction) - n = index + 1 - self.output_direction = self.dir[n%len(self.dir)] + self.__Rotate(self.output_direction,'right') - ### test if there is layering between input and output - if self.input_direction == self.output_direction: - n+=1 - self.output_direction = self.dir[n%len(self.dir)] ### def OnRotateOutputL(self, event): """ Rotate on the left for output ports. """ - - index = self.dir.index(self.output_direction) - n = index - 1 - self.output_direction = self.dir[n%len(self.dir)] - - ### test if there is layering between input and output - if self.input_direction == self.output_direction: - n-=1 - self.output_direction = self.dir[n%len(self.dir)] + self.__Rotate(self.output_direction,'left') ### def OnRotateR(self, event): diff --git a/Mixins/Savable.py b/Mixins/Savable.py index 6c6174b2..d462dde9 100644 --- a/Mixins/Savable.py +++ b/Mixins/Savable.py @@ -272,15 +272,15 @@ def Load(self, obj_loaded, fileName = None): ### Check comparison between serialized attribut (L) and normal attribut (dump_attributes) ### for model build with a version of devsimpy <= 2.5 ### font checking - if len(obj_loaded.dump_attributes) != len(L): - if fileName.endswith(DumpZipFile.ext[-1]): - if not isinstance(L[9], list): - import wx - L.insert(9, [FONT_SIZE, 74, 93, 700, 'Arial']) - else: - if not isinstance(L[6], list): - import wx - L.insert(6, [FONT_SIZE, 74, 93, 700, 'Arial']) + # if len(obj_loaded.dump_attributes) != len(L): + # if fileName.endswith(DumpZipFile.ext[-1]): + # if not isinstance(L[9], list): + # import wx + # L.insert(9, [FONT_SIZE, 74, 93, 700, 'Arial']) + # else: + # if not isinstance(L[6], list): + # import wx + # L.insert(6, [FONT_SIZE, 74, 93, 700, 'Arial']) #======================================================================= @@ -303,6 +303,9 @@ def Load(self, obj_loaded, fileName = None): j = 6 if fileName.endswith(DumpZipFile.ext[-1]) else 4 L.insert(j, 'middle') + else: + print(L,obj_loaded.dump_attributes) + try: ### assign dumped attributs for i, attr in enumerate(obj_loaded.dump_attributes): @@ -346,9 +349,9 @@ def Load(self, obj_loaded, fileName = None): @BuzyCursorNotification def LoadPlugins(self, obj, fileName): - """ Method which load plugins from zip - Used for define or redefine method of amd. and .cmd model - The name of plugin file must be "plugins.py" + """ Method which load plugins from zip. + Used for define or redefine method of amd. and .cmd model. + The name of plugin file must be "plugins.py". """ ### if list of activated plugins is not empty if obj.plugins: @@ -396,7 +399,7 @@ def LoadPlugins(self, obj, fileName): ###----------------------------------------------------------- class DumpGZipFile(DumpBase): - """ For save .dsp file + """ For save .dsp file. """ ext = [".dsp"] @@ -466,7 +469,7 @@ def Load(self, obj_loaded, fileName=None): ###----------------------------------------------------------- class DumpYAMLFile(DumpBase): - """ For save .yaml file + """ For save .yaml file. """ ext = [".yaml", '.yml'] @@ -518,12 +521,12 @@ def Load(self, obj_loaded, fileName = None): ###----------------------------------------------------------- class DumpJSFile(DumpBase): - """ For save .js file + """ For save .js file. """ ext = [".js"] def Save(self, obj_dumped, fileName = None): - """ + """ Save method. """ assert(fileName.endswith(tuple(DumpJSFile.ext))) diff --git a/Mixins/Selectable.py b/Mixins/Selectable.py index d8752b45..884c4cc3 100644 --- a/Mixins/Selectable.py +++ b/Mixins/Selectable.py @@ -22,12 +22,12 @@ class Selectable: """ def __init__(self): - """ Constructor + """ Constructor. """ self.selected = False def OnRenameFromClick(self, event): - """ + """ Rename the component from click. """ canvas = event.GetEventObject() @@ -35,7 +35,7 @@ def OnRenameFromClick(self, event): event.Skip() def OnRenameFromMenu(self, event): - """ + """ Rename the component from menu. """ canvas = event.GetEventObject().GetParent() @@ -43,7 +43,7 @@ def OnRenameFromMenu(self, event): event.Skip() def DoLabelDialog(self, canvas): - """ + """ Dialog to ask new label. """ ### only for Block and Port when control is down diff --git a/Mixins/Structurable.py b/Mixins/Structurable.py index 03a1af2f..2427b1d0 100644 --- a/Mixins/Structurable.py +++ b/Mixins/Structurable.py @@ -23,7 +23,7 @@ import Components class Structurable(Components.DEVSComponent): - """ Structurable class interface for DEVS coupled model integration + """ Structurable class interface for DEVS coupled model integration. """ def __init__(self): @@ -46,18 +46,28 @@ def ConnectDEVSPorts(self, p1, p2): self.devsModel.connectPorts(p1, p2) def addSubModel(self, devs): + """ Add sub model. + """ self.devsModel.addSubModel(devs) def addInPort(self): + """ Add input port. + """ return self.devsModel.addInPort() def addOutPort(self): + """ Add output port. + """ return self.devsModel.addOutPort() def getIPorts(self): + """ Get inputs port list. + """ return self.devsModel.IPorts def getOPorts(self): + """ Get the outputs port list + """ return self.devsModel.OPorts def ClearAllPorts(self): diff --git a/Patterns/Factory.py b/Patterns/Factory.py index 10401fe3..797cdb7f 100644 --- a/Patterns/Factory.py +++ b/Patterns/Factory.py @@ -60,23 +60,33 @@ def __init__(self, model): self.__algorithm = SimStrategy1(self) def simulate(self, T = 100000000): + """ Simulate for T + """ return self.__algorithm.simulate(T) def getMaster(self): + """ Get the master DEVS model. + """ return self.model def setMaster(self, model): + """ Set the DEVS master model. + """ self.model = model def setAlgorithm(self, s): + """ Set the simulation algo. + """ self.__algorithm = s def getAlgorithm(self): + """ Get the selected simlation algo. + """ return self.__algorithm class SimulationThread(threading.Thread, Simulator): """ - Thread for DEVS simulation task + Thread for DEVS simulation task. """ def __init__(self, model=None, strategy='', prof=False, ntl=False, verbose=False, dynamic_structure_flag=False, real_time_flag=False): @@ -103,7 +113,7 @@ def __init__(self, model=None, strategy='', prof=False, ntl=False, verbose=False @hotshotit def run(self): - """ Run thread + """ Run thread. """ ### define the simulation strategy @@ -176,11 +186,14 @@ def terminate(self, error = False, msg = None): self.end_flag = True def set_sleep(self, sleeptime): + """ Set the sleep. + """ self.thread_sleep = True self._sleeptime = sleeptime def suspend(self): - + """ Suspend the Thread. + """ #main_thread = threading.currentThread() #for t in threading.enumerate(): # t.thread_suspend = True @@ -188,6 +201,8 @@ def suspend(self): self.thread_suspend = True def resume_thread(self): + """ Resume the Thread. + """ self.thread_suspend = False return SimulationThread(model, strategy, prof, ntl, verbose, dynamic_structure_flag, real_time_flag) \ No newline at end of file diff --git a/Patterns/Memoize.py b/Patterns/Memoize.py index e12fbca5..5eb9f461 100644 --- a/Patterns/Memoize.py +++ b/Patterns/Memoize.py @@ -26,9 +26,14 @@ class memoized(object): not re-evaluated. """ def __init__(self, func): + """ Constructor. + """ self.func = func self.cache = {} + def __call__(self, *args): + """ Call function. + """ try: return self.cache[args] except KeyError: @@ -39,9 +44,11 @@ def __call__(self, *args): # uncachable -- for instance, passing a list as an argument. # Better to not cache than to blow up entirely. return self.func(*args) + def __repr__(self): """Return the function's docstring.""" return self.func.__doc__ + def __get__(self, obj, objtype): """Support instance methods.""" return functools.partial(self.__call__, obj) \ No newline at end of file diff --git a/Patterns/Strategy.py b/Patterns/Strategy.py index fd0617ff..537649fe 100644 --- a/Patterns/Strategy.py +++ b/Patterns/Strategy.py @@ -51,8 +51,8 @@ #import DEVSKernel.PyDEVS.DEVS as PyDEVS #import DEVSKernel.PyPDEVS.DEVS as PyPDEVS -def getFlatImmChildrenList(model, flat_imm_list = []): - """ Set priority flat list +def getFlatImmChildrenList(model, flat_imm_list:list = [])->list: + """ Set priority flat list. """ for m in model.immChildren: @@ -63,15 +63,12 @@ def getFlatImmChildrenList(model, flat_imm_list = []): return flat_imm_list -def getFlatPriorityList(model, flat_priority_list = []): - """ Set priority flat list +def getFlatPriorityList(model, flat_priority_list:list = [])->list: + """ Set priority flat list. """ ### if priority list never edited, priority is componentList order. - if hasattr(model, 'PRIORITY_LIST') and model.PRIORITY_LIST: - L = model.PRIORITY_LIST - else: - L = model.componentSet + L = model.PRIORITY_LIST if hasattr(model, 'PRIORITY_LIST') and model.PRIORITY_LIST else model.componentSet for m in L: if isinstance(m, PyDEVS.AtomicDEVS): @@ -83,16 +80,24 @@ def getFlatPriorityList(model, flat_priority_list = []): return flat_priority_list -def HasActiveChild(L): - """ Return true if a children of master is active +def HasActiveChild(L:list)->bool: + """ Return true if a children of master is active. """ return L and True in [a.timeNext != INFINITY for a in L] +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASS DEFINITION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class SimStrategy: - """ Strategy abstract class or interface + """ Strategy abstract class or interface. """ def __init__(self, simulator=None): + """ Constructor. + """ self._simulator = simulator def simulate(self, T = 100000000): @@ -101,10 +106,12 @@ def simulate(self, T = 100000000): pass class SimStrategy1(SimStrategy): - """ Original strategy for PyDEVS simulation + """ Original strategy for PyDEVS simulation. """ def __init__(self, simulator = None): + """ Constructor. + """ SimStrategy.__init__(self, simulator) def simulate(self, T = 100000000): @@ -133,10 +140,12 @@ class SimStrategy2(SimStrategy): """ def __init__(self, simulator=None): + """ Constructor. + """ SimStrategy.__init__(self, simulator) def simulate(self, T = 100000000): - """ + """ Simulate for T """ master = self._simulator.getMaster() @@ -277,19 +286,20 @@ def GetValue(self): return self._value def AddHosts(self,p): - """ Make host list composed by tuple of priority, model and transition function + """ Make host list composed by tuple of priority, model and transition function. """ model = p.host v = (model.priority/10000.0, model, execExtTransition) - if v not in self._host: - if hasattr(model, 'priority'): - self._host.append(v) + if v not in self._host and hasattr(model, 'priority'): + self._host.append(v) def GetHosts(self): + """ Return the host. + """ return self._host def FlatConnection(p1, p2): - """ + """ Make flat connection. """ if isinstance(p1.host, PyDEVS.AtomicDEVS) and isinstance(p2.host, PyDEVS.AtomicDEVS): @@ -445,7 +455,7 @@ def __init__(self, simulator=None): def simulate(self, T = 100000000): - """ + """ Simulate for T. """ ### ref to cpu time evaluation @@ -586,6 +596,8 @@ class SimStrategy5(SimStrategy4): """ def __init__(self, simulator = None): + """ Constructor. + """ SimStrategy4.__init__(self, simulator) def SetClassicDEVSOption(self): diff --git a/PreferencesGUI.py b/PreferencesGUI.py index 0316f642..a9080ba5 100644 --- a/PreferencesGUI.py +++ b/PreferencesGUI.py @@ -51,17 +51,29 @@ import ReloadModule import Menu -#---------------------------------------------------------------------- +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASSES DEFINITION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class GeneralPanel(wx.Panel): """ General preferences panel """ + ### wxPython version + wxv = [wx.VERSION_STRING] + def __init__(self, parent): """ Constructor. """ wx.Panel.__init__(self, parent) + self.InitUI() + + def InitUI(self): + ### FileBrowse self.plugin_dir = filebrowse.DirBrowseButton(self, wx.NewIdRef(), startDirectory=PLUGINS_PATH, labelText=_("Plug-ins directory:"), toolTip=_("Change the plug-ins directory"), dialogTitle=_("Plug-ins directory...")) self.domain_dir = filebrowse.DirBrowseButton(self, wx.NewIdRef(), startDirectory=DOMAIN_PATH, labelText=_("Library directory:"), toolTip=_("Change the library directory"), dialogTitle=_("Libraries directory...")) @@ -114,11 +126,8 @@ def __init__(self, parent): if wx.VERSION_STRING >= '4.0': self.cb11.SetToolTipString = self.cb11.SetToolTip self.cb1.SetToolTipString(_("Enable the notification messages")) self.cb11.SetValue(builtins.__dict__['NOTIFICATION']) - - ### wxPython version - wxv = [wx.VERSION_STRING] - self.cb2 = wx.ComboBox(self, wx.NewIdRef(), GetWXVersionFromIni(), choices=wxv, style=wx.CB_READONLY) + self.cb2 = wx.ComboBox(self, wx.NewIdRef(), GetWXVersionFromIni(), choices=GeneralPanel.wxv, style=wx.CB_READONLY) if wx.VERSION_STRING >= '4.0': self.cb2.SetToolTipString = self.cb2.SetToolTip self.cb2.SetToolTipString(_("Default version of wxPython.")) self.default_wxv = self.cb2.GetValue() @@ -173,19 +182,25 @@ def OnApply(self, event): dlg.Destroy() ### def OnNbOpenedFileChanged(self, event): + """ Update the number opened files. + """ builtins.__dict__['NB_OPENED_FILE'] = self.nb_opened_file.GetValue() # number of recent files ### def OnNbHistoryUndoChanged(self, event): + """ Update the history for undo. + """ builtins.__dict__['NB_HISTORY_UNDO'] = self.nb_history_undo.GetValue() # number of history undo ### def OnFontSizeChanged(self, event): + """ Update font size. + """ builtins.__dict__['FONT_SIZE'] = self.font_size.GetValue() # Block font size ### def OnDomainPathChanged(self, event): - """ + """ Update the domain path. """ new_domain_dir = self.domain_dir.GetValue() old_parent_domain_dir = os.path.dirname(builtins.__dict__['DOMAIN_PATH']) @@ -215,22 +230,31 @@ def OnDomainPathChanged(self, event): ### def OnPluginsDirChanged(self, event): + """ Update of plugins path has been invoked. + """ builtins.__dict__['PLUGINS_PATH'] = self.plugin_dir.GetValue() ### def OnOutDirChanged(self, event): + """ Update of output directory has been invoked. + """ builtins.__dict__['OUT_DIR'] = os.path.basename(self.out_dir.GetValue()) ### def OnTransparancyChanged(self, event): + """ Update of windwis transparency directory has been invoked. + """ builtins.__dict__['TRANSPARENCY'] = self.cb1.GetValue() ### def OnNotificationChanged(self, event): + """ Update of notifcation option directory has been invoked. + """ builtins.__dict__['NOTIFICATION'] = self.cb11.GetValue() def OnwxPythonVersionChanged(self, event): - """ + """ Update of wxpython version has been invoked. + This option has been deprecated when wxversion has been removed from wx v. 4.x. """ ### new value @@ -265,14 +289,19 @@ def OnwxPythonVersionChanged(self, event): parser.write(open(path,'w')) class SimulationPanel(wx.Panel): - """ Simulation Panel + """ Simulation Panel. """ def __init__(self, parent): - """ Constructor + """ Constructor. """ wx.Panel.__init__(self, parent) + self.InitUI() + + def InitUI(self): + """ Init the UI. + """ ### Sizer hbox1 = wx.BoxSizer(wx.HORIZONTAL) hbox2 = wx.BoxSizer(wx.HORIZONTAL) @@ -422,7 +451,7 @@ def OnSelectSound(self, evt): dlg.Destroy() def onCb1Check(self, evt): - """ CheckBox has been checked + """ CheckBox has been checked. """ if evt.GetEventObject().GetValue(): @@ -437,13 +466,13 @@ def onCb1Check(self, evt): self.sim_error_sound_path = os.devnull def onCb4(self, evt): - """ ComboBox has been checked + """ ComboBox has been checked. """ val = evt.GetEventObject().GetValue() self.sim_defaut_strategy = val def onCb3(self, evt): - """ ComboBox has been checked + """ ComboBox has been checked. """ val = evt.GetEventObject().GetValue() @@ -464,7 +493,7 @@ def onCb3(self, evt): self.sim_defaut_strategy = self.cb4.GetValue() def onSc(self, evt): - """ CheckBox has been checked + """ CheckBox has been checked. """ val = evt.GetEventObject().GetValue() self.sim_defaut_plot_dyn_freq = val @@ -503,15 +532,21 @@ def OnApply(self, evt): builtins.__dict__['NTL'] = self.cb2.GetValue() class EditorPanel(wx.Panel): - """ Edition Panel + """ Edition Panel. """ def __init__(self, parent): - """ Constructor + """ Constructor. """ wx.Panel.__init__(self, parent) + self.InitUI() + + def InitUI(self): + """ Init the UI. + """ + vbox = wx.BoxSizer(wx.VERTICAL) self.cb = wx.CheckBox(self, wx.NewIdRef(), _("Use local programmer software")) @@ -525,7 +560,7 @@ def __init__(self, parent): self.SetSizer(vbox) def OnApply(self, evt): - """ Apply changes + """ Apply changes. """ builtins.__dict__['LOCAL_EDITOR'] = self.cb.IsChecked() @@ -541,6 +576,12 @@ def __init__(self, parent): wx.Toolbook.__init__(self, parent, wx.NewIdRef(), style=wx.BK_DEFAULT) + self.InitUI() + + def InitUI(self): + """ Init the UI. + """ + ### don't try to translate this labels with _() because there are used to find png L = [('General',"(self)"),('Simulation',"(self)"), ('Editor',"(self)"), ('Plugins',"(self)")] @@ -590,7 +631,7 @@ def __init__(self, parent): self.Bind(wx.EVT_BUTTON, self.OnRefresh, id=self.refBtn.GetId()) def OnPageChanged(self, event): - """ + """ Page has been changed. """ # old = event.GetOldSelection() new = event.GetSelection() @@ -605,7 +646,7 @@ def OnPageChanged(self, event): event.Skip() def OnPageChanging(self, event): - """ + """ Pas is changing. """ new = event.GetSelection() ### plug-in page @@ -617,7 +658,7 @@ def OnPageChanging(self, event): event.Skip() def OnAdd(self, event): - """ Add plug-in + """ Add plug-in. """ wcd = 'All files (*)|*|Editor files (*.py)|*.py' open_dlg = wx.FileDialog(self, message=_('Choose a file'), defaultDir=HOME_PATH, defaultFile='', wildcard=wcd, style=wx.OPEN|wx.CHANGE_DIR) @@ -704,6 +745,14 @@ def __init__(self, parent, title): """ wx.Frame.__init__(self, parent, wx.NewIdRef(), title, style = wx.DEFAULT_FRAME_STYLE | wx.CLIP_CHILDREN) + self.InitUI() + + self.Layout() + self.Center() + + def InitUI(self): + """ Init the UI. + """ _icon = wx.EmptyIcon() if wx.VERSION_STRING < '4.0' else wx.Icon() _icon.CopyFromBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16, "preferences.png"), wx.BITMAP_TYPE_ANY)) self.SetIcon(_icon) @@ -742,9 +791,6 @@ def __init__(self, parent, title): self.Bind(wx.EVT_BUTTON, self.OnCancel, id=wx.ID_CANCEL) self.Bind(wx.EVT_BUTTON, self.OnClose, id=wx.ID_CLOSE) - self.Layout() - self.Center() - def OnApply(self, evt): """ Apply button has been clicked. """ @@ -752,10 +798,14 @@ def OnApply(self, evt): self.Close() def OnCancel(self, evt): + """ Cancel button has been invoked. + """ self.Close() evt.Skip() def OnClose(self, evt): + """ Close button has been invoked. + """ self.Close() evt.Skip() diff --git a/WizardGUI.py b/WizardGUI.py index ac4eb403..4003c425 100644 --- a/WizardGUI.py +++ b/WizardGUI.py @@ -181,17 +181,29 @@ def modelTransition(self, state): return code +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## +# +# CLASSES DEFINITION +# +## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## + class TextObjectValidator(wx.PyValidator): """ TextObjectValidator() """ def __init__(self): + """ Constructor. + """ wx.PyValidator.__init__(self) def Clone(self): + """ Clone method. + """ return TextObjectValidator() def Validate(self, win): + """ Validate fields. + """ textCtrl = self.GetWindow() text = textCtrl.GetValue() @@ -207,15 +219,22 @@ def Validate(self, win): return True def TransferToWindow(self): - return True # Prevent wxDialog from complaining. + """ Prevent wxDialog from complaining. + """ + return True def TransferFromWindow(self): - return True # Prevent wxDialog from complaining. + """ Prevent wxDialog from complaining. + """ + return True class wizard_page(WizardPage): """ An extended panel obj with a few methods to keep track of its siblings. This should be modified and added to the wizard. Season to taste.""" + def __init__(self, parent, title): + """ Constructor. + """ WizardPage.__init__(self, parent) self.next = self.prev = None self.sizer = wx.BoxSizer(wx.VERTICAL) @@ -254,12 +273,10 @@ class Wizard(wizmod): """Add pages to this wizard object to make it useful.""" def __init__(self, title, parent, img_filename = ""): - """ Constructor + """ Constructor. """ - if img_filename and os.path.exists(img_filename): - img = wx.Bitmap(img_filename) - else: - img = wx.NullBitmap + img = wx.Bitmap(img_filename) if img_filename and os.path.exists(img_filename) else wx.NullBitmap + wizmod.__init__(self, parent, wx.NewIdRef(), title, img) self.SetPageSize((400,300)) @@ -287,6 +304,8 @@ def add_page(self, page): self.pages.append(page) def run(self): + """ Run wizard. + """ self.RunWizard(self.pages[0]) def on_page_changed(self, evt): @@ -324,7 +343,7 @@ class ModelGeneratorWizard(Wizard): """ def __init__(self, *args, **kwargs): - """ Constructor + """ Constructor. """ if 'specific_domain_path' in kwargs: @@ -592,50 +611,34 @@ def onBt2Click(evt): def onBt5Check(evt): """ Python file selector is checked. """ - - if evt.GetEventObject().GetValue(): - fb1.Enable(False) - else: - fb1.Enable(True) + fb1.Enable(not evt.GetEventObject().GetValue()) # event handler for check button def onBt51Check(evt): """ Python file selector is checked. """ - if evt.GetEventObject().GetValue(): - fb12.Enable(False) - else: - fb12.Enable(True) + fb12.Enable(not evt.GetEventObject().GetValue()) def onBt6Check(evt): """ Python file selector is checked. """ - - if evt.GetEventObject().GetValue(): - fb4.Enable(False) - else: - fb4.Enable(True) + fb4.Enable(not evt.GetEventObject().GetValue()) # event handler for check button def onBt61Check(evt): """ Python file selector is checked. """ - if evt.GetEventObject().GetValue(): - fb41.Enable(False) - else: - fb41.Enable(True) - + fb41.Enable(not evt.GetEventObject().GetValue()) + def onCbId1(evt): - if evt.GetEventObject().GetValue(): - spin_id1.Enable(False) - else: - spin_id1.Enable(True) - + """ + """ + spin_id1.Enable(not evt.GetEventObject().GetValue()) + def onCbId2(evt): - if evt.GetEventObject().GetValue(): - spin_id2.Enable(False) - else: - spin_id2.Enable(True) + """ + """ + spin_id2.Enable(not evt.GetEventObject().GetValue()) def OnSpecificBehavior(evt): """ Give the control on the number of input and output form specific behavior choice diff --git a/ZipManager.py b/ZipManager.py index 9b5e8a2e..2556a112 100644 --- a/ZipManager.py +++ b/ZipManager.py @@ -369,7 +369,7 @@ def GetTests(fn:str)->[str]: def GetModule(self, rcp: bool=False)->types.ModuleType: """ Return module from zip file corresponding to the amd or cmd model. It used when the tree library is created. - If the module refered by self.fn is already imported, its returned else its imported using zipimport + If the module refered by self.fn is already imported, its returned else its imported using zipimport. """ # if necessary, recompile (for update after editing code source of model) @@ -380,7 +380,9 @@ def GetModule(self, rcp: bool=False)->types.ModuleType: py_fn = getPythonModelFileName(self.fn) try: - fullname = "".join([os.path.basename(os.path.dirname(self.fn)), py_fn.split('.py')[0]]) + ### module is referenced in sys.modules with the format: + ### the last tag allow to differenciate the model with the same name but different extention in the same lib. + fullname = "".join([os.path.basename(os.path.dirname(self.fn)), py_fn.split('.py')[0],self.fn.split('.')[-1]]) return self.ImportModule() if fullname not in sys.modules else sys.modules[fullname] ### model has not python file ! except Exception as e: @@ -424,8 +426,9 @@ def ImportModule(self)->types.ModuleType: ### allows to import with a reference from the parent directory (like parentName.model). ### Now import of .amd or .cmd module is composed by DomainModel (no point!). - ### Example : import CollectorMessageCollector - fullname = "".join([os.path.basename(os.path.dirname(self.fn)), getPythonModelFileName(self.fn).split('.py')[0]]) + ### Example : import CollectorMessageCollectoramd or CollectorMessageCollectorcmd + + fullname = "".join([os.path.basename(os.path.dirname(self.fn)), getPythonModelFileName(self.fn).split('.py')[0],self.fn.split('.')[-1]]) sys.modules[fullname] = module return module diff --git a/icons/16x16/git.png b/icons/16x16/git.png new file mode 100644 index 00000000..3423fdef Binary files /dev/null and b/icons/16x16/git.png differ diff --git a/icons/16x16/zip.png b/icons/16x16/zip.png new file mode 100644 index 00000000..a29111ba Binary files /dev/null and b/icons/16x16/zip.png differ diff --git a/icons/git.png b/icons/git.png new file mode 100644 index 00000000..b84bd540 Binary files /dev/null and b/icons/git.png differ diff --git a/icons/zip.png b/icons/zip.png new file mode 100644 index 00000000..1e7bbd00 Binary files /dev/null and b/icons/zip.png differ