Hi Kristian,

Kristian Lippert a écrit :
> Hi
> I have a play-method in my own stream-player and it works:
> 
>     def node_clicked(self, widget, item):
>         def play_uri(self, station):
>             # We already know the real URL of the playable audio stream, no
>             # need to query the resource manager
>             # get player and start playing
>             player =
> self.frontend.retrieve_controllers('/poblesec/music_player')[0]
>             player.player.play_model(station)
>             main = self.frontend.retrieve_controllers('/poblesec')[0]
>             main.show_music_player()
>             self.stop_loading_animation()
> 
>         pdb.set_trace()
>         if isinstance(item, Action):
>             item.run()

Side note: this test is useless if you know that your list contains only
PlayableModels.

>         elif isinstance(item, PlayableModel):
>             play_uri(self, item)
> 
> It works fine but if there are problems with the stream it will hang for
> a while, so I thought I could use a deferred, like:
> 
>     def node_clicked(self, widget, item):
> 
>         def play_uri(self, station):
>             # We already know the real URL of the playable audio stream, no
>             # need to query the resource manager
>             # get player and start playing
>             player =
> self.frontend.retrieve_controllers('/poblesec/music_player')[0]
>             player.player.play_model(station)
> 
>             main = self.frontend.retrieve_controllers('/poblesec')[0]
>             main.show_music_player()
>             self.stop_loading_animation()
> 
>         pdb.set_trace()
>         if isinstance(item, Action):
>             item.run()
>         elif isinstance(item, PlayableModel):
>             dfr = defer.Deferred().addCallback(play_uri)
>             return dfr(self, item)
> 
> My problem is that I am not sure:
> 1) Do I create the deferred in the right manner?

Not really, see my explanation below.

> 2) How does the binding of the parameters happen?

Simply pass extra arguments to the addCallback method, they are going to
be passed to the callback after the result argument.

> 3) Do I need to activate the deferred my self or will this happen by
> magic by it self?

If you instantiate a deferred with defer.Deferred(), then nothing won't
happen until someone/something invokes its callback() method, that will
in turn trigger the chained callbacks to be called.

One simple example:

def cb(result, arg1, arg2):
    print result, arg1, arg2

dfr = defer.Deferred()
dfr.addCallback(cb, 'hello', 'world')
dfr.callback()

If you want to try it out as is in a python shell, you'll have to import
twisted.internet.reactor, and call reactor.run().

> As far as I can read the deferred can be compared to the .NET
> asynchronous delegates or boost::thread. Boost::thread is much simpler
> but they share the problem regarding binding variables.

Unfortunately deferreds won't magically make synchronous code
asynchronous. They are a tool to help you write asynchronous code, but
in that case the underlying methods you are calling
(player.player.play_model, main.show_music_player,
self.stop_loading_animation) are all synchronous (in the sense that they
don't return a deferred). You could mock asynchrony by calling them in a
thread, but that's highly discouraged so I'm not giving you the link to
the doc of the method that allows that ;)

> Please help me fix the code!
> 
> Best Regards,
> Kristian

I hope this helps.

Olivier

Reply via email to