wait
Code: Select all
u32 now = device->getTimer()->getTime();
static u32 last = now;
if(now>(last+2000)){}
Umm.. not sure if I understand, but what I meant was that you'll have to do it in a loop, such as the main application loop.
Because you don't want to sleep or stop the app, so you need to check over and over again until it is the correct time.
But it doesn't really make sense like that because the "last" time will be reset every loop.
It sounds like you need some sort of class to update your nodes.
Like a node manager. Give it an update function which performs whatever you want (after 2 seconds).
Any nodes that you want updated after 2 seconds, just add them to the node manager list (array) and also add the time when you added them.
In the update function, check each node in the list and check if it has been waiting at least 2 seconds, then do what you want with it and remove it from the node manager class once it's been updated.
So then you just need to call the update function in the main loop.
Get it?
Because you don't want to sleep or stop the app, so you need to check over and over again until it is the correct time.
Code: Select all
while(device->run())
{
//! Do something....
u32 last = device->getTimer()->getTime();
if( device->getTimer()->getTime() > (last+2000) )
{
}
}
It sounds like you need some sort of class to update your nodes.
Like a node manager. Give it an update function which performs whatever you want (after 2 seconds).
Any nodes that you want updated after 2 seconds, just add them to the node manager list (array) and also add the time when you added them.
In the update function, check each node in the list and check if it has been waiting at least 2 seconds, then do what you want with it and remove it from the node manager class once it's been updated.
So then you just need to call the update function in the main loop.
Get it?
I can hear birds chirping
I live in the Eye of Insanity.
I live in the Eye of Insanity.
I wrote some little code for removing GUI elements after a specified time. I created a structure holding the "time to remove" and a pointer to the element to remove and add the to a list. In the main loop I iterate over this list every frame and remove elements if necessary. I am currently at work so I don't have the project here, but maybe you get the idea.
Dustbin::Games on the web: https://www.dustbin-online.de/
Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
OK, now I got the code. I use it to toggle elements, because some need to be hidden and others need to be shown.
Then you need a list of those objects:
and then, at some point of code that is reached every frame, you put
One drawback: only one element is shown/hidden per frame, but in my project I haven't yet seen any problems.
Code: Select all
class GUIElementToToggle {
public:
GUIElementToToggle(IGUIElement *pElement, u32 iTime, bool bVisible) {
m_pElement=pElement;
m_iRemoveTime=iTime;
m_bVisible=bVisible;
printf("element \"%s\" marked for %s at %i\n",stringc(pElement->getToolTipText()).c_str(),bVisible?"showing":"hiding",iTime);
}
IGUIElement *m_pElement;
u32 m_iRemoveTime;
bool m_bVisible;
};
Code: Select all
list<GUIElementToToggle *> m_lElementsToToggle;
Code: Select all
list<GUIElementToToggle *>::Iterator it;
for (it=m_lElementsToToggle.begin(); it!=m_lElementsToToggle.end(); it++) {
if (m_pTimer->getTime()>(*it)->m_iRemoveTime) {
printf("%s element \"%s\" (%i)\n",(*it)->m_bVisible?"Showing":"Hiding",stringc((*it)->m_pElement->getToolTipText()).c_str(),m_pTimer->getTime());
IGUIElement *pElement=(*it)->m_pElement;
pElement->setVisible((*it)->m_bVisible);
GUIElementToToggle *pToRemove=*it;
m_lElementsToToggle.erase(it);
delete pToRemove;
break;
}
}
Dustbin::Games on the web: https://www.dustbin-online.de/
Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
Dustbin::Games on facebook: https://www.facebook.com/dustbingames/
Dustbin::Games on twitter: https://twitter.com/dustbingames
That's because you have a call to "break" in the loop.Brainsaw wrote:One drawback: only one element is shown/hidden per frame, but in my project I haven't yet seen any problems.
Don't break, do the whole list.
Yea?
Code: Select all
list<GUIElementToToggle *>::Iterator it;
u32 curTime = m_pTimer->getTime();
for (it=m_lElementsToToggle.begin(); it!=m_lElementsToToggle.end(); it++)
{
if (curTime > (*it)->m_iRemoveTime)
{
printf("%s element "%s" (%i)\n",(*it)->m_bVisible?"Showing":"Hiding",stringc((*it)->m_pElement->getToolTipText()).c_str(),m_pTimer->getTime());
IGUIElement *pElement=(*it)->m_pElement;
pElement->setVisible((*it)->m_bVisible);
GUIElementToToggle *pToRemove=*it;
m_lElementsToToggle.erase(it);
delete pToRemove;
}
}
I can hear birds chirping
I live in the Eye of Insanity.
I live in the Eye of Insanity.
Hi,
You can use code similar to this:
Cheers,
You can use code similar to this:
Code: Select all
bool UpdateVisibleTimer = 1;
float VisibleTime = device->getTimer()->getTime();
while(device->run())
{
if(UpdateVisibleTimer)
{
VisibleTime = device->getTimer()->getTime(); // Get time.
UpdateVisibleTimer = 0; // Disable grab new time.
}
if(VisibleTime + 2000 < device->getTimer()->getTime())
{
// ...do something, eg:
UpdateVisibleTimer = 1; // if You want start new time counter.
Node->setVisible(false); // Hide Your node.
}
}
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Writing a bunch of code like this in the main loop is not going to scale well, and will not be reusable.
If you want to avoid these defficiencies, you will probably want to create a generic timer queue or timer wheel. All it needs to do is keep track of operations to perform, and when to perform them.
Travis
If you want to avoid these defficiencies, you will probably want to create a generic timer queue or timer wheel. All it needs to do is keep track of operations to perform, and when to perform them.
Travis
Author of this thread need change bisibility parameter of node after 2 seconds, and idea which I show is very good for this problem and it can be reusable many times, he can create many eg. enumerations states etc. I don't know where You see the problemvitek wrote:Writing a bunch of code like this in the main loop is not going to scale well, and will not be reusable.
If you want to avoid these defficiencies, you will probably want to create a generic timer queue or timer wheel. All it needs to do is keep track of operations to perform, and when to perform them.
Travis
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
One node only in this sample, but in Your game he should have some Entity Manager or similar, so he can call:
You can do in this way what You want, so as I said this code is very good for this problem
Code: Select all
for(ini i = 0; i < EntityManager->getEntitiesCount(); ++i)
{
EntityManager->getEntity(i)->getNode()->setVisible(false);
}
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
-
- Posts: 1186
- Joined: Fri Dec 29, 2006 12:04 am
This would set all entities invisible at once. You could of course something do like thisNadro wrote:Code: Select all
for(ini i = 0; i < EntityManager->getEntitiesCount(); ++i) { EntityManager->getEntity(i)->getNode()->setVisible(false); }
Code: Select all
const unsigned int entCount = EntityManager->getEntitiesCount();
for(unsigned int i = 0; i < entCount; ++i)
{
Entity* entity = EntityManager->getEntity(i);
if (entity->getStartTime() + 2000 >= now)
entity->getNode()->setVisible(false);
}
Like suggested before i'd go for something like this (pseudo code)
Code: Select all
enum E_WHAT_TODO
{
EWT_INVISIBLE = 0,
};
struct S_ACTION
{
irr::scene::ISceneNode* node;
E_WHAT_TODO todo;
irr::u32 when;
};
S_ACTION action;
action.node = someNode;
action.todo = EWT_INVISIBLE;
action.when = now + 2000;
ActionManager am;
am.addAction(action);
while(device->run())
{
<compute elapsed time>
am.update(elapsed);
driver->beginScene();
smgr->drawAll();
driver->endScene();
}
void ActionManager::update(elapsed)
{
<process all stored actions, if any>
}
Might be overkill for the original posters application, but yeah, could be doable like this.
"Whoops..."