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