Houston, we've got a problem.
So I'm writing a plugin for some random program and using SFML window to render some debug stuff. The plugin has a structure like this:
struct MySystem
{
MySystem()
{
window = new sf::RenderWindow(...);
}
~MySystem()
{
delete window;
}
void Update()
{
sf::Event event;
while(window->pollEvent(event);
}
sf::RenderWindow *window;
};
MySystem *mySystem;
void DLL_API PluginInit()
{
mySystem = new MySystem();
}
void DLL_API PluginUpdate()
{
mySystem->Update();
}
void DLL_API PluginRelease()
{
delete mySystem;
}
So far, so good. Now imagine there's a button "stop plugin" in the program I'm making the plugin for. The button apparently has an event function like this:
void ProgramImMakingPluginFor::OnPluginStopButtonPressed()
{
PluginRelease();
}
What happens is this: the program crashes when I hit the "StopPlugin" button and crashed stack trace points to my line with while(window->pollEvent(event)); A couple of restless nights pointed out that what actually happens is this:
During my Update() when I call window->pollEvent(event) instead of processing messages addressed to my window it processes messages to non-sfml windows as well. sf::Window::pollEvent() calls sf::Window::popEvent() that calls WindowImplWin32::processEvents() that looks like this:
void WindowImplWin32::processEvents()
{
// We process the window events only if we own it
if (!m_callback)
{
MSG message;
while (PeekMessageW(&message, NULL/*SIC*/, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessageW(&message);
}
}
}
And during MySystem::Update() pollEvent() calls ProgramImMakingPluginFor::OnPluginStopButtonPressed() that calls PluginRelease() and destroys mySystem. Apparently bad things happen if inside mySystem->Update() you destroy instance of mySystem.
Two questions:
1) Shouldn't it have been
while (PeekMessageW(&message, m_handle, 0, 0, PM_REMOVE))
instead of
while (PeekMessageW(&message, NULL, 0, 0, PM_REMOVE))
?
2) Which options do I have for a workaround?