After looking through your code, I found the problem. Something to look at when you get any breaks in your application is the "Autos" tab or the Locals tab. Here you'll notice something about the this
pointer: it's null!
That means the instance that AddSprite
is being called on doesn't exist. This is your SpriteManager
, which I see is a singleton. In your main, you don't create an instance of it.
I had to do a couple things to get it working. I included "LudoRenderer/SpriteManager.h"
in Main.cpp
, and added the CreateInstance
call:
SpriteManager::CreateInstance();
The only problem with this was that you had declared your constructor/destructor private, like other singletons, but never defined them, so I did that as well:
SpriteManager::SpriteManager(){}
SpriteManager::~SpriteManager(){}
After those changes, it "worked". That's in quotes because your problem is solved, but there is another error later in the code m_GameManager->SetWagon(m_Wagon);
.
Here, m_GameManager
is not initialized. I uncommented m_GameManager = GameManager::GetInstance();
on line 43 in LudoEngine.cpp
, which put us in the same problem as before, no CreateInstance
is ever called. I added the necessary header in main, called the create method. This fixed the problem, and your engine ran (cool demo, too!)
There was a crash on exit, in ErrorLogger::LogError
, because ErrorLogger
was null. It was being called in LudoMemory
's destructor, but I'll leave this one for you. :)
Now, two tips I tihnk that would help. The first is about the issue we're solving. Normally, singletons will create themselves if they aren't already. I'd change your singleton GetInstance
to something like this:
static T *GetInstance ( )
{
if (!m_Singleton) // or == NULL or whatever you prefer
{
CreateInstance();
}
return m_Singleton; // not sure what the cast was for
}
This will force creation of the singleton if it hasn't been already. Now, if you'd like users to call CreateInstance
before trying to GetInstance
, you could add some sort of warning:
static T *GetInstance ( )
{
if (!m_Singleton) // or == NULL or whatever you prefer
{
CreateInstance();
std::cerr << "Warning, late creation of singleton!" << std::endl;
// or perhaps:
ErrorLogger::GetInstance()->
LogError(L"Warning, late creation of singleton!");
}
return m_Singleton;
}
Since that leaves out the important information "which singleton?", you could always try to add typeinfo to it:
#include <typeinfo>
// ...
std::cerr << "Warning, late creation of singleton: "
<< typeid(T).name() << std::endl;
To try to get some type names in there.
And lastly, it's okay to delete 0
, your checked delete macro is not needed.
To clarify, you have LUDO_SAFE_DELETE
, which checks if it's not null before it calls delete. In C++, deleting null has no effect, so your check isn't needed. All instances of your safe delete could be replaced with just your LUDO_DELETE.