</li>
<li><a href="#METHODS">METHODS</a>
<ul><li><a href="#new">new</a></li>
-<li><a href="#new_dt_gt_0_5">new( dt => 0.5 )</a></li>
<li><a href="#run">run</a></li>
+<li><a href="#stop">stop</a></li>
+<li><a href="#pause">pause</a></li>
<li><a href="#add_event_handler">add_event_handler</a></li>
<li><a href="#add_move_handler">add_move_handler</a></li>
<li><a href="#add_show_handler">add_show_handler</a></li>
-<li><a href="#quit">quit</a></li>
<li><a href="#remove_move_handler_index">remove_move_handler( $index )</a></li>
<li><a href="#remove_event_handler_index">remove_event_handler( $index )</a></li>
<li><a href="#remove_show_handler_index">remove_show_handler( $index )</a></li>
<li><a href="#remove_all_event_handlers">remove_all_event_handlers</a></li>
<li><a href="#remove_all_show_handlers">remove_all_show_handlers</a></li>
<li><a href="#remove_all_handlers">remove_all_handlers</a></li>
+<li><a href="#dt">dt</a></li>
+<li><a href="#min_t">min_t</a></li>
+<li><a href="#current_time">current_time</a></li>
</ul>
</li>
<li><a href="#AUTHORS">AUTHORS</a>
<h1 id="NAME">NAME</h1><p><a href="#TOP" class="toplink">Top</a></p>
<div id="NAME_CONTENT">
-<p>SDLx::Controller - Handles the loops for event, movement and rendering</p>
+<p>SDLx::Controller - Handles the loops for events, movement and rendering</p>
</div>
<h1 id="SYNOPSIS">SYNOPSIS</h1><p><a href="#TOP" class="toplink">Top</a></p>
<div id="SYNOPSIS_CONTENT">
-<pre> use SDLx::Controller
+<pre> use SDLx::Controller;
# create our controller object
my $app = SDLx::Controller->new;
matter what, but this is not the right way to do it as it penalizes better
hardware.</p>
<p>This module provides an industry-proven standard for frame independent
-movement. It calls the movement handlers based on time (tick counts) rather
+movement. It calls the movement handlers based on time (hi-res seconds) rather
than frame rate. You can add/remove handlers and control your main loop with
ease.</p>
</div>
<h2 id="new">new</h2>
<div id="new_CONTENT">
+<pre> SDLx::Controller->new(
+ dt => 0.5,
+ min_t => 0,
+ event => $event_object,
+ );
-</div>
-<h2 id="new_dt_gt_0_5">new( dt => 0.5 )</h2>
-<div id="new_dt_gt_0_5_CONTENT">
-<p>Controller construction. Optional <code>dt</code> parameter indicates delta t times
-in which to call the movement handlers, and defaults to 0.1.</p>
+</pre>
+<p>The <code>dt</code> parameter specifies the length, in seconds, of a full movement step, and defaults to 0.1.
+The <code>dt</code> can be anything and the game can still look the same.
+It is only when you change the <code>dt</code> without changing all the things in the movement step that are being multiplied by the first move argument that it will make a difference.
+If you lower the <code>dt</code>, everything will move faster than it did with it set higher, and vice-versa.
+This is useful to add slo-mo and fast-forward features to the game, all you would have to do is change the <code>dt</code>.</p>
+<p><code>min_t</code> specifies the minimum time, in seconds, that has to accumulate before any move or show handlers are called, and defaults to 1 / 60.
+Having the <code>min_t</code> to 1 / 60 ensures that the controller can update the screen at a maximum of 60 times per second.
+A "V-Sync" such as this is necessary to prevent video "tear", which occurs when the app is updating faster than the monitor can display.
+Setting it to 0, as in the example, will let the app run as fast as it possibly can.</p>
+<p><code>event</code> is a SDL::Event object that events going to the event callbacks are polled in to. Defaults to <code>SDL::Event->new()</code>.</p>
+<p>All parameters are optional.</p>
<p>Returns the new object.</p>
</div>
<h2 id="run">run</h2>
<div id="run_CONTENT">
<p>After creating and setting up your handlers (see below), call this method to
-activate the main loop. The main loop will run until an event handler returns
-undef.</p>
+activate the main loop. The main loop will run until <code>stop</code> is called.</p>
<p>All hooked functions will be called during the main loop, in this order:</p>
<dl>
<dt>1. Events</dt>
<dt>2. Movements</dt>
<dt>3. Displaying</dt>
</dl>
-<p>Please refer to each handler below for information on received arguments.</p>
+<p>Please refer to each handler below for information on received arguments.
+Note that the second argument every callback recieves is the <code>SDLx::Controller</code> object.</p>
+
+</div>
+<h2 id="stop">stop</h2>
+<div id="stop_CONTENT">
+<p>Returns from the <code>run</code> loop.</p>
+
+</div>
+<h2 id="pause">pause</h2>
+<div id="pause_CONTENT">
+<p>Attempts to pause the application with a call to <code>SDL::Events::wait_event</code>. See <a href="SDL-Events.html">SDL::Events</a>.</p>
+<p>Takes 1 argument which is a callback. The application waits for the next event with <code>wait_event</code>.
+When one is recieved, it is passed to the callback as the first argument, along with the <code>SDLx::Controller</code> object as the second argument.
+If the callback then returns a true value, <code>pause</code> will return.
+If the callback returns a false value, <code>pause</code> will indefinitely wait for more events, repeating the process, until the callback returns true.</p>
+<p>This can be used to easily implement a pause when the app loses focus:</p>
+<pre> sub focus {
+ my ($e, $controller) = @_;
+ if($e->type == SDL_ACTIVEEVENT) {
+ if($e->active_state & SDL_APPINPUTFOCUS) {
+ if($e->active_gain) {
+ return 1;
+ }
+ else {
+ $controller->pause(\&focus);
+ # recursive, but only once since the window
+ # can't lose focus again without gaining is first
+ }
+ }
+ }
+ return 0;
+ }
+
+</pre>
+<p>Note: if you implement your own pause function, remember to update <code>current_time</code> to the current time when the application unpauses.
+This should be done with <code>Time::HiRes::time</code>.
+Otherwise, time will accumulate while the application is paused, and many movement steps will be called all at once when it unpauses.</p>
+<p>Note 2: a pause will be potentially dangerous to the <code>run</code> cycle (even if you implement your own) unless called by an <code>event</code> callback.</p>
</div>
<h2 id="add_event_handler">add_event_handler</h2>
<p>Register a callback to handle events. You can add as many subs as you need.
Whenever a SDL::Event occurs, all registered callbacks will be triggered in
order. Returns the order queue number of the added callback.</p>
-<p>The first (and only) argument passed to registered callbacks is the
-<a href="SDL-Event.html">SDL::Event</a> object itself, so you can test for <code>$event->type</code>, etc.</p>
-<p>Each event handler is <strong>required</strong> to return a defined value for the main loop
-to continue. To exit the main loop (see "run" above), return <code>undef</code> or
-nothing at all.</p>
-
-
-
+<p>The first argument passed to registered callbacks is the <a href="SDL-Event.html">SDL::Event</a> object.
+The second is the <code>SDLx::Controller</code> object.</p>
+<pre> sub stop {
+ my ($event, $app) = @_;
+ if($event->type == SDL_QUIT) {
+ $controller->stop;
+ }
+ }
+ $controller->add_event_handler(\&stop);
+</pre>
</div>
<h2 id="add_move_handler">add_move_handler</h2>
<div id="add_move_handler_CONTENT">
<p>Register a callback to update your objects. You can add as many subs as
you need. Returns the order queue number of the added callback.</p>
-<p>All registered callbacks will be triggered in order for as many
-<code>dt</code> as have happened between calls. You should use these handlers to update
-your in-game objects, check collisions, etc.</p>
-<p>The first (and only) argument passed is a reference to the dt value itself,
+<p>All registered callbacks will be triggered in order for as many <code>dt</code> as have happened between calls,
+and once more for any remaining time less than <code>dt</code>.
+The first argument passed to the callbacks is the portion of the step, which will be 1 for a full step, and less than 1 for a partial step.
+Movement values should be multiplied by this value.
+The full steps correspond to the amount of <code>dt</code> passed between calls, and the partial step corresponds to the call with the remaining time less than <code>dt</code>.
+The argument can be 0 if no time has passed since the last cycle. Set a <code>min_t</code> if you need to protect against this.</p>
+<p>The second argument passed to the callbacks is the <code>SDLx::Controller</code> object.
+The third is the total amount of time passed since the call of <code>run</code>.</p>
+<p>You should use these handlers to update your in-game objects, check collisions, etc.
so you can check and/or update it as necessary.</p>
-<p>Any returned values are ignored.</p>
-
-
-
+<pre> sub move_ball {
+ my ($step, $app, $t) = @_;
+ $ball->move_x( $ball->x_vel * $step );
+ $ball->move_y( $ball->y_vel * $step );
+ }
+</pre>
</div>
<h2 id="add_show_handler">add_show_handler</h2>
<div id="add_show_handler_CONTENT">
<p>Register a callback to render objects. You can add as many subs as you need.
-Returns the order queue number of the added callback.</p>
-<p>All registered callbacks will be triggered in order, once per run of the main
-loop. The first (and only) argument passed is the number of ticks since
-the previous round.</p>
+Returns the order queue number of the added callback.
+All registered callbacks will be triggered in order, once per run of the <code>run</code> loop.</p>
+<p>The first argument passed is the number of ticks since the previous call.
+The second is the <code>SDLx::Controller</code> object.</p>
+<pre> sub show_ball {
+ my ($delta, $app) = @_;
+ $app->draw_rect(
+ [ $ball->x, $ball->y, $ball->size, $ball->size ],
+ $ball->colour
+ );
+ }
-</div>
-<h2 id="quit">quit</h2>
-<div id="quit_CONTENT">
-<p>Exits the main loop. Calling this method will cause <code>run</code> to return.</p>
+</pre>
</div>
<h2 id="remove_move_handler_index">remove_move_handler( $index )</h2>
<p>Quick access to removing all handlers at once.</p>
</div>
+<h2 id="dt">dt</h2>
+<div id="dt_CONTENT">
+
+</div>
+<h2 id="min_t">min_t</h2>
+<div id="min_t_CONTENT">
+
+</div>
+<h2 id="current_time">current_time</h2>
+<div id="current_time_CONTENT">
+<p>If an argument is passed, modifies the corresponding value to the argument.
+<code>dt</code> and <code>min_t</code> will keep their old value until the beginning of the next <code>run</code> cycle.</p>
+<p>Returns the corresponding value.</p>
+
+</div>
<h1 id="AUTHORS">AUTHORS</h1><p><a href="#TOP" class="toplink">Top</a></p>
<div id="AUTHORS_CONTENT">
<p>See <b>AUTHORS</b> in <cite>SDL</cite>.</p>