[Stackless] Realistic ticking and acting
Grant Olson
olsongt at verizon.net
Fri Jul 14 00:45:18 CEST 2006
>
> Is there an obvious flaw in my use of Stackless? (in Ticker5.py)
>
> Can you implement Ticker7.py more elegantly Stackless?
>
> --
> kai
>
I really do think you're making things more complex than they need to be.
I've attached a (very rough) cleanup of your Ticker5.py; I don't think it'll
make the list but it should get to you. Let me know if it doesn't.
First off, the way you're using channels, you can eliminate the .receive()
and .schedule() calls. It is important to remember some basic rules for
stackless scheduling:
+ Tasklets are added to the schedule in the order they're created.
+ A tasklet gets moved to the end of the queue if it reschedules itself.
And these two are the important ones for you:
+ A tasklet is suspended when it calls .receive() on an empty channel
+ A tasklet is suspended when it calls .send() on an empty channel.
+ If a tasklet calls .send() on a listening channel:
- the receiving tasklet is automatically activated.
- the sending tasklet is rescheduled at the end of the queue.
Right now, you're sending messages both ways: One from the ticker to the
actor, and a confirmation from the actor to the ticker. I'm guessing you
did this to try and make the ticker behave in the order you wanted, but it's
unnecessary. Assume we have three tasklets:
T = the ticker loop, sends ticks to all available actors.
A = Actor one, listening.
B = Actor two, listening.
With that, you can literally trace out the scheduling on paper.
1. T(begins loop)
2. T(sends tick to A)
3. A(gets tick and performs actions);T(scheduled after A)
4. A(finishes);T(resumes and sends tick to B)
5. B(gets tick and performs actions);T(scheduled after B)
6. B(finishes);T(resumes and finishes first round of loops)
7. T(begins loop again)
... goto step 2
There are a couple of things here:
+ You don't need to have your actors talk back to the ticker
For it to work in the right order.
+ You don't need to make calls to .schedule() because the use
Of channels takes care of that.
+ You could add a million actors, and the same basic rules and order
Would apply.
Secondly, the reason you couldn't do multiple actions in a tick is because
of where you were listening on the channel. In your code you should listen
on in the act() method. Then you can adjust the code to allow multiple
actions at once without messing up the ticker scheduling. You'll just need
to track the amount of turns that have gone by in your actions array instead
of consuming a few ticks in your (for example) .standing() method.
Thirdly, right now you're just using the channels to synchronize your
tasklets. You should really take advantage of the fact that you can send
useful information (a.k.a. a message) with that trigger. I say this because
I think your Fight() class overcomplicates things. Actor B should be able
to tell actor A that it is attacking it. Actor A should be able to adjust
its list of goals and respond accordingly when the next tick gets triggered.
Once again, here's an implementation of actor code with a reasonably
detailed description of what is going on. You may want to take a look. It
is a little different than what you're trying to do, but it exhibits
reasonably complicated interactions without a lot of code. If anything is
unclear, let me know:
http://members.verizon.net/olsongt/stackless/why_stackless.html#actors
Best of luck!
-Grant
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Ticker5.py
Url: http://www.stackless.com/pipermail/stackless/attachments/20060713/d8c08628/attachment.txt
-------------- next part --------------
_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless
More information about the Stackless
mailing list