
Moderators: Sascha Willems, walaber
Julio Jerez wrote:Kella I am having so many problems with Ogre architecture.
here is one of the them, in the OgreRoot the mFrameListeners container is a stl::set, this is huge mistake, it should be a List or a Vector and each Listeners should be added to the end of the array.
Sets are only useful for when you are dealing with lot of items, but an application will only have very few listeners so the benefit of a set is not justified while they add lot of chaotic behavior to the end application.
The Listeners in the set are sorted by the pointer, the causes that the end application does not know the order or execution.
In one of the demos there are three listeners, one is the timestep calculator, the second is the Newton Listener, and then there is the controller update.
Here is the problem it does not matter what order they are added to the ListenerSet, the order is not the same even from machine to machine or form run to run of the same same app.
Ideally you want the order to be timer, physics and control, but I get Timer, control, physics and there is not way to change that since the memory allocation is generating the pointers in different heaps.
I am considered to be a Moron in the Ogre community, maybe you can let them knows about this issue an either they can tell you a solution or change the set to be a vector or a list.
Julio Jerez wrote:I there a reason why this is that way, you would think this would be a very common problem for any one using more than one listener, speciallly people using multithread code.
has any one posted this over ether ogre forum?
by sinbad » Sat Mar 10, 2007 1:57 pm
It's a fair point, but not exactly super-high on the radar since a) the number of frame listeners will be small and b) they only get called twice a frame. Chance of any perceivable performance difference between set and vector: zero
The docs have always said that framelistener call ordering is undefined. It's one of the things that encourages people to think about their own event dissemination procedures rather than registering many frame listeneres.
I take the point, but I don't plan to change it just at the moment because I don't think it's that important. Submit a patch and I might do it for Shoggoth
bool Root::renderOneFrame(void)
{
if(!_fireFrameStarted())
return false;
if (!_updateAllRenderTargets())
return false;
return _fireFrameEnded();
}
bool Root::_fireFrameRenderingQueued(FrameEvent& evt)
{
// Increment next frame number
++mNextFrame;
// Remove all marked listeners
std::set<FrameListener*>::iterator i;
for (i = mRemovedFrameListeners.begin();
i != mRemovedFrameListeners.end(); i++)
{
mFrameListeners.erase(*i);
}
mRemovedFrameListeners.clear();
// Tell all listeners
for (i= mFrameListeners.begin(); i != mFrameListeners.end(); ++i)
{
if (!(*i)->frameRenderingQueued(evt))
return false;
}
return true;
}
class StateManager : public Ogre::Singleton<StateManager>
{
public:
StateManager();
~StateManager();
bool registerState(GameState* state);
const std::map<GameState::Id, GameState*>* getRegisteredStates();
GameState* getActiveState();
GameState::Id getActiveStateId();
bool isAcceptable(GameState::Id id);
bool isAcceptableInstantly(GameState::Id id);
bool requestState(GameState::Id id, bool unloadPrevious = true);
bool forceState(GameState::Id id);
void exitAllStates();
void destroy();
static StateManager& getSingleton(void);
static StateManager* getSingletonPtr(void);
private:
GameState* activeState;
GameState::Id activeStateId;
std::map<GameState::Id, GameState*> states;
};
class GameState : public OIS::KeyListener, public OIS::MouseListener, public Ogre::WindowEventListener
{
public:
enum Id { NONE, LOADING, INIT, MAIN_GUI, SANDBOX, TERMINATE };
GameState() { paused = false; valid = false; };
virtual ~GameState() {};
virtual GameState::Id getId() = 0;
virtual Ogre::String getName() = 0;
virtual void enter() { valid = true; };
virtual void exit() { valid = false; };
virtual void update(unsigned long frameTime) {};
virtual void pause() { paused = true; };
virtual void resume() { paused = false; };
virtual bool isValid() { return valid; };
virtual bool isPaused() { return paused; };
virtual bool isAcceptable(GameState::Id state) { return true; };
virtual bool isAcceptableInstantly(GameState::Id state) { return true; };
virtual bool changeState(GameState::Id newState, GameState* state) { return false; };
//virtual bool requestSubState(GameState* state) {return false; };
//virtual bool deactivateSubState(GameState* state) { return false; };
//virtual bool deactivateSubState(Ogre::String name) { return false; };
virtual bool keyPressed(const OIS::KeyEvent &e) { return true; };
virtual bool keyReleased(const OIS::KeyEvent &e) { return true; };
virtual bool mouseMoved(const OIS::MouseEvent &e) { return true; };
virtual bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; };
virtual bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; };
virtual void windowMoved(Ogre::RenderWindow* rw) {};
virtual void windowResized(Ogre::RenderWindow* rw) {};
virtual void windowClosed(Ogre::RenderWindow* rw) {};
virtual void windowFocusChange(Ogre::RenderWindow* rw) {};
protected:
bool valid;
bool paused;
};
kallaspriit wrote:You do not have to use a single frame listener and in my own application, I don't. Have you read Application.cpp in my MinimalOgreNewt project? That shows the minimum that needs to be done to get a simple application running and anyone can extend that with any design and logic they see fit. In my application, instead of framelisteners I have game states that events are passed to
Users browsing this forum: No registered users and 3 guests