Sophie

Sophie

distrib > Mageia > 7 > i586 > media > core-release > by-pkgid > a2116f36018873d572acbcadddb8e994 > files > 15

clanlib0.8-docs-0.8.1-22.mga7.i586.rpm


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Custom Resource Types - ClanLib Game SDK</title>
<link rel="stylesheet" type="text/css" href="../../default.css">
</head>
<body style="background-color: #a4daea; color: black; margin: 1em 3em 1em 3em;">
<div style="border-style: solid; border-width:thin; border-color: black;">
<div style="background-color: white; color: black; padding: .3em 1em .3em 1em; border-bottom-style: dotted; border-bottom-width: 2px;">
<table cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td align="center">
<h1>
<a href="http://www.clanlib.org"><img style="border-style: none; padding-right: 130px;" src="../../gfx/clanlib.png" alt="ClanLib"></a>
</h1>
</td>
</tr>
</table>
<!--<div class="menu">
  <a href="index.html">News</a>
  <a href="intro.html">About</a>
  <a href="download.html">Download</a>
  <a href="cvs.html">CVS</a>
  <a class="active" href="docs.html">Docs</a>
  <a href="games.html">Games</a>
  <a href="contact.html">Contact</a>
  <a href="links.html">Links</a>
</div>-->
</div>
<div style="background-color: white; padding: 1em 3em 1em 3em;">
<!-- clanlib header end -->

<div style="border-bottom-style: dotted;  border-bottom-width: 1px; margin-bottom: 1em;"><h2>Custom Resource Types</h2></div>



<p>Extending the resource management system to incorporate a new resource type can be tricky,
but with a little guidance, it is fairly straight forward.  </p>

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>Intoduction</h3></div>
<p>For this tutorial we will be using a simple class called Object</p>

<ul><pre><font face="Arial,Courier New,Courier">class Object
{
public:
	Object();
	Object(int x, int y);
	int x;
	int y;
};
</font></pre></ul>

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>Modifing the class</h3></div>
<p>First you will need to add a constructor that will load from the resource management system and an instance of <a href="../Reference/html/CL_Resource.html">CL_Resource</a> to store our resource information in.</p>

<ul><pre><font face="Arial,Courier New,Courier">class Object
{
public:
	Object();
	Object(int x, int y);
	Object(const std::string &resource_id, CL_ResourceManager *manager);
	int x;
	int y;

private:
	CL_Resource resource;
};
</font></pre></ul>

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>Creating your resourcedata class</h3></div>
<p>Now, before we actually define our new constructor for Object, lets create our new <codelinke> CL_ResourceData</codelink> derivative class that will actually do the loading. This class is also fairly simple; it needs a constructor that takes a <a href="../Reference/html/CL_Resource.html">CL_Resource</a> and two functions: on_load() and on_unload().  These functions will be called by the resource manager when the resource is loaded and unloaded respectively.</p>

<ul><pre><font face="Arial,Courier New,Courier">class CL_ResourceData_Object : public CL_ResourceData
{
public:
	ResourceData_Object(CL_Resource &resource);
	virtual ~ResourceData_Object();
	Object &get_object();
private:
	void on_load();
	void on_unload();
	Object object;
};
</font></pre></ul>

<p>The constructor tells the resource to attach the data through this instance of CL_ResourceData.  Later when you ask your resource manager to load the object it will call the on_load() function which actually reads in your data.  Notice that the call to get_attribute takes two parameters in this instance. The first is obviously the variable name, but the second is the default value which is used when the attribute is not found.</p>
<ul><pre><font face="Arial,Courier New,Courier">ResourceData_Object::ResourceData_Object(CL_Resource &resource)
: CL_ResourceData(resource)
{
	resource.attach_data("object", this);
}
ResourceData_Object::on_load()
{
	CL_Resource resource = get_resource();
	int x = atoi( (resource.get_element().get_attribute("x","50")).c_str() );
	int y = atoi( (resource.get_element().get_attribute("y","75")).c_str() );
 
	object.x = x;
	object.y = y;
}
ResourceData_Object::on_unload()
{
	object = Object();
}
</font></pre></ul>

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>The callback function</h3></div>
<p>In order for this to work, we have to create a custom callback function to load your new resource types.  The callback function just looks to see if the new resource is of our custom type, and in that event creates a new instance of our resourcedata type.</p>

<ul><pre><font face="Arial,Courier New,Courier">static void resource_added(CL_Resource &resource)
{
	std::string type = resource.get_type();

	if (type == "object") new ResourceData_Object(resource);
}
</font></pre></ul>
<p>And then in your initialization routines just add a line like:</p>
<ul><pre><font face="Arial,Courier New,Courier">CL_Slot slot_resource_added - CL_ResourceManager::sig_resource_added().connect(&resource_added);
</font></pre></ul>

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>Adding object's constructor</h3></div>
<p>Now just add that constructor for Object that we nearly forgot about.  This function will just ask the our <a href="../Reference/html/CL_ResourceManager.html">CL_ResourceManager</a> for the instance of our object, then we tell it load it up.  Then just get our our data from the resource, but if it returns no data then the name you specified is not of type Object.  Then just get out your data however you like, a copy constuctor or overloaded = operator comes in real handy here.</p>

<ul><pre><font face="Arial,Courier New,Courier">Object::Object(const std::string &resource_id, CL_ResourceManager *manager)
{
	resource = manager-&gt;get_resource(resource_id);
	resource.load();

	ResourceData_Object *data =
		(ResourceData_Object *) resource.get_data("object");

	if(!data)
		throw CL_Error("Resource '" + resource_id + "' is not of type 'object'");

	x = data-&gt;get_object().x;
	y = data-&gt;get_object().y;

	resource.unload();
}
</font></pre></ul>

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>Finale</h3></div>
<p>The last thing to do is to call your resource. For a resource file looking like:</p>

<ul><pre><font face="Arial,Courier New,Courier">&lt;resources&gt;
	&lt;object name="object01" x="20" y="20" /&gt;
&lt;/resources&gt;
</font></pre></ul>
<p>Just create your object like this:</p>

<ul><pre><font face="Arial,Courier New,Courier">Object *my_object = new Object("object01", new CL_ResourceManager("my_resourcefile.xml"));
</font></pre></ul>

Thats it!

<div style="border-bottom-style: dotted;  border-bottom-width: 1px;"><h3>TODO:</h3></div>
<list>
<li>Explain how to use the resource manager's provider to load files.</li>
<li>Explain how to make the resource manager cache objects.</li>
</list>
<!-- clanlib footer begin -->
<div style="margin-top: 0em; text-align: center; color: #a0a0a0; border-top-style: dotted; border-top-width: 1px;">
              Questions or comments, write to the <a href="http://clanlib.org/contact.html">ClanLib mailing list</a>.
            </div>
</div>
</div>
</body>
</html>