Hello,

I was wondering what would be a good way to have a Label showing the 
content of a variable, and updating automatically when the variable 
changes. I made something like this but I would love to hear if you have 
something better for me.

import cocos
from cocos.director import director

import pyglet

class Observable(pyglet.event.EventDispatcher):
    """
    A value that will fire an on_change event when its value
    is changed.
    """
    
    _value = 0
    
    def __init__(self, value, *args, **kwargs):
        super(Observable, self).__init__(*args, **kwargs)
        self.value = value
    
    def _set_value(self, new_value):
        self._value = new_value
        self.dispatch_event("on_change", self.value)
    
    value = property(lambda self: self._value, _set_value)
    
Observable.register_event_type("on_change")

class TestLayer(cocos.layer.Layer):
    """
    The layer containing the timer
    """
    def __init__(self):
        super( TestLayer, self ).__init__()

        self.timer = Observable(0)
        
        @self.timer.event
        def on_change(timer):
            self.timer_label.element.text = "Time: {}s".format(timer)

        self.timer_label = cocos.text.Label("Time: 
{}s".format(self.timer.value), 
                                            position=(100, 100), 
font_size=20)
        self.add(self.timer_label)
        
        self.schedule_interval(self.increase_timer, 1)

    def increase_timer(self, dt):
        self.timer.value += 1

if __name__ == "__main__":
    # director init takes the same arguments as pyglet.window
    director.init(width=800, height=600, do_not_scale=True)
    director.run( cocos.scene.Scene( TestLayer() ) )

What I don't like too much with this method is that I have to reference the 
timer.value to manipulate my variable, instead of having just a timer 
variable.

Another solution I had, inspired by CocosNode make_property function was to 
create properties with the setter calling a callback.


import cocos
from cocos.director import director

import pyglet

class TestLayer(cocos.layer.Layer):
    """
    The layer containing the timer
    """
    def __init__(self):
        super( TestLayer, self ).__init__()
        self.timer_label = cocos.text.Label("Time: 0s",  # Problem, I 
cannot yet reference self.timer
                                            position=(100, 100), 
font_size=20)
        self.add(self.timer_label)
        self.timer = 0 # Problem: if I set this before creating the label, 
on_timer is called and self.timer_label does not yet exist
        
        self.schedule_interval(self.increase_timer, 1)

    def increase_timer(self, dt):
        self.timer += 1

    def on_timer(self, value):
        self.timer_label.element.text = "Time: {}s".format(value)
    
    def make_property(attr):
        def set_attr():
            def inner(self, value):
                setattr(self, "_"+attr, value)
                #Call the function on_attributename passing the new value 
as arg.
                getattr(self, "on_" + attr)(value)
            return inner
        def get_attr():
            def inner(self):
                return getattr(self, "_"+attr)
            return inner
        return property(
            get_attr(),
            set_attr())
    timer = make_property("timer")
    

if __name__ == "__main__":
    # director init takes the same arguments as pyglet.window
    director.init(width=800, height=600, do_not_scale=True)
    director.run( cocos.scene.Scene( TestLayer() ) )

As I wrote in the code, this leads some problem of setting first the timer 
property or creating first the label.

Thanks for your comments and suggestions!

Dan.

-- 
You received this message because you are subscribed to the Google Groups 
"cocos2d discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/cocos-discuss.
For more options, visit https://groups.google.com/d/optout.

Reply via email to