]>
Dogcows Code - chaz/yoink/blob - src/Moof/Core.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
19 #include "fastevents.h"
25 #include "ModalDialog.hh"
26 #include "Settings.hh"
47 if (settings
.get("rngseed", randomSeed
)) srand(randomSeed
);
50 Scalar timestep
= 80.0;
51 settings
.get("timestep", timestep
);
52 mTimestep
= 1.0 / timestep
;
54 Scalar framerate
= 40.0;
55 settings
.get("framerate", framerate
);
56 mFramerate
= 1.0 / framerate
;
59 settings
.get("showfps", mShowFps
);
64 * The main loop. This just calls dispatchEvents(), update(), and
65 * draw() over and over again. The timing of the update and draw are
66 * decoupled. The actual frame rate is also calculated here. This
67 * function will return the exit code used to stop the loop.
74 Scalar totalTime
= 0.0;
75 Scalar ticks
= Timer::getTicks();
77 Scalar nextUpdate
= ticks
;
78 Scalar nextDraw
= ticks
;
79 Scalar nextSecond
= ticks
+ SCALAR(1.0);
84 const int MAX_FRAMESKIP
= 15;
85 const Scalar inverseTimestep
= SCALAR(1.0) / mTimestep
;
87 ASSERT(video
&& "cannot run core without a current video context");
91 Timer::fireIfExpired();
95 while (nextUpdate
< Timer::getTicks() && i
< MAX_FRAMESKIP
)
97 totalTime
+= mTimestep
;
98 update(totalTime
, mTimestep
);
100 nextUpdate
+= mTimestep
;
104 if (nextDraw
< (ticks
= Timer::getTicks()))
107 draw((ticks
+ mTimestep
- nextUpdate
) * inverseTimestep
);
110 nextDraw
+= mFramerate
;
112 if (mShowFps
&& nextSecond
< ticks
)
117 logInfo
<< mFps
<< " fps" << std::endl
;
119 nextSecond
+= SCALAR(1.0);
123 // be a good citizen and give back what you don't need
126 while (!mStack
.empty());
128 mDispatch
.dispatch("engine.stopping");
132 void dispatchEvents()
136 while (FE_PollEvent(&event
) == 1)
141 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
&&
142 (SDL_GetModState() & KMOD_CTRL
) )
145 logWarning("escape forced");
150 case SDL_VIDEORESIZE
:
151 video
->resize(event
.resize
.w
, event
.resize
.h
);
160 void update(Scalar t
, Scalar dt
)
162 for (mStackIt
= mStack
.begin(); mStackIt
!= mStack
.end();
165 (*mStackIt
)->update(t
, dt
);
169 void draw(Scalar alpha
)
171 // FIXME - this will crash if the layer being drawn pops itself
172 std::list
<LayerP
>::reverse_iterator it
;
173 for (it
= mStack
.rbegin(); it
!= mStack
.rend(); ++it
)
179 void handleEvent(const Event
& event
)
181 for (mStackIt
= mStack
.begin(); mStackIt
!= mStack
.end();
184 if ((*mStackIt
)->handleEvent(event
)) break;
189 void push(LayerP layer
)
191 ASSERT(layer
&& "cannot push null layer");
192 mStack
.push_front(layer
);
193 logInfo
<< "stack: " << mStack
.size()
194 << " [pushed " << layer
.get() << "]" << std::endl
;
195 layer
->addedToCore();
201 if (mStack
.begin() == mStackIt
) fixIt
= true;
203 LayerP layer
= mStack
.front();
205 logInfo
<< "stack: " << mStack
.size()
206 << " [popped " << layer
.get() << "]" << std::endl
;
207 layer
->removedFromCore();
209 if (fixIt
) mStackIt
= --mStack
.begin();
214 LayerP
pop(Layer
* layer
)
218 std::list
<LayerP
> layers
;
220 std::list
<LayerP
>::iterator it
;
221 for (it
= mStack
.begin(); it
!= mStack
.end(); ++it
)
223 layers
.push_back(*it
);
225 if (it
== mStackIt
) fixIt
= true;
227 if ((*it
).get() == layer
)
230 mStack
.erase(mStack
.begin(), it
);
232 for (it
= layers
.begin(); it
!= layers
.end(); ++it
)
234 (*it
)->removedFromCore();
235 logInfo
<< "stack: " << mStack
.size()
236 << " [popped " << (*it
).get() << "]"
240 if (fixIt
) mStackIt
= --mStack
.begin();
242 return layers
.back();
252 mStackIt
= mStack
.begin();
253 logInfo("stack: 0 [cleared]");
261 std::list
<LayerP
> mStack
;
262 std::list
<LayerP
>::iterator mStackIt
;
274 mImpl(new Core::Impl
) {}
284 int Core::getFps() const
290 void Core::push(LayerP layer
)
302 LayerP
Core::pop(Layer
* layer
)
305 return mImpl
->pop(layer
);
314 int Core::getSize() const
316 return mImpl
->mStack
.size();
327 Dispatch::Handler
Core::addHandler(const std::string
& event
,
328 const Dispatch::Function
& callback
)
330 return mImpl
->mDispatch
.addHandler(event
, callback
);
333 Dispatch::Handler
Core::addHandler(const std::string
& event
,
334 const Dispatch::Function
& callback
,
335 Dispatch::Handler handler
)
337 return mImpl
->mDispatch
.addHandler(event
, callback
, handler
);
340 void Core::dispatch(const std::string
& event
,
341 const Dispatch::Message
* message
)
343 mImpl
->mDispatch
.dispatch(event
, message
);
351 typedef boost::shared_ptr
<Backend_
> BackendP
;
359 #if defined(_WIN32) || defined(__WIN32__)
360 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
) != 0)
362 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_EVENTTHREAD
) != 0)
365 const char* error
= SDL_GetError();
366 gError
.init(Error::SDL_INIT
, error
);
372 SDL_VideoDriverName(name
, sizeof(name
));
373 logInfo
<< "initialized SDL; using video driver `"
374 << name
<< "'" << std::endl
;
379 const char* error
= FE_GetError();
380 gError
.init(Error::FASTEVENTS_INIT
, error
);
384 gError
.init(Error::NONE
);
395 if (gRetainCount
++ == 0)
397 gInstance
= BackendP(new Backend_
);
401 static void release()
403 if (--gRetainCount
== 0)
410 static const Error
& getError()
418 static int gRetainCount
;
419 static BackendP gInstance
;
422 Error
Backend_::gError(Error::UNINITIALIZED
);
423 int Backend_::gRetainCount
= 0;
424 BackendP
Backend_::gInstance
;
437 bool Backend::isInitialized()
439 return getError().code() == Error::NONE
;
442 const Error
& Backend::getError()
444 return Backend_::getError();
This page took 0.052272 seconds and 5 git commands to generate.