Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/ka_controller.py
diff options
context:
space:
mode:
authorThomas 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)
commit7ce7155dead3893e572006588fc342fb3af7ec60 (patch)
tree2bb234d6d159aa797767bf1ceccea53117dc773a /ka_controller.py
parentbcde11455168a07de8a3b17f2a4d77ce8931e75d (diff)
Layers are now arranged as a tree data structure.
Diffstat (limited to 'ka_controller.py')
-rw-r--r--ka_controller.py137
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