Added new pages and docs
[sdlgit/SDL-Site.git] / pages / SDLx-Controller.html-inc
index ecfccd0..f01db69 100644 (file)
@@ -3,18 +3,20 @@
 <h3 id="TOP">Index</h3>
 
 <ul><li><a href="#NAME">NAME</a></li>
+<li><a href="#CATEGORY">CATEGORY</a></li>
 <li><a href="#SYNOPSIS">SYNOPSIS</a>
 <ul><li><a href="#DESCRIPTION">DESCRIPTION</a></li>
 </ul>
 </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 =&gt; 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="#paused">paused</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>
@@ -22,6 +24,9 @@
 <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="CATEGORY">CATEGORY</h1><p><a href="#TOP" class="toplink">Top</a></p>
+<div id="CATEGORY_CONTENT">
+<p>Extension, Controller</p>
 
 </div>
 <h1 id="SYNOPSIS">SYNOPSIS</h1><p><a href="#TOP" class="toplink">Top</a></p>
 <div id="SYNOPSIS_CONTENT">
-<pre>  use SDLx::Controller
-
-  # create our controller object
-  my $app = SDLx::Controller-&gt;new;
+<pre> use SDLx::Controller;
 
-  # register some callbacks
-  $app-&gt;add_event_handler( \&amp;on_event );
-  $app-&gt;add_move_handler( \&amp;on_move );
-  $app-&gt;add_show_handler( \&amp;on_show );
-
-  # run our game loop
-  $app-&gt;run;
+ # create our controller object
+ my $app = SDLx::Controller-&gt;new;
 
+ # we could also do:
+ my $app = SDLx::App-&gt;new;
+ # because App is also a controller
 
+ # register some callbacks
+ $app-&gt;add_event_handler( \&amp;on_event );
+ $app-&gt;add_move_handler( \&amp;on_move );
+ $app-&gt;add_show_handler( \&amp;on_show );
 
+ # run our game loop
+ $app-&gt;run;
 
 </pre>
 
 </div>
 <h2 id="DESCRIPTION">DESCRIPTION</h2>
 <div id="DESCRIPTION_CONTENT">
-<p>The core of a SDL application/game is the main loop, where you handle events
+<p>The core of an SDL application/game is the main loop, where you handle events
 and display your elements on the screen until something signals the end of
 the program. This usually goes in the form of:</p>
 <pre>  while (1) {
@@ -76,7 +87,7 @@ MS-DOS games, anyone?).</p>
 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>
 
@@ -87,27 +98,113 @@ ease.</p>
 </div>
 <h2 id="new">new</h2>
 <div id="new_CONTENT">
+<pre> SDLx::Controller-&gt;new(
+     dt    =&gt; 0.5,
+     min_t =&gt; 0,
+     event =&gt; $event_object,
+ );
 
-</div>
-<h2 id="new_dt_gt_0_5">new( dt =&gt; 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> at 1 / 60 ensures that the controller can update the screen at a maximum of 60 times per second.
+A &quot;V-Sync&quot; such as this is necessary to prevent video &quot;tear&quot;, which occurs when the app is updating faster than the monitor can display.
+Setting it to 0, as seen above, will let the app run as fast as it possibly can.</p>
+<p><code>delay</code> specifies a loop delay in millisecs to place on the controller loop. <strong>NOTE:</strong> Picking a good delay based on the needs can help reduce CPU load and pressure.</p>
+<p><code>event</code> is a SDL::Event object that events going to the event callbacks are polled in to. It defaults to <code>SDL::Event-&gt;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 repeat the process.</p>
+<p>This can be used to easily implement a pause when the app loses focus:</p>
+<pre> sub window {
+     my ($e, $app) = @_;
+     if($e-&gt;type == SDL_QUIT) {
+                $app-&gt;stop;
+         # quit handling is here so that the app
+         # can be stopped while paused
+     }
+     elsif($e-&gt;type == SDL_ACTIVEEVENT) {
+         if($e-&gt;active_state &amp; SDL_APPINPUTFOCUS) {
+             if($e-&gt;active_gain) {
+                 return 1;
+             }
+             else {
+                 $app-&gt;pause(\&amp;window);
+                 # 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="paused">paused</h2>
+<div id="paused_CONTENT">
+<p>Returns 1 if the app is paused, undef otherwise.
+This is only useful when used within code that will be run by <code>pause</code>:</p>
+<pre> sub pause {
+     # press P to toggle pause
+
+     my ($e, $app) = @_;
+     if($e-&gt;type == SDL_QUIT) {
+         $app-&gt;stop;
+         # quit handling is here so that the app
+         # can be stopped while paused
+     }
+     elsif($e-&gt;type == SDL_KEYDOWN) {
+         if($e-&gt;key_sym == SDLK_P) {
+             # We're paused, so end pause
+             return 1 if $app-&gt;paused;
+
+             # We're not paused, so pause
+             $app-&gt;pause(\&amp;pause);
+         }
+     }
+     return 0;
+ }
+
+
+
+
+</pre>
 
 </div>
 <h2 id="add_event_handler">add_event_handler</h2>
@@ -115,45 +212,58 @@ undef.</p>
 <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-&gt;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 &quot;run&quot; 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-&gt;type == SDL_QUIT) {
+        $app-&gt;stop;
+    }
+ }
+ $app-&gt;add_event_handler(\&amp;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. If you need to protect against this, set a <code>min_t</code>, or put a <code>return unless $_[0]</code> at the start of every move handler.</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-&gt;move_x( $ball-&gt;x_vel * $step );
+     $ball-&gt;move_y( $ball-&gt;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 time, in seconds, since the previous call.
+The second is the <code>SDLx::Controller</code> object.</p>
+<pre> sub show_ball {
+     my ($delta, $app) = @_;
+     $app-&gt;draw_rect(
+         [ $ball-&gt;x, $ball-&gt;y, $ball-&gt;size, $ball-&gt;size ],
+         $ball-&gt;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>
@@ -190,9 +300,24 @@ The first coderef in the handler list that this matches will be removed.</p>
 <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>
+<p>See <a href="/SDL.html#AUTHORS">/SDL.html#AUTHORS</a>.</p>
 
 </div>
 <h2 id="ACKNOWLEGDEMENTS">ACKNOWLEGDEMENTS</h2>