The Synchronous Blog

A blog about reactive programming languages.

Imperative Reactivity

with 2 comments

The LINK reactivity primitive was already presented in this post.
LINK makes the use of event-driven paradigm easier, avoiding all the bureaucracy of events definition, posting and handling: they are all done implicitly.
However, in another post, we pointed out three issues in this paradigm: inversion of control, multi-core processors and listener life cycle.

This post deals with the first and more annoying limitation of event-driven programming: inversion of control.
Event-driven programming demands that its callbacks execute very fast as the event handling is serialized: while one event is being handled, others are not – only one callback executes at a time.
Callbacks are, therefore, logically instantaneous and can’t hold state. They commonly receive state (those void* parameters), decode it (to work like a state machine and know where it was left), update it and return.
The sequential execution paradigm is broken here, as control is now guided by the event queue (the environment).

LuaGravity supports reactivity inside its methods in some way like Esterel does.
The AWAIT primitive suspends the execution of a method and waits for another method (or timer) to happen.
For example, AWAIT(keyboard.ENTER.press) suspends the running method until ENTER is pressed.
AWAIT is like a LINK, but is broken when its condition happens and resumes (instead of calling) the suspended method.

A little bit confusing, huh?
Hope the following example helps.
Let’s say we want an animation to change its direction following the sequence RIGHT, DOWN, LEFT and UP when the respective keys are pressed.
Without using the AWAIT primitive, we need to hold state between successive executions of animation.changeDirection:

-- WITHOUT AWAIT
LINK(RIGHT.press,  animation.changeDirection)
LINK(DOWN.press, animation.changeDirection)
LINK(LEFT.press,    animation.changeDirection)
LINK(UP.press,       animation.changeDirection)

function animation.changeDirection (key)
    if (obj.state == 'right') and (key == 'DOWN') then
        obj.state = 'down'
        obj.x = obj.x()                -- stay here
        obj.y = obj.y() + S(obj.speed) -- move down

    elseif (obj.state == 'down') and (key == 'LEFT') then
        obj.state = 'left'
        obj.x = obj.x() - S(obj.speed) -- move left
        obj.y = obj.y()                -- stay here

    elseif (obj.state == 'left') and (key == 'UP') then
        obj.state = 'up'
        obj.x = obj.x()                -- stay here
        obj.y = obj.y() - S(obj.speed) -- move up

    elseif (obj.state == 'up') and (key == 'RIGHT') then
        obj.state = 'right'
        obj.x = obj.x() + S(obj.speed) -- move right
        obj.y = obj.y()                -- stay here
    end
end

With the use of AWAIT, we code the animation sequentially:

-- WITH AWAIT
while true do
    AWAIT(RIGHT.press)
    obj.x = obj.x() + S(obj.speed)   -- move right
    obj.y = obj.y()                  -- stay here

    AWAIT(DOWN.press)  obj.x = obj.x() -- stay here
    obj.y = obj.y() + S(obj.speed)   -- move down

    AWAIT(LEFT.press)  obj.x = obj.x() - S(obj.speed) -- move left
    obj.y = obj.y()                  -- stay here

    AWAIT(UP.press)
    obj.x = obj.x()                  -- stay here
    obj.y = obj.y() - S(obj.speed)   -- move up
end

In the code above, obj.x() takes its current position, and S(obj.speed) animates the objects (position = integral of speed).
Much cleaner with AWAIT, isn’t?
See the result in the video below:

The full example code can be found here.

Advertisements

Written by francisco

October 7, 2008 at 8:31 pm

2 Responses

Subscribe to comments with RSS.

  1. […] solution in LuaGravity uses its AWAIT […]

  2. […] solution in LuaGravity uses its AWAIT […]


Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: