diff options
author | Thomas Jourdan <b.vehikel@googlemail.com> | 2009-12-06 12:40:41 (GMT) |
---|---|---|
committer | Thomas Jourdan <b.vehikel@googlemail.com> | 2009-12-06 12:40:41 (GMT) |
commit | 7ce7155dead3893e572006588fc342fb3af7ec60 (patch) | |
tree | 2bb234d6d159aa797767bf1ceccea53117dc773a /ka_controller.py | |
parent | bcde11455168a07de8a3b17f2a4d77ce8931e75d (diff) |
Layers are now arranged as a tree data structure.
Diffstat (limited to 'ka_controller.py')
-rw-r--r-- | ka_controller.py | 137 |
1 files changed, 91 insertions, 46 deletions
diff --git a/ka_controller.py b/ka_controller.py index 2618ab7..932a4d7 100644 --- a/ka_controller.py +++ b/ka_controller.py @@ -17,34 +17,40 @@ import gtk import gtk.glade +import gobject import cairo import ka_debug import model_population import ka_incoming import kandidtube -import ka_random +import model_random import ka_task class KandidController(object): """ inv: self.model is not None - inv: self._canvas is not None + inv: self._widget_tree is not None """ - def __init__(self, init_canvas): + def __init__(self, init_widget_tree): """ - pre: init_canvas is not None + pre: init_widget_tree is not None """ - self._canvas = init_canvas + self._start_from_scratch = True + self._widget_tree = init_widget_tree self._tube = None - # create to data model + # create data model self.model = model_population.KandidModel(12) self.model.randomize() self.incoming = ka_incoming.KandidIncoming(3) self.surface_cache = {} + self._update_population_gui() + self._update_incomming_gui() + + def autoconnect_events(self): #Create a dictionary to connect events events = { 'on_breed_generation' : self.on_breed_generation, @@ -73,39 +79,44 @@ class KandidController(object): events[key] = self.on_incomingarea_expose key = 'on_incoming_#_popup'.replace('#', strix) events[key] = self.on_incoming_popup - self._canvas.widgetTree.signal_autoconnect(events) - self._update_population_gui() - self._update_incomming_gui() + self._widget_tree.signal_autoconnect(events) + gobject.timeout_add(100, self.on_timer) + def _update_model(self, in_model): if in_model: self.model = in_model self.model._state = model_population.STATE_EVOLVED + self.surface_cache = {} self._update_population_gui() def _update_population_gui(self): + # update fitness for cell_index in range(self.model.size): strix = str(cell_index) key = 'fitness_#'.replace('#', strix) - self._canvas.widgetTree.get_widget(key). \ + self._widget_tree.get_widget(key). \ set_value(self.model.fitness[cell_index]) - self._canvas.widgetTree.get_widget('flurrySpinButton'). \ + # update flurry + self._widget_tree.get_widget('flurrySpinButton'). \ set_value(self.model.flurry_rate) - good, moderate, poor = self.model.classify() + # update buttons + dummy, moderate, poor = self.model.classify() is_sensitive = len(poor) > 0 and len(moderate) > 0 - self._canvas.widgetTree.get_widget('breedGenerationButton'). \ + self._widget_tree.get_widget('breedGenerationButton'). \ set_sensitive(is_sensitive) - self._canvas.widgetTree.get_widget('randomGenerationButton'). \ + self._widget_tree.get_widget('randomGenerationButton'). \ set_sensitive(is_sensitive) def _update_incomming_gui(self): for index in range(self.incoming.capacity): - self._canvas.widgetTree.get_widget('incomingbutton_' + str(index)). \ + self._widget_tree.get_widget('incomingbutton_' + str(index)). \ set_sensitive(len(self.incoming.incoming_protozoans) > index) def _draw_from_cache(self, widget, cell_index): if self.surface_cache.has_key(cell_index): -# ka_debug.info('_draw_from_cache: ' + widget.name + ' ' + str(cell_index)) +# ka_debug.info('_draw_from_cache: ' + widget.name + ' ' +# + str(cell_index)) ctx = self._create_context(widget) ctx.set_operator(cairo.OPERATOR_SOURCE) ctx.set_source_surface(self.surface_cache[cell_index]) @@ -125,10 +136,10 @@ class KandidController(object): """ New size for drawing area available. pre: widget is not None """ -# ka_debug.info('on_drawingarea_size_allocate: ' + widget.name + ' ' -# + str(widget.allocation.width) -# + 'x' + str(widget.allocation.height)) - self._start_calculation([_name_to_index(widget.name)]) + ka_debug.info('on_drawingarea_size_allocate: ' + widget.name + ' ' + + str(widget.allocation.width) + + 'x' + str(widget.allocation.height)) + self.start_calculation([_name_to_index(widget.name)]) def _create_context(self, widget): """ Create cairo context. @@ -144,14 +155,14 @@ class KandidController(object): """ pre: len(args) >= 1 """ - ka_debug.info('on_fitness_value_changed %f [%s]' % - (args[0].get_value(), args[0].get_name())) +# ka_debug.info('on_fitness_value_changed %f [%s]' % +# (args[0].get_value(), args[0].get_name())) self.model.fitness[_name_to_index(args[0].get_name())] \ = args[0].get_value() self._update_population_gui() def on_breed_generation(self, *args): - if ka_task.is_completed(): + if ka_task.GeneratorTask.is_completed(): # ka_debug.info('on_breed_generation entry') ka_task.GeneratorTask(self.task_breed_generation, self.on_model_completed).start() @@ -160,7 +171,7 @@ class KandidController(object): ka_debug.info('on_breed_generation ignored') def on_random_generation(self, *args): - if ka_task.is_completed(): + if ka_task.GeneratorTask.is_completed(): ka_debug.info('on_random_generation entry') ka_task.GeneratorTask(self.task_random_generation, self.on_model_completed).start() @@ -174,23 +185,35 @@ class KandidController(object): """ # ka_debug.info('on_model_completed entry') for cell_index in args[0]: - self._canvas.widgetTree.get_widget('vbox_' + str(cell_index)). \ + self._widget_tree.get_widget('vbox_' + str(cell_index)). \ set_sensitive(False) - self._start_calculation(args[0]) + self.start_calculation(args[0]) # ka_debug.info('on_model_completed exit') - def _start_calculation(self, concerned): + def on_timer(self, *args): + if self._start_from_scratch: + self._start_from_scratch = False + ka_debug.info('on_timer _start_from_scratch') + self.start_all_calculations() + + def start_all_calculations(self): + self._start_from_scratch = False + ka_debug.info('start_all_calculations %u' % (self.model.size)) + self.start_calculation([i for i in range(self.model.size)]) + + def start_calculation(self, concerned): """ pre: len(concerned) > 0 pre: forall(concerned, lambda x: 0 <= x <= self.model.size) """ for cell_index in concerned: - widget = self._canvas.widgetTree.get_widget('drawingarea_' + widget = self._widget_tree.get_widget('drawingarea_' + str(cell_index)) task = ka_task.GeneratorTask(self.task_render, self.on_image_completed) task.start(self.model.protozoans[cell_index], cell_index, widget.allocation.width, widget.allocation.height) + ka_debug.info('start_calculation %ux%u for %s' % (widget.allocation.width, widget.allocation.height, widget.name)) def task_breed_generation(self, *args, **kwargs): """ @@ -199,6 +222,7 @@ class KandidController(object): # ka_debug.info('task_breed_generation entry') new_indices = self.model.breed() # ka_debug.info('task_breed_generation exit') + ka_task.GeneratorTask.leave() return new_indices def task_random_generation(self, *args, **kwargs): @@ -208,31 +232,34 @@ class KandidController(object): # ka_debug.info('task_random_generation entry') new_indices = self.model.random() # ka_debug.info('task_random_generation exit') + ka_task.GeneratorTask.leave() return new_indices def task_render(self, *args, **kwargs): """ pre: len(args) == 4 """ - protozoon, cell_index, width, height = args[0], args[1], args[2], args[3] + protozoon, cell_index, width, height = \ + args[0], args[1], args[2], args[3] # ka_debug.info('task_render entry: ' + str(cell_index)) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) ctx = cairo.Context(surface) protozoon.render(ctx, width, height) self.surface_cache[cell_index] = surface # ka_debug.info('task_render exit: ' + str(cell_index)) + ka_task.GeneratorTask.leave() return cell_index def on_image_completed(self, *args): # ka_debug.info('on_image_completed: ' + str(args[0])) cell_index = args[0] - widget = self._canvas.widgetTree.get_widget('drawingarea_' + widget = self._widget_tree.get_widget('drawingarea_' + str(cell_index)) self._draw_from_cache(widget, cell_index) - self._canvas.widgetTree.get_widget('vbox_' + str(cell_index)). \ + self._widget_tree.get_widget('vbox_' + str(cell_index)). \ set_sensitive(True) - self._canvas.widgetTree.get_widget('fitness_' + str(cell_index)). \ - set_value(self.model.fitness[cell_index]) + self._widget_tree.get_widget('fitness_' + str(cell_index)). \ + set_value(self.model.fitness[cell_index]) def on_flurry_value_changed(self, *args): """ @@ -240,7 +267,7 @@ class KandidController(object): pre: 0 <= args[0].get_value() <= 9 """ ka_debug.info('on_flurry_value_changed [%s]' % args[0].get_value()) - ka_random.set_flurry(args[0].get_value()) + model_random.set_flurry(args[0].get_value()) def on_protozoon_popup(self, widget, event): ka_debug.info('on_protozoon_popup: ' + widget.name) @@ -276,15 +303,31 @@ class KandidController(object): """Update population or protozoon preview when received from others.""" ka_debug.info('on_received: Received %u bytes, type: [%s] md5: [%s]' % \ (len(code_element), code_type, code_md5)) - inbox_widget = self._canvas.widgetTree.get_widget('incomingBox') + inbox_widget = self._widget_tree.get_widget('incomingBox') if code_type == kandidtube.SEND_POPULATION: - if self.is_overwrite_allowed: + if self.is_overwrite_allowed(): + self._start_from_scratch = False self._update_model(model_population.from_buffer(code_element)) - self.model._state = model_population.STATE_EVOLVED - inbox_widget.queue_draw() + self.start_all_calculations() else: - ka_debug.info("I've already an evolved population, doing nothing") + in_model = model_population.from_buffer(code_element) + max_fit, best_ix, second_ix = -1, -1, -1 + for index, fit in enumerate(in_model.fitness): + if fit > max_fit: + second_ix = best_ix + best_ix, max_fit = index, fit + if best_ix >= 0: + self.incoming.append_protozoon(in_model.protozoans[best_ix]) + if second_ix >= 0: + self.incoming.append_protozoon(in_model.protozoans[second_ix]) + if best_ix >= 0 or second_ix >= 0: + ka_debug.info("I've already an evolved population, proposing protozoon %d, %d." % (best_ix, second_ix)) + inbox_widget.queue_draw() + self._update_incomming_gui() + else: + ka_debug.info("I've already an evolved population, ignore incoming protozoon.") elif code_type == kandidtube.SEND_PROTOZOON: + ka_debug.info("Proposing protozoon.") self.incoming.append_protozoon(model_population.from_buffer(code_element)) inbox_widget.queue_draw() self._update_incomming_gui() @@ -311,30 +354,30 @@ class KandidController(object): def _show_popup(self, widget, event, menu): ka_debug.info('%s [%s]' % (menu, widget.name)) index = _name_to_index(menu) - self._canvas.widgetTree.get_widget('favorite_menuitem_' + str(index)). \ + self._widget_tree.get_widget('favorite_menuitem_' + str(index)). \ set_sensitive(self.model.fitness[index] < 9.0) - self._canvas.widgetTree.get_widget('awfull_menuitem_' + str(index)). \ + self._widget_tree.get_widget('awfull_menuitem_' + str(index)). \ set_sensitive(self.model.fitness[index] > 0.0) - popup_menu = self._canvas.widgetTree.get_widget(menu) + popup_menu = self._widget_tree.get_widget(menu) popup_menu.popup(None, None, None, event.button, event.time) def on_accept_incoming(self, menu_item): ka_debug.info('on_accept_incoming [%s]' % menu_item.parent.name) new_at = self.incoming.accept_protozoon(self.model, \ _name_to_index(menu_item.parent.name)) - self._start_calculation([new_at]) - inbox_widget = self._canvas.widgetTree.get_widget('incomingBox') + self.start_calculation([new_at]) + inbox_widget = self._widget_tree.get_widget('incomingBox') self._update_incomming_gui() inbox_widget.queue_draw() def on_decline_incoming(self, menu_item): ka_debug.info('on_decline_incoming [%s]' % menu_item.parent.name) self.incoming.decline_protozoon(_name_to_index(menu_item.parent.name)) - inbox_widget = self._canvas.widgetTree.get_widget('incomingBox') + inbox_widget = self._widget_tree.get_widget('incomingBox') self._update_incomming_gui() inbox_widget.queue_draw() - def on_incomingarea_expose(self, widget, event): + def on_incomingarea_expose(self, widget, dummy): """ Repaint image of a single protozoon inside incoming area. pre: widget is not None """ @@ -356,7 +399,9 @@ class KandidController(object): """Delegate reading from journal to data model pre: (file_path is not None) and (len(file_path) >= 1) """ + self._start_from_scratch = False self._update_model(model_population.read_file(file_path)) + self.start_all_calculations() def write_file(self, file_path): """Delegate writing data model to journal |