application running in background after it was closed

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
danieLs0xFF
Posts: 14
Joined: Wed Aug 16, 2006 6:58 pm

application running in background after it was closed

Post by danieLs0xFF »

hi
i have a little problem :P
i started coding my app using the following model http://irrlicht.sourceforge.net/phpBB2/ ... 795#152795
I handle pressing Escape key event, and when this happens i do a pointer_to_irrDevice->closeDevice(); from the current state ( pStateManager->pApplication->irrDevice->closeDevice(); )

the problem is that sometimes the window in which irrlicht runs closes but the app still runs in the background
it's strage that sometimes it closes fine and sometimes it runs in the background and i have no ideea what's causing that

the documentation says that closeDevice will make device->run() return false and this means that the while loop should be over and my app close.
any ideas?


here is where while loop is maybe it helps

Code: Select all

void CApplication::Run()
{
	LoadConfig();

	irrDevice = createDevice(cfgVideoDriver, dimension2d<s32>(1024, 768), 32, cfgFullScreen);
	if (!irrDevice)
	{
		irrDevice = createDevice(EDT_BURNINGSVIDEO, dimension2d<s32>(1024, 768), 32, cfgFullScreen);
	}

	irrDevice->setWindowCaption(L"Appname v1.0 - author");

	videoDriver	= irrDevice->getVideoDriver();
	irrFS		= irrDevice->getFileSystem();
	guiEnv		= irrDevice->getGUIEnvironment();
	inOutFader	= guiEnv->addInOutFader();
	
	inOutFader->setColor(SColor(0, 0, 0, 0));

	CStateManager *stateManager = new CStateManager(this);
	
	stateManager->Init();

	while (irrDevice->run() && videoDriver)
	{
		stateManager->Run();
		//irrDevice->yield();
	}

	irrDevice->drop();

	delete stateManager;
}

[quote][/quote]
Last edited by danieLs0xFF on Fri Apr 11, 2008 8:04 pm, edited 1 time in total.
danieLs0xFF
Posts: 14
Joined: Wed Aug 16, 2006 6:58 pm

Post by danieLs0xFF »

anybody :? :(
help
this is an annoying bug i'm haveing
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

You may need to put return 0; at the end of your main() function, or PostQuitMessage(0), I've had this problem a few times.

Code: Select all

void main()
{
    app app1;
    app1.run();
    return 0;
} 
This way your whole program will know to close, not just the device.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Or you can try:

Code: Select all

irrDevice->closeDevice();
irrDevice->drop();
TheQuestion = 2B || !2B
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Post by Lonesome Ducky »

From what he said, I'm guessing he does irrDevice->closeDevice() when it's checking for input and the esc key was hit.
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Lonesome Ducky wrote:From what he said, I'm guessing he does irrDevice->closeDevice() when it's checking for input and the esc key was hit.
Well exactly, that's all we can do is guess. We don't have all of his code at all, so I can't really assess the situation.
TheQuestion = 2B || !2B
CuteAlien
Admin
Posts: 9933
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: application running in background after it was closed

Post by CuteAlien »

danieLs0xFF wrote: the documentation says that closeDevice will make device->run() return false and this means that the while loop should be over and my app close.
any ideas?
I also can't tell without more code. But there is one thing upon which I once stumpled and that is that device->run() will only return false exactly one time. So if you have another call for that somewhere it will get the return false, your irrlicht device (and window) will be closed - but your device->run() in your mainloop will still run. Because next time the device->run() will return true again.

But why don't you just use your debugger and check where it hangs? In VS it would be "debug"-"break all" and you will get to the currently executed lines. Probably similar functionality exists in gdb.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

danieLs0xFF wrote:anybody :? :(
help
this is an annoying bug i'm haveing
If you actually want a meaningful answer, then you can post your entire source, the platform you are running on, and the toolchain you are using to compile it. Alternatively, you could...

Image
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
danieLs0xFF
Posts: 14
Joined: Wed Aug 16, 2006 6:58 pm

Post by danieLs0xFF »

rogerborg wrote:
danieLs0xFF wrote:anybody :? :(
help
this is an annoying bug i'm haveing
If you actually want a meaningful answer, then you can post your entire source, the platform you are running on, and the toolchain you are using to compile it. Alternatively, you could...

Image

WTF?? your answer wasn't helpful and not even polite
so i may as well say

Image

yourself
danieLs0xFF
Posts: 14
Joined: Wed Aug 16, 2006 6:58 pm

Re: application running in background after it was closed

Post by danieLs0xFF »

CuteAlien wrote:But why don't you just use your debugger and check where it hangs? In VS it would be "debug"-"break all" and you will get to the currently executed lines. Probably similar functionality exists in gdb.
this doesn't happen all the time, it just happens at random
i just run my app and close it, and i notice that my pc is running slowly than usual and when i look in task manager there it is, the process still running in the background and i need to kill it for it to fully close

i try with the debugger(i use visual studio 2003) but it seems that when running inside debugger i didn't manage to replicate the problem

when running from outside both debug & release version make this problem, but as i said not all the time this is what it bugs me and i can't figure out why
it does happen at random
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Since the window is closed (and we assume that you drop the device without creating a new one immediately after that, although we don't know your code), it's likely that it's a gfx hw driver issue, and not directly related to Irrlicht. You should also test with the provided precompiled examples, since those are known to work on many machines.
Oh, btw, programming is a mostly frustrating job, you should work on your frustration tolerance :wink:
danieLs0xFF
Posts: 14
Joined: Wed Aug 16, 2006 6:58 pm

Post by danieLs0xFF »

i didn't post all the source code from the beginning as i was afraid it is too much of a trouble for you (those who want to help) to look through all of it

i posted what i thought it was relevant

anyways here's the code, so if anybody has any idea what i'm doing wrong please help

thank you

I'm compileing on windows xp using visual studio 2003, and irrlicht 1.4

main.cpp

Code: Select all

#include <irrlicht.h>
#ifdef _IRR_WINDOWS_
#include <windows.h>
#endif

#include "CApplication.h"

#ifdef _WIN32
#pragma comment(lib, "Irrlicht.lib")
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char* argv[])
#endif
{
	CApplication app;
	app.Run();

	return 0;
}


CApplication.h

Code: Select all

#ifndef __C_APPLICATION_H_INCLUDED__
#define __C_APPLICATION_H_INCLUDED__

#include <irrlicht.h>
#include <irrXML.h>
#include "CStateManager.h"

using namespace irr;
using namespace io;
using namespace video;
using namespace gui;
using namespace core;

class CApplication
{
public:
	CApplication();
	~CApplication();
	void Run();

	IrrlichtDevice	*irrDevice;
	IVideoDriver	*videoDriver;
	IGUIEnvironment *guiEnv;
	IGUIInOutFader	*inOutFader;
	IFileSystem		*irrFS;

private:
	/* BEGIN CONFIG */
	bool			cfgFullScreen;
	E_DRIVER_TYPE	cfgVideoDriver;

	void LoadConfig();
	/* END CONFIG */

};

#endif

CApplication.cpp

Code: Select all

#include "CApplication.h"

CApplication::CApplication()
: irrDevice(0), videoDriver(0), guiEnv(0), irrFS(0),
  cfgFullScreen(false), cfgVideoDriver(EDT_BURNINGSVIDEO)
{	
}

CApplication::~CApplication()
{
}

void CApplication::Run()
{
	LoadConfig();

	irrDevice = createDevice(cfgVideoDriver, dimension2d<s32>(1024, 768), 32, cfgFullScreen);
	if (!irrDevice)
	{
		irrDevice = createDevice(EDT_BURNINGSVIDEO, dimension2d<s32>(1024, 768), 32, cfgFullScreen);
	}

	irrDevice->setWindowCaption(L"Imnuri Crestine v1.0 - Daniel Anechitoaie");

	videoDriver	= irrDevice->getVideoDriver();
	irrFS		= irrDevice->getFileSystem();
	guiEnv		= irrDevice->getGUIEnvironment();
	inOutFader	= guiEnv->addInOutFader();
	
	inOutFader->setColor(SColor(0, 0, 0, 0));

	CStateManager *stateManager = new CStateManager(this);
	
	stateManager->Init();

	while (irrDevice->run() && videoDriver)
	{
		stateManager->Run();
		//irrDevice->yield();
	}

	irrDevice->drop();

	delete stateManager;
}

void CApplication::LoadConfig()
{
	IrrXMLReader* xml = createIrrXMLReader("ImnuriCrestine.conf");	

	while(xml && xml->read())
	{
		switch(xml->getNodeType())
		{
		case EXN_ELEMENT:
			{
				if (!strcmp("FullScreen", xml->getNodeName()))
				{
					if (!strcmp("true", xml->getAttributeValue("value")))
					{
						cfgFullScreen = true;
					}
				}
				else 
				if (!strcmp("VideoDriver", xml->getNodeName()))
				{
					if (!strcmp("DirectX8", xml->getAttributeValue("value")))
					{
						cfgVideoDriver = EDT_DIRECT3D8;
					}
					else
					if (!strcmp("DirectX9", xml->getAttributeValue("value")))
					{
						cfgVideoDriver = EDT_DIRECT3D9;
					}
					else
					if (!strcmp("OpenGL", xml->getAttributeValue("value")))
					{
						cfgVideoDriver = EDT_OPENGL;
					}
				}
			}
			break;
		}
	}

	delete xml;
}

CState.h

Code: Select all

#ifndef __C_STATE_H_INCLUDED__
#define __C_STATE_H_INCLUDED__

class CState
{
public:
	virtual void Init() = 0;
	virtual void Enter() = 0;
	virtual void Run() = 0;
	virtual void Exit() = 0;
};

#endif

CStateManager.h

Code: Select all

#ifndef __C_STATE_MANAGER_H_INCLUDED__
#define __C_STATE_MANAGER_H_INCLUDED__

#include <irrlicht.h>
#include "CState.h"
#include "CStateSplash.h"
#include "CStateMenu.h"

using namespace irr;
using namespace video;

class CApplication;

class CStateManager
{
public:
	CStateManager(CApplication *pApplication);
	~CStateManager();
	void Init();
	void Run();
	void ChangeState(CState *pNewState);

	CState			*pCurrentState;
	CState			*pStateSplash;
	CState			*pStateMenu;
	CState			*pStateHymn;
	CState			*pStateAbout;

	CApplication	*pApplication;
};

#endif

CStateManager.cpp

Code: Select all

#include "CStateManager.h"
#include "CApplication.h"

CStateManager::CStateManager(CApplication *pApplication)
{
	this->pApplication = pApplication;

	pStateSplash	= new CStateSplash(this);
	pStateMenu		= new CStateMenu(this);
	//pStateHymn		= new CStateHymn(this);
	//pStateAbout		= new CStateAbout(this);
}

CStateManager::~CStateManager()
{
	delete pStateSplash;
	delete pStateMenu;
	//delete pStateHymn;
	//delete pStateAbout;
}

void CStateManager::Init()
{
	pStateSplash->Init();
	pStateMenu->Init();
	//pStateHymn->Init();
	//pStateAbout->Init();

	pCurrentState = pStateSplash;
	pCurrentState->Enter();
}

void CStateManager::Run()
{
	pCurrentState->Run();
}

void CStateManager::ChangeState(CState *pNewState)
{
	pCurrentState->Exit();
	pCurrentState = pNewState;
	pCurrentState->Enter();
}

CStateMenu.h

Code: Select all

#ifndef __C_STATE_MENU_H_INCLUDED__
#define __C_STATE_MENU_H_INCLUDED__

#include <irrlicht.h>
#include "CState.h"

using namespace irr;
using namespace video;
using namespace core;
using namespace gui;
using namespace io;

class CStateManager;

class CStateMenu : public CState, public IEventReceiver
{
public:
	CStateMenu(CStateManager *pStateManager);
	~CStateMenu();
	virtual void Init();
	virtual void Enter();
	virtual void Run();
	virtual void Exit();
	virtual bool OnEvent(const SEvent& event);

private:
	ITexture			*textureMenu;

	IVideoDriver		*videoDriver;
	IGUIEnvironment		*guiEnv;
	IGUIInOutFader		*inOutFader;
	IFileSystem			*irrFS;

	rect<s32>			menuBackground;
	//array< rect<s32> >	splashLoadingBar;

	u32					timeLastFrame;
	u32					timeTotalFrames;
	bool				faderSet;

	CStateManager		*pStateManager;
};

#endif

CStateMenu.cpp

Code: Select all

#include "CStateMenu.h"
#include "CStateManager.h"
#include "CApplication.h"
#include "TextureMenu.h"

CStateMenu::CStateMenu(CStateManager *pStateManager) 
: textureMenu(0), irrFS(0), videoDriver(0), guiEnv(0), inOutFader(0),
  timeLastFrame(0), timeTotalFrames(0),
  faderSet(false)
{
	this->pStateManager = pStateManager;
	this->videoDriver	= pStateManager->pApplication->videoDriver;
	this->irrFS			= pStateManager->pApplication->irrFS;
	this->guiEnv		= pStateManager->pApplication->guiEnv;
	this->inOutFader	= pStateManager->pApplication->inOutFader;
}

CStateMenu::~CStateMenu()
{
}

void CStateMenu::Init()
{
	menuBackground = rect<s32>(0,  256, 1024, 1024);

	IReadFile* file;
	const c8* fileNameTextureMenu = "#TextureMenu";
	file = irrFS->createMemoryReadFile(textureMenuBuff, textureMenuBuffSize, fileNameTextureMenu, false);
	textureMenu = videoDriver->getTexture(file);
}

void CStateMenu::Enter() 
{
	pStateManager->pApplication->irrDevice->setEventReceiver(this);
	inOutFader->fadeIn(400);
}

void CStateMenu::Run() 
{
	//u32 cTime = pStateManager->pApplication->irrDevice->getTimer()->getTime();
	//if (cTime >= (timeLastFrame + 35))
	//{
	//	splashLoadingBarFrame++;
	//	if (splashLoadingBarFrame > 9)
	//	{
	//		splashLoadingBarFrame = 0;
	//	}
	//	timeTotalFrames += (cTime - timeLastFrame); 
	//	timeLastFrame = cTime;
	//}

	//if (timeTotalFrames >= 6400) 
	//{
	//	if(!faderSet)
	//	{
	//		inOutFader->fadeOut(400);
	//		faderSet = true;
	//	}
	//	//if (timeTotalFrames >= 7000) 
	//	//	splashOver = true;
	//}

	videoDriver->beginScene(true, true, video::SColor(0, 0, 0, 0));
	videoDriver->draw2DImage(textureMenu, position2d<s32>(0, 0),  menuBackground);
	guiEnv->drawAll();
	videoDriver->endScene();
}

void CStateMenu::Exit() 
{
}

bool CStateMenu::OnEvent(const SEvent& event)
{
	if (!pStateManager->pApplication->irrDevice)
		return false;

	if (event.EventType == EET_KEY_INPUT_EVENT &&
		event.KeyInput.Key == KEY_ESCAPE &&
		event.KeyInput.PressedDown == false)
	{
		pStateManager->pApplication->irrDevice->closeDevice();
	}

	return false;
}

CStateSplash.h

Code: Select all

#ifndef __C_STATE_SPLASH_H_INCLUDED__
#define __C_STATE_SPLASH_H_INCLUDED__

#include <irrlicht.h>
#include "CState.h"

using namespace irr;
using namespace video;
using namespace core;
using namespace gui;
using namespace io;

class CStateManager;

class CStateSplash : public CState, public IEventReceiver
{
public:
	CStateSplash(CStateManager *pStateManager);
	~CStateSplash();
	virtual void Init();
	virtual void Enter();
	virtual void Run();
	virtual void Exit();
	virtual bool OnEvent(const SEvent& event);

private:
	ITexture			*textureSplash;

	IVideoDriver		*videoDriver;
	IGUIEnvironment		*guiEnv;
	IGUIInOutFader		*inOutFader;
	IFileSystem			*irrFS;

	rect<s32>			splashBackground;
	array< rect<s32> >	splashLoadingBar;

	u32					timeLastFrame;
	u32					timeTotalFrames;
	u32					splashLoadingBarFrame;
	bool				faderSet;

	CStateManager		*pStateManager;
};

#endif

CStateSplash.cpp

Code: Select all

#include "CStateSplash.h"
#include "CStateManager.h"
#include "CApplication.h"
#include "TextureSplash.h"

CStateSplash::CStateSplash(CStateManager *pStateManager) 
: textureSplash(0), irrFS(0), videoDriver(0), guiEnv(0), inOutFader(0),
  timeLastFrame(0), timeTotalFrames(0), splashLoadingBarFrame(0),
  faderSet(false)
{
	this->pStateManager = pStateManager;
	this->videoDriver	= pStateManager->pApplication->videoDriver;
	this->irrFS			= pStateManager->pApplication->irrFS;
	this->guiEnv		= pStateManager->pApplication->guiEnv;
	this->inOutFader	= pStateManager->pApplication->inOutFader;
}

CStateSplash::~CStateSplash()
{
}

void CStateSplash::Init()
{
	splashBackground = rect<s32>(0,  256, 1024, 1024);

	splashLoadingBar.push_back(rect<s32>(0,   0, 208,  13));
	splashLoadingBar.push_back(rect<s32>(0,  13, 208,  26));
	splashLoadingBar.push_back(rect<s32>(0,  26, 208,  39));
	splashLoadingBar.push_back(rect<s32>(0,  39, 208,  52));
	splashLoadingBar.push_back(rect<s32>(0,  52, 208,  65));
	splashLoadingBar.push_back(rect<s32>(0,  65, 208,  78));
	splashLoadingBar.push_back(rect<s32>(0,  78, 208,  91));
	splashLoadingBar.push_back(rect<s32>(0,  91, 208, 104));
	splashLoadingBar.push_back(rect<s32>(0, 104, 208, 117));
	splashLoadingBar.push_back(rect<s32>(0, 117, 208, 130));

	IReadFile* file;
	const c8* fileNameTextureSplash = "#TextureSplash";
	file = irrFS->createMemoryReadFile(textureSplashBuff, textureSplashBuffSize, fileNameTextureSplash, false);
	textureSplash = videoDriver->getTexture(file);
}

void CStateSplash::Enter() 
{
	pStateManager->pApplication->irrDevice->setEventReceiver(this);
}

void CStateSplash::Run() 
{
	u32 cTime = pStateManager->pApplication->irrDevice->getTimer()->getTime();
	if (cTime >= (timeLastFrame + 35))
	{
		splashLoadingBarFrame++;
		if (splashLoadingBarFrame > 9)
		{
			splashLoadingBarFrame = 0;
		}
		timeTotalFrames += (cTime - timeLastFrame); 
		timeLastFrame = cTime;
	}

	if (timeTotalFrames >= 6400) 
	{
		if(!faderSet)
		{
			inOutFader->fadeOut(400);
			faderSet = true;
		}
		if (timeTotalFrames >= 7000) 
			pStateManager->ChangeState(pStateManager->pStateMenu);
	}

	videoDriver->beginScene(true, true, video::SColor(0, 0, 0, 0));
	videoDriver->draw2DImage(textureSplash, position2d<s32>(0, 0),  splashBackground);
	videoDriver->draw2DImage(textureSplash, position2d<s32>(411, 644),  splashLoadingBar[splashLoadingBarFrame]);
	guiEnv->drawAll();
	videoDriver->endScene();
}

void CStateSplash::Exit() 
{
}

bool CStateSplash::OnEvent(const SEvent& event)
{
	if (!pStateManager->pApplication->irrDevice)
		return false;

	if (event.EventType == EET_KEY_INPUT_EVENT &&
		event.KeyInput.Key == KEY_ESCAPE &&
		event.KeyInput.PressedDown == false)
	{
		pStateManager->pApplication->irrDevice->closeDevice();
	}

	return false;
}

TextureMenu.h

Code: Select all

unsigned int 	textureMenuBuffSize	= 692809;
unsigned char 	textureMenuBuff[] 	= {
0x89,0x50,0x4e,0x47,0x0d,0x0a
.......
Not relevant, file generated from a png using bin2h
.......
};
TextureSplash.h

Code: Select all

same as TextureMenu, different data
CuteAlien
Admin
Posts: 9933
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

danieLs0xFF wrote:i didn't post all the source code from the beginning as i was afraid it is too much of a trouble for you (those who want to help) to look through all of it
Hm, well, yeah. You should try to reduce it - that's hard to debug.

I'm not sure, but maybe the esc-key event gets handled, you close the device in it - and then you continue using the device within your states. There it crashes. I would have to debug that myself to be sure, as it's not immediately obvious in which order that stuff will be executed. Adding debug-messages (for example in OnEvent and in the state-enter, state-run, state-exit functions) might help to find that out.

Also as general hint - if you start to see nearly identical code in several places then it's nearly always a hint that your architecture can be simplified. In your case it's for example always beginScene <stuff> drawAll endScene. And you will have that all the time as there will be no place in your game where you don't need drawing. So you can put that part in Run().
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Yeah, I have to agree with CuteAlien. You are closing the device with one of your event receivers, and I'm not sure, but I still think all event receivers get call with the same event, so that your other event receiver is receiving KEY_ESC, and also trying to close the device, etc. Maybe something like that.
TheQuestion = 2B || !2B
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Still waiting on a fully compilable and runnable project before I invest any time in tracking down this edge case.
Last edited by rogerborg on Sat Apr 12, 2008 10:34 am, edited 1 time in total.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply