[Tutor] Learning about callbaks

Alan Gauld alan.gauld at btinternet.com
Tue Jan 1 15:17:17 CET 2008


"Michael Bernhard Arp Sørensen" <michaelarpsorensen at stevnstrup.dk> 
wrote

> I have a game class and a menu class. When the user chooses
> "quit" in the menu, I want the menu object to call a method that
> executes a quit_program() from the game class.

self.game.quit_program()

should do it.

Except in your code bekow you don't define a quit_program method
in the Game class.

> Obviously, menu is an object within the game object.

Not obviously, but it's certainly an option. You could have
kept menu as a separate object if that made more sense
to you. But having a menu contained by Game is also fine.

> -----------------
class UserInput(CommonBase):
    def __init__(self, queue, game):
        self.loop = 1
        self.queue = queue
        self.game = game

    def main(self):
        while True:
            tstr = raw_input("Input string: ")
            print "Input: ", tstr
            if tstr == "q":
                self.quitProgram()

    def quitProgram(self, game, quit_callback):
        self.loop = 0
        game.loop = 0
        quit_callback()

> ---------------------------

I'm not sure I really understand what this class is modelling.
What kind of an object is UserInput?
Does it represent a single command or is it representing an
action - getting input from the user? In which case its a
very abstract kind of object.

If this (as I think) is the "menu" that you refer to above
then I'd expect it to be responsible for displaying a menu
and obtaing a selection, it could then dispatch a message
to the associated operatrion (a callback).

However this class has a queue and game parameter that
are assigned to local attribiutes but then never used...

The main() method displays the prompt and then
calls the quit method with no arguments.

The quit method tries to use a call back function but the
call back is never passed to it.

In fact in this case you don't even need a callback
since the UserInput object has an attribute pointing
at the game object so you can call game methods
directly.

I'm also not sure what the threading stuff is needed
for either. Try to simplify the example by cutting out
all the redundant stuff and not using callbacks
initially, just call the game methods via the game
attribute.

Then once it works modify it to use callback style.

Also, in the code below you are using loop as a boolean
so it would be better to assign True/False rather than 1/0
as values.


> ----------------
class Game(CommonBase):
    def __init__(self):
        self.loop = 1
        self.queue = Queue.Queue()

    def startUI(self, tid):
        ui = UserInput(self.queue, self)
        ui.main()

    def stoploop():
        self.loop = 0

    def main(self):
        thread.start_new_thread(self.startUI, (1,))

        while self.loop:
            try:
                data = self.queue.get(block = False)
            except Queue.Empty:
                pass
            else:
                pass
            time.sleep(0.1)

g = Game()
g.main()

> Allthough I might be wrong on that point.
> I'm desperate.

I think you need to strip back and simplify, it looks like
you may have been reading too many different resources
and incorporated some ieas without really undertansding
what they do and why.

HTH,


-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 




More information about the Tutor mailing list