anyone
05-18-2007, 11:22 AM
I encountered problems using ClanLib's facility to initialize a CL_Surface instance by an id and a pointer to my resource manager.
The resources file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<section name="Game">
<surface name="Car" file="car.tga"/>
</section>
</resources>
And my program like that:
#include <iostream>
#include <string>
using namespace std;
#include <unistd.h>
#include <ClanLib/core.h>
#include <ClanLib/application.h>
#include <ClanLib/display.h>
#include <ClanLib/sdl.h>
class c01 : public CL_ClanApplication
{
private:
CL_SetupCore* mCore;
CL_ResourceManager* mResources;
CL_SetupDisplay* mDisplay;
CL_SetupSDL* mSDLEngine;
public:
c01 (void)
{
mCore = 0;
mDisplay = 0;
mSDLEngine = 0;
}
virtual int
main (int argc, char *argv[])
{
mCore = new CL_SetupCore ();
mResources = new CL_ResourceManager ("resources.xml");
mDisplay = new CL_SetupDisplay ();
mSDLEngine = new CL_SetupSDL ();
const string id = "Game/Car";
CL_Resource r = mResources->get_resource (id);
cout << "Type of '" << id << "': '" << r.get_type () << "'\n";
CL_DisplayWindow window ("buggy", 800, 600);
CL_GraphicContext *gc = window.get_gc ();
gc->clear (CL_Color::black);
CL_Surface *car;
try {
// This call always results in a thrown exception
car = new CL_Surface (id, mResources);
}
catch (CL_Error e) {
std::cout << e.message << std::endl;
return 1;
}
car->draw (100, 100, gc);
window.flip ();
sleep (5);
return 0;
}
~c01 (void)
{
if (mSDLEngine) delete mSDLEngine;
if (mResources) delete mResources;
if (mDisplay) delete mDisplay;
if (mCore) delete mCore;
}
};
int
main (int argc, char *argv[])
{
c01 app;
return app.main (argc, argv);
}
When compiling and running the program, the output will be:
Type of 'Game/Car': 'surface'
Resource 'Game/Car' is not of type 'surface'
That sounds paradox of course. I examined ClanLib's sources and found CL_Surface's constructors in Display/surface.cpp. The following code belongs to the constructor which I' using in the red marked line:
CL_Surface::CL_Surface(
const std::string &resource_id,
CL_ResourceManager *manager)
: impl(0)
{
resource = manager->get_resource(resource_id);
if (resource.get_type() != "surface" )
throw CL_Error("Resource '" + resource_id + "' is not of type 'surface'");
resource.load();
CL_ResourceData_Surface *data =
(CL_ResourceData_Surface *) resource.get_data("surface");
if (!data)
throw CL_Error("Resource '" + resource_id + "' is not of type 'surface'");
impl = data->get_surface().impl;
impl->add_ref();
}
As you see there are two lines that trigger an exception with exactly the same message (I think that can be done better, but that's beyond the scope of this thread). My output is, in fact, the result of the latter exception throwing, meaning that data == 0!
I really don't know whether the definitions in my resource file are insufficient, but calling car = new CL_Surface ("car.tga") works correctly.
I'm using a self-compiled version of ClanLib 0.8. I hope you can help me.
The resources file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<section name="Game">
<surface name="Car" file="car.tga"/>
</section>
</resources>
And my program like that:
#include <iostream>
#include <string>
using namespace std;
#include <unistd.h>
#include <ClanLib/core.h>
#include <ClanLib/application.h>
#include <ClanLib/display.h>
#include <ClanLib/sdl.h>
class c01 : public CL_ClanApplication
{
private:
CL_SetupCore* mCore;
CL_ResourceManager* mResources;
CL_SetupDisplay* mDisplay;
CL_SetupSDL* mSDLEngine;
public:
c01 (void)
{
mCore = 0;
mDisplay = 0;
mSDLEngine = 0;
}
virtual int
main (int argc, char *argv[])
{
mCore = new CL_SetupCore ();
mResources = new CL_ResourceManager ("resources.xml");
mDisplay = new CL_SetupDisplay ();
mSDLEngine = new CL_SetupSDL ();
const string id = "Game/Car";
CL_Resource r = mResources->get_resource (id);
cout << "Type of '" << id << "': '" << r.get_type () << "'\n";
CL_DisplayWindow window ("buggy", 800, 600);
CL_GraphicContext *gc = window.get_gc ();
gc->clear (CL_Color::black);
CL_Surface *car;
try {
// This call always results in a thrown exception
car = new CL_Surface (id, mResources);
}
catch (CL_Error e) {
std::cout << e.message << std::endl;
return 1;
}
car->draw (100, 100, gc);
window.flip ();
sleep (5);
return 0;
}
~c01 (void)
{
if (mSDLEngine) delete mSDLEngine;
if (mResources) delete mResources;
if (mDisplay) delete mDisplay;
if (mCore) delete mCore;
}
};
int
main (int argc, char *argv[])
{
c01 app;
return app.main (argc, argv);
}
When compiling and running the program, the output will be:
Type of 'Game/Car': 'surface'
Resource 'Game/Car' is not of type 'surface'
That sounds paradox of course. I examined ClanLib's sources and found CL_Surface's constructors in Display/surface.cpp. The following code belongs to the constructor which I' using in the red marked line:
CL_Surface::CL_Surface(
const std::string &resource_id,
CL_ResourceManager *manager)
: impl(0)
{
resource = manager->get_resource(resource_id);
if (resource.get_type() != "surface" )
throw CL_Error("Resource '" + resource_id + "' is not of type 'surface'");
resource.load();
CL_ResourceData_Surface *data =
(CL_ResourceData_Surface *) resource.get_data("surface");
if (!data)
throw CL_Error("Resource '" + resource_id + "' is not of type 'surface'");
impl = data->get_surface().impl;
impl->add_ref();
}
As you see there are two lines that trigger an exception with exactly the same message (I think that can be done better, but that's beyond the scope of this thread). My output is, in fact, the result of the latter exception throwing, meaning that data == 0!
I really don't know whether the definitions in my resource file are insufficient, but calling car = new CL_Surface ("car.tga") works correctly.
I'm using a self-compiled version of ClanLib 0.8. I hope you can help me.