]>
Dogcows Code - chaz/yoink/blob - src/moof/view.cc
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
13 #include <cstdlib> // exit, srand
14 #include <ctime> // time
18 #include "fastevents.h"
23 #include "modal_dialog.hh"
24 #include "settings.hh"
33 class root_view
: public view
35 void update(scalar t
, scalar dt
)
37 if (children().size() == 0) stop();
41 static root_view gRootView
;
48 impl(view
* view
, moof::settings
& settings
, moof::video
& video
) :
57 if (settings
.get("rngseed", randomSeed
)) srand(randomSeed
);
60 scalar timestep
= 80.0;
61 settings
.get("timestep", timestep
);
62 timestep_
= 1.0 / timestep
;
64 scalar framerate
= 40.0;
65 settings
.get("framerate", framerate
);
66 framerate_
= 1.0 / framerate
;
69 settings
.get("showfps", show_fps_
);
83 timestep_
= SCALAR(0.01);
84 framerate_
= SCALAR(0.02);
90 * The main loop. This just calls dispatch_events(), update(), and
91 * draw() over and over again. The timing of the update and draw are
92 * decoupled. The actual frame rate is also calculated here. This
93 * function will return the exit code used to stop the loop.
98 ASSERT(video_
&& "running without video set");
100 scalar totalTime
= 0.0;
101 scalar ticks
= timer::ticks();
103 scalar nextUpdate
= ticks
;
104 scalar nextDraw
= ticks
;
105 scalar nextSecond
= ticks
+ SCALAR(1.0);
110 const scalar timestep
= timestep_
;
111 const scalar framerate
= framerate_
;
113 const int MAX_FRAMESKIP
= 15;
114 const scalar inverseTimestep
= SCALAR(1.0) / timestep
;
119 timer::fire_expired_timers(); // 1. fire timers
120 dispatch_events(); // 2. dispatch events
122 if (!is_running_
) break;
125 while (nextUpdate
< timer::ticks() && i
< MAX_FRAMESKIP
)
127 totalTime
+= timestep
; // 3. update state
128 view_
.update(totalTime
, timestep
);
130 nextUpdate
+= timestep
;
133 if (!is_running_
) break;
136 if (nextDraw
< (ticks
= timer::ticks()))
139 (ticks
+ timestep
- nextUpdate
) * inverseTimestep
);
140 video_
->swap(); // 4. draw state
142 nextDraw
+= framerate
;
145 if (nextSecond
< timer::ticks())
150 if (show_fps_
) log_info
<< fps_
<< " fps" << std::endl
;
152 nextSecond
+= SCALAR(1.0);
156 if (!is_running_
) break;
158 ticks
= timer::ticks(); // 5. yield timeslice
159 if (ticks
< nextUpdate
&& ticks
< nextDraw
) timer::sleep(0.0);
169 void dispatch_events()
173 while (FE_PollEvent(&event
) == 1)
178 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
&&
179 (SDL_GetModState() & KMOD_CTRL
) )
182 log_warning("escape forced");
187 case SDL_VIDEORESIZE
:
188 video_
->resize(event
.resize
.w
, event
.resize
.h
);
192 view_
.handle_event(event
);
196 bool handle_event(const event
& event
)
198 std::list
<view_ptr
>::iterator it
;
199 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
201 if ((*it
)->handle_event(event
)) return true;
207 void update(scalar t
, scalar dt
)
209 std::list
<view_ptr
>::iterator it
;
210 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
212 (*it
)->update(t
, dt
);
216 void draw(scalar alpha
)
218 std::list
<view_ptr
>::iterator it
;
219 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
226 void add_child(view_ptr child
)
228 ASSERT(child
&& "adding null view");
229 ASSERT(child
.get() != &view_
&& "adding view to itself");
231 child
->impl_
->parent_
->remove_child(child
);
232 children_
.push_back(child
);
234 child
->impl_
->parent_
= &view_
;
235 child
->impl_
->percolate_objects();
237 child
->did_add_to_view();
240 void percolate_objects()
242 bool recurseAgain
= false;
244 if (parent_
->impl_
->video_
&& parent_
->impl_
->video_
!= video_
)
246 video_
= parent_
->impl_
->video_
;
250 if (parent_
->impl_
->settings_
&&
251 parent_
->impl_
->settings_
!= settings_
)
253 settings_
= parent_
->impl_
->settings_
;
259 std::list
<view_ptr
>::iterator it
;
260 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
262 (*it
)->impl_
->percolate_objects();
267 view_ptr
remove_child(view
* child
)
269 ASSERT(child
&& "cannot remove null child");
271 std::list
<view_ptr
>::iterator it
;
272 for (it
= children_
.begin(); it
!= children_
.end(); ++it
)
274 if ((*it
).get() == child
)
276 view_ptr found
= *it
;
277 found
->will_remove_from_view();
280 found
->impl_
->parent_
= &gRootView
;
298 moof::settings
* settings_
;
302 std::list
<view_ptr
> children_
;
312 view::view(moof::settings
& settings
, moof::video
& video
) :
314 impl_(new view::impl(this, settings
, video
)) {}
317 impl_(new view::impl(this)) {}
320 void view::update(scalar t
, scalar dt
)
323 impl_
->update(t
, dt
);
326 void view::draw(scalar alpha
) const
332 bool view::handle_event(const event
& event
)
335 return impl_
->handle_event(event
);
339 void view::add_child(view_ptr view
)
342 impl_
->add_child(view
);
345 view_ptr
view::remove_child(view
* view
)
348 return impl_
->remove_child(view
);
351 view_ptr
view::remove_child(view_ptr view
)
354 return impl_
->remove_child(view
.get());
364 view
& view::parent() const
366 return *(impl_
->parent_
);
369 const std::list
<view_ptr
>& view::children() const
371 return impl_
->children_
;
375 moof::settings
& view::settings() const
377 ASSERT(impl_
->settings_
&& "accessing null reference");
379 return *(impl_
->settings_
);
382 video
& view::video() const
384 ASSERT(impl_
->video_
&& "accessing null reference");
386 return *(impl_
->video_
);
399 return impl_
->stop();
402 bool view::is_running() const
405 return impl_
->is_running_
;
This page took 0.053186 seconds and 4 git commands to generate.