]>
Dogcows Code - chaz/yoink/blob - src/Moof/Core.cc
2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *******************************************************************************/
30 #include <cstdlib> // exit, srand
31 #include <ctime> // time
36 #include "fastevents.h"
42 #include "ModalDialog.hh"
43 #include "Settings.hh"
64 if (settings
.get("rngseed", randomSeed
)) srand(randomSeed
);
67 Scalar timestep
= 80.0;
68 settings
.get("timestep", timestep
);
69 mTimestep
= 1.0 / timestep
;
71 Scalar framerate
= 40.0;
72 settings
.get("framerate", framerate
);
73 mFramerate
= 1.0 / framerate
;
76 settings
.get("showfps", mShowFps
);
81 * The main loop. This just calls dispatchEvents(), update(), and draw()
82 * over and over again. The timing of the update and draw are decoupled.
83 * The actual frame rate is also calculated here. This function will return
84 * the exit code used to stop the loop.
91 Scalar totalTime
= 0.0;
92 Scalar ticks
= Timer::getTicks();
94 Scalar nextUpdate
= ticks
;
95 Scalar nextDraw
= ticks
;
96 Scalar nextSecond
= ticks
+ SCALAR(1.0);
101 const int MAX_FRAMESKIP
= 15;
102 const Scalar inverseTimestep
= SCALAR(1.0) / mTimestep
;
104 ASSERT(video
&& "cannot run core without a current video context");
108 Timer::fireIfExpired();
112 while (nextUpdate
< Timer::getTicks() && i
< MAX_FRAMESKIP
)
114 totalTime
+= mTimestep
;
115 update(totalTime
, mTimestep
);
117 nextUpdate
+= mTimestep
;
121 if (nextDraw
< (ticks
= Timer::getTicks()))
124 draw((ticks
+ mTimestep
- nextUpdate
) * inverseTimestep
);
127 nextDraw
+= mFramerate
;
129 if (mShowFps
&& nextSecond
< ticks
)
134 logInfo
<< mFps
<< " fps" << std::endl
;
136 nextSecond
+= SCALAR(1.0);
140 // be a good citizen and give back what you don't need
143 while (!mStack
.empty());
145 mDispatch
.dispatch("engine.stopping");
149 void dispatchEvents()
153 while (FE_PollEvent(&event
) == 1)
158 if (event
.key
.keysym
.sym
== SDLK_ESCAPE
&&
159 (SDL_GetModState() & KMOD_CTRL
) )
162 logWarning("escape forced");
167 case SDL_VIDEORESIZE
:
168 video
->resize(event
.resize
.w
, event
.resize
.h
);
177 void update(Scalar t
, Scalar dt
)
179 for (mStackIt
= mStack
.begin(); mStackIt
!= mStack
.end(); ++mStackIt
)
181 (*mStackIt
)->update(t
, dt
);
185 void draw(Scalar alpha
)
187 // FIXME - this will crash if the layer being drawn pops itself
188 std::list
<LayerP
>::reverse_iterator it
;
189 for (it
= mStack
.rbegin(); it
!= mStack
.rend(); ++it
)
195 void handleEvent(const Event
& event
)
197 for (mStackIt
= mStack
.begin(); mStackIt
!= mStack
.end(); ++mStackIt
)
199 if ((*mStackIt
)->handleEvent(event
)) break;
204 void push(LayerP layer
)
206 ASSERT(layer
&& "cannot push null layer");
207 mStack
.push_front(layer
);
208 logInfo
<< "stack: " << mStack
.size()
209 << " [pushed " << layer
.get() << "]" << std::endl
;
210 layer
->addedToCore();
216 if (mStack
.begin() == mStackIt
) fixIt
= true;
218 LayerP layer
= mStack
.front();
220 logInfo
<< "stack: " << mStack
.size()
221 << " [popped " << layer
.get() << "]" << std::endl
;
222 layer
->removedFromCore();
224 if (fixIt
) mStackIt
= --mStack
.begin();
229 LayerP
pop(Layer
* layer
)
233 std::list
<LayerP
> layers
;
235 std::list
<LayerP
>::iterator it
;
236 for (it
= mStack
.begin(); it
!= mStack
.end(); ++it
)
238 layers
.push_back(*it
);
240 if (it
== mStackIt
) fixIt
= true;
242 if ((*it
).get() == layer
)
245 mStack
.erase(mStack
.begin(), it
);
247 for (it
= layers
.begin(); it
!= layers
.end(); ++it
)
249 (*it
)->removedFromCore();
250 logInfo
<< "stack: " << mStack
.size()
251 << " [popped " << (*it
).get() << "]" << std::endl
;
254 if (fixIt
) mStackIt
= --mStack
.begin();
256 return layers
.back();
266 mStackIt
= mStack
.begin();
267 logInfo("stack: 0 [cleared]");
275 std::list
<LayerP
> mStack
;
276 std::list
<LayerP
>::iterator mStackIt
;
288 mImpl(new Core::Impl
) {}
298 int Core::getFps() const
304 void Core::push(LayerP layer
)
316 LayerP
Core::pop(Layer
* layer
)
319 return mImpl
->pop(layer
);
328 int Core::getSize() const
330 return mImpl
->mStack
.size();
341 Dispatch::Handler
Core::addHandler(const std::string
& event
,
342 const Dispatch::Function
& callback
)
344 return mImpl
->mDispatch
.addHandler(event
, callback
);
347 Dispatch::Handler
Core::addHandler(const std::string
& event
,
348 const Dispatch::Function
& callback
, Dispatch::Handler handler
)
350 return mImpl
->mDispatch
.addHandler(event
, callback
, handler
);
353 void Core::dispatch(const std::string
& event
,
354 const Dispatch::Message
* message
)
356 mImpl
->mDispatch
.dispatch(event
, message
);
364 typedef boost::shared_ptr
<Backend_
> BackendP
;
372 #if defined(_WIN32) || defined(__WIN32__)
373 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
) != 0)
375 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_EVENTTHREAD
) != 0)
378 const char* error
= SDL_GetError();
379 gError
.init(Error::SDL_INIT
, error
);
385 SDL_VideoDriverName(name
, sizeof(name
));
386 logInfo
<< "initialized SDL; using video driver `"
387 << name
<< "'" << std::endl
;
392 const char* error
= FE_GetError();
393 gError
.init(Error::FASTEVENTS_INIT
, error
);
397 gError
.init(Error::NONE
);
408 if (gRetainCount
++ == 0)
410 gInstance
= BackendP(new Backend_
);
414 static void release()
416 if (--gRetainCount
== 0)
423 static const Error
& getError()
431 static int gRetainCount
;
432 static BackendP gInstance
;
435 Error
Backend_::gError(Error::UNINITIALIZED
);
436 int Backend_::gRetainCount
= 0;
437 BackendP
Backend_::gInstance
;
450 bool Backend::isInitialized()
452 return getError().code() == Error::NONE
;
455 const Error
& Backend::getError()
457 return Backend_::getError();
463 /** vim: set ts=4 sw=4 tw=80: *************************************************/
This page took 0.064681 seconds and 5 git commands to generate.