Modules ======= 1. ui (user interface) - console or gui - ui - It is the entry point and controls everything - Sees only the API of the structure module 2. structure - It is now only the sheet for the moment, but will become a book tree: BookTree --1*-- BookTreeNode --1*-- Book --1*-- Sheet --1*-- Item --1*- - Element - It is the only API for the user interface. 3. items - uses a plugin system to add item types to the system, so that the structure does not know the list of available item types - it is a minimum data element that can be executed - examples: table of definition of data, plantrisk execution launcher, etc. - it is containts one or more elements 4. elements - blocks on which the items are based: tables, text, output window - the ui knows about the elements but not about the items. Each element corresponds (more or less ?) to a widget. 5. persister - code allowing data to be reused from one execution to another To be added: 6. data model Module: interface ============== interface/ ui.py widgets.py console/ console_ui.py console_widgets.py gui/ gui_ui.py (needed?) qt/ qt_ui.py Module: structure ================= interface | V structure | | V | items | | | | V | | element | | ? | | V V V persister Design choices ============== - Each element has as basic flags: - editable - executable - visible - Each item can have several editable elements, but only one executable element. - All persistence should stay out of the ui code. - when editing the ui gets a new value and passes it to the sheet -> item Hesitation: does the item persist the values or the elements? --> Both: the elements persists the elements defining its state (a single element in this case) and the items persists additional information needed, such as failed, cancelled, --> NO, to complex! for the moment the item will do everything! Hesitation: The element class Subprocess should have self.cmd or not? - pro: it is the attribute needed to run the process. How could the ui know it otherwise? - con: the element should have only self.value. ---> Solution: subprocess will have get_cmd! Division of tasks ================= ui: controls the - display (very different if gui or console) - edition, calling a method in sheet when an element is edited - execution of the executable elements, calling a method in sheet when the element is executed. sheet: contains the logic of - the script: sequence of executable steps - the cursor (updated after each execution, depending on the failure etc) - impact of edition on the cursor. item (normally defined as a plugin): - definition: an atomic executable step - controls the logic of the edition and execution and all the persistance related to the item and its elements element - defintion: component of the item, known by the ui (the ui has to know about all items, how to display/edit them and execute, if it is the case - does it control the persistence of the single element it contains? - proposal 1: YES, but the method is explicitly called by the item - proposal 2: NO, it is simpler to let all the persistence to the item (it has to control the persistence of many things anyway) New hesitation on the persister =============================== What do I want from the persister? 1. to be able to use item.failed transparently (a property) - will item be from a class derived from Persistence (so will Item BE a container instead of having a container? - yes, so that the setattr, getattr magic can be written once... - so, Item and Sheet would derive from PersistentContainer 2. to have lists and dictionaries updated when setitem, del etc are used 3. the defensive code using __nonzero__ is not needed. What will item.failed return? - a bool? - but what to do with the dictionaries? should we return a special object for dictionaries and lists and normal objects for the rest?... - hmm, not elegant... - a PersistentBool? - and in the case of a path, will be a PersistentObject? - and we will have to use .value all the time??? Does the object retured by the setattr magic know that it is something to be persisted? - that is the question. - in principle not because the item/sheet are the only objects that should change the value of the ===> Proposed solution: return normal objects and create a special .update() method for the list/dict case - this is what was done in the beginning. ===> parhaps also: disable the setattr, so that it is not done accidentally for item/sheet to use self.update('failed', True). For the lists/dicts we would do names = self.names names.append(name) self.update('names', names) New design decisions ==================== Global data - it is a dictionary! not a class, etc. Each element needs a unique name in this dictionary, so we can't have a BOSet 'Plant' and a Mapping or a File also named 'Plant' - there should be a mechanism to check collisions! - the item way of organising the data can/will be different. That is why we have the property data in Item.