Glop Input Design

Into the plethora of modules included in Glop I add POE. I’m going to use it under the hood, and try to hide it from the user as much as possible (well, in that postmodern way of exposing it when people want it). You’ll note that I’m coupling the design with all the libraries I’m including with it. I’m not certain that I’m making the right decision in doing so, but building abstraction layers around these kind of modules is not a simple task, and sometimes wouldn’t accomplish anything. Especially for things like POE, where the module basically is its abstraction layer.

Anyway, on to the title of this post, the input design. By “design” here, for the first time, it doesn’t mean “just an idea.” It means what I’m doing, and what I’ll be coding soon. Also, in this input design we begin to silhouette the rest of the design, which is quite exciting.

Mouse Interaction

First, every screen object implements an interface that the Glop kernel knows how to use. Among other things, this will include update (called every frame), draw, and select_draw. The latter method is the one we’re interested in, and it by default just registers a picker id and calls draw.

Whenever the mouse is clicked, it runs through all the objects in the scene and calls select_draw on them. It then finds the root of the select stack and calls select on it. This method should, and if you inherit from Glop::Actor (or whatever it turns out to be), does just call select on the next item in the stack. Then, presumably, the leaf objects will override this behavior and do something specific.

If you don’t need to do something as complex as the select_draw stuff, you can put it in a mode where it just reports all mouse click positions to a callback. In fact, the select_draw mode is just the default callback to this routine.

Keyboard Interaction

Keyboard interaction is completely different. All you do is register a callback with the global keyboard handler for a specific event. Give it an option whether you want to be called every time it changes, or every frame reporting the state. The latter mode means that you don’t have to keep track of the keystate when you’re doing an acceleration-driven object. It does that for you (well, more accurately, SDL does that for you, and it just passes along the information). The keycodes are strings with a familiar syntax: "x" (the key x), "C-x" or "C_x" (control-x), "Alt" (the obvious), etc.


    package Missile;
    use Glop;
    use Class::Closure;   # if you please
    sub CLASS {
        extends Glop::Actor;
        has(my $p) = v;   # v is short for v(0,0), which is short for v(0,0,0);
        has(my $v) = v;

        register Glop::Input::Keyboard
            'report',  # report every frame
            LEFT    => sub { $v += $STEP * v(-1,0) if $_[0] },
            RIGHT   => sub { $v += $STEP * v(1,0) if $_[0] },
            UP      => sub { $v += $STEP * v(0,1) if $_[0] },
            DOWN    => sub { $v += $STEP * v(0,-1) if $_[0] },
        # or for this insanely common case, there's a special semantic
        register Glop::Input::Keyboard
            qw(report keypad) => sub { $v += $STEP * $_[1] if $_[0] },

        method update => sub {  # This shouldn't be necessary if you're using ODE masses
                                # more on that later
            $p += $v;
        method draw => sub {
            drawing {    # Just a nicer way of saying glPush/PopMatrix
                Glop::Draw->Circle;    # default unit radius
        method select => sub {
            # see the animations post later this month for how this will work

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s