1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Created by texi2html 1.64 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
Karl Berry <karl@freefriends.org>
Olaf Bachmann <obachman@mathematik.uni-kl.de>
and many others.
Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
-->
<HTML>
<HEAD>
<TITLE>Crystal Space: Tutorial Introduction</TITLE>
<META NAME="description" CONTENT="Crystal Space: Tutorial Introduction">
<META NAME="keywords" CONTENT="Crystal Space: Tutorial Introduction">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="texi2html 1.64">
</HEAD>
<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<A NAME="SEC158"></A>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_69.html#SEC157"> < </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_71.html#SEC159"> > </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_69.html#SEC157"> << </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_69.html#SEC157"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_73.html#SEC171"> >> </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<HR SIZE=1>
<H2> 5.1 Developing a Crystal Space Application </H2>
<!--docid::SEC158::-->
<P>
Crystal Space is a package of components and libraries which can all be useful
for creating computer games. Although some of the packages are intended more
for 3D gaming this is not as such a restriction of the package. Components as
the sound driver function just as well in a 2D gaming environment and the
networking component can even be used in a text oriented environment. This
highlights one of the important characteristics of Crystal Space: the
components and libraries are more or less independent of each other. If you
don't want networking, then just don't use the networking drivers. If you
don't want scripting then don't include that. All packages are designed to be
functional on their own or with a minimal number of other packages. There are
some dependencies of course. For example, the 3D Engine requires a 3D
Rasterizer to display its output. On the other hand, you could very well use
the 3D Rasterizer without the 3D Engine.
</P><P>
Although there is a high level of independence, there is also a high level of
integration. The components and libraries were also designed to be used
together and as such offer a flexible scheme of integration.
</P><P>
If you are interested in developing a program using Crystal Space, then it is
important to understand that Crystal Space is not a single monolithic library,
but instead consists of several <EM>libraries</EM> and <EM>plug-in modules</EM>.
This manual uses the term <EM>module</EM> for both libraries and plug-ins when
the distinction between the two is not important.
</P><P>
A plug-in module is similar to a library, but has some advantages over a
library. All plug-ins can be accessed in a common fashion. They have a
<EM>very</EM> clear interface, and they can provide this interface even if they
are extracted to a DLL. So they are the better solution as long as speed is
not the dictator of all decisions as in the math library (access to plug-in
functions uses virtual methods). The main difference between the interface of
a library and a plug-in is that a library may use SCF and C++ classes;
plug-ins may only use SCF.
</P><P>
<UL>
<LI>
What is SCF?
<P>
The main SCF object is the <EM>Interface</EM>. An interface is the
solution to strictly decouple the public methods of an object from their
implementation. You only get a pointer to an abstract class with only virtual
methods, called the interface, so your program doesn't know about the actual
object behind the pointer. This object is called an <EM>Implementation</EM> of
the interface. You as the user of Crystal Space will call functions that
create the actual object, but only return the interface. After that you can
use the interface like a C++ object. When you don't need it anymore, don't
`<SAMP>delete</SAMP>' it, but call <CODE>DecRef()</CODE>. When you pass a pointer to the
interface to anywhere, call <CODE>IncRef()</CODE> from there, and <CODE>DecRef()</CODE>
when you don't need the interface there anymore.
</P><P>
As the user you'll only have to include a header that defines the interface,
but not the implementation. Despite the obvious advantage of having a very
clear structure in your code, there is the advantage that linking the
interface to the implementation can be done at run-time, but more about this
later.
</P><P>
<LI>
What are the characteristics of a library?
<P>
A library is just a normal C++ library as you know them. A library can
optionally provide SCF interfaces. In the case of a library this is just
a way to define a clear structure. But as their main interface, libraries
provide C++ classes.
</P><P>
<LI>
What are the characteristics of a plug-in?
<P>
A plug-in, on the other hand, will only provide SCF interfaces, no normal
C++ classes. The plug-in itself will also appear as an SCF interface.
This is part of the definition of a plug-in. A plug-in can be organized as
static library or DLL; this only makes a small difference in how you use
it in your program.
</P><P>
As the user of Crystal Space, you have to do
the following steps to use a plug-in:
</P><P>
<UL>
<LI>
First, do all these steps for the dependencies (other plug-ins) that this
plug-in relies on.
<P>
<LI>
Register the library that contains the plug-in.
<P>
<LI>
Load the plug-in. This will also initialize the plug-in. It will fail if you
forgot any dependencies.
<P>
<LI>
Query the plug-in interface. This is an SCF interface, so you now have
access to the functions of the plug-in.
</UL>
<P>
<LI>
How can I register the plug-in library?
<P>
<EM>Registering</EM> means to tell SCF the name of the plug-in that was
given to it by its author, and a class or a dynamic library to associate it
with. For example, to use the software graphics driver you must tell SCF
that the plug-in with the name `<SAMP>crystalspace.graphics3d.software</SAMP>' can be
found in `<TT>soft3d.dll</TT>' or `<TT>soft3d.so</TT>'. Actually the extension will
be added automatically, so you just have to use `<TT>soft3d</TT>' as the name of
the library. You can find examples for this in `<TT>scf.cfg</TT>'.
</P><P>
How you must register a library depends on whether it is a static library or
a dynamic library (`<TT>.dll</TT>' or `<TT>.so</TT>'). For a static library, put this
line at toplevel into one of your C++ files and link to the static library:
<TABLE><tr><td> </td><td class=example><pre>SCF_REGISTER_STATIC_LIBRARY(<VAR>name</VAR>)
</pre></td></tr></table>This will register all plug-ins in the statically-linked library `<TT>name</TT>'.
This name is chosen by the author of the library. In the case of static
libraries, it may be different from the filename of the library.
</P><P>
For a dynamic library, use `<SAMP>scfreg</SAMP>' at your command line:
<TABLE><tr><td> </td><td class=example><pre>scfreg <VAR>name</VAR>.dll # For Windows or DOS
scfreg lib<VAR>name</VAR>.so # For most Unix platforms
</pre></td></tr></table>This will register all plug-ins in the specified dynamic library. Dynamic
libraries need to be registered only once as long as you do not modify the
library itself. The information is then stored in `<TT>scf.cfg</TT>' (that's why
you can find examples of plugin-to-library association in this file).
</P><P>
<LI>
How can I load the plug-in?
<P>
To load a plug-in, you must tell the plug-in manager the name
of the plug-in as it was registered in the previous step. In the most
common case you will probably use the plug-in loader to load the plug-in.
This is a conveniance class that is able to load plug-in as specified
in a config file, from the commandline, or as requested by the application
programmer. In addition to loading the plug-in (the plug-in loader will
use the plug-in manager to do that), the plug-in loader will optionally
also register the plug-in with the <EM>Object Registry</EM>.
</P><P>
The object registry is a central location in the Crystal Space framework
where any module can register SCF objects. The object registry is not
only for plug-ins. It can contain any SCF object. Objects in the
object registry also have a tag name associated with them. By convention
the <EM>default</EM> object for a given SCF interface will be
added to the object registry with the tag name equal to the interface
name. For example, a 3D renderer is a plug-in module that
implements (among others) the <CODE>iGraphics3D</CODE> interface. At the same
time there can be multiple 3D renderers in memory (for example, for
procedural textures). But the default 3D renderer will be registered
with the tag name 'iGraphics3D'.
</P><P>
Note that the decision which graphics driver you use (e.g. Software or
OpenGL) is done at the time you load the plug-in by passing the name of
that driver. At the time you ask for the plug-in interface and use use it in
your program, this does not make a difference anymore. This makes it possible
to exchange the driver simply by loading another driver, but without changing
your main program.
</P><P>
The CS modules themselves will use the standard plug-ins with the
default tag name as explained above. For example, the 3d engine looks
for the graphics driver by looking in the object registry for an object
with the tag 'iGraphics3D'.
</P><P>
Now how can you actually load the plug-in? You can either load them
manually in the code using the <CODE>CS_LOAD_PLUGIN</CODE> macro or else
you can use the plugin loader. As explained above, the plugin loader
can load plugins specified on the commandline, a config file, or else
explicitely requested in the code. This is done in a specific way:
The commandline has highest priority. i.e. if the user specified the
OpenGL video driver on the commandline then this will be the plugin that
is loaded on the 'iGraphics3D' tag. The config file and plugins requested
from the code are ignored then (for that tag at least). The plugins
requested from the code have lowest priority and only serve as a default
if neither the commandline nor the config file specified a plug-in for
the given tag.
</P><P>
There is a class called <CODE>csInitializer</CODE> which contains various
conveniance routines to help initialize a Crystal Space application.
This class also contains a routine (<CODE>RequestPlugins</CODE>) which will
use the plugin loader automatically.
</P><P>
There are several advantages to using the plugin loader as opposed
to manually loading plug-ins using <CODE>CS_LOAD_PLUGIN</CODE>:
</P><P>
<UL>
<LI>
The plugin loader will sort all plug-ins based on dependencies.
For example, the engine depends on a 3D rasterizer so the plugin
loader will make sure that the engine is loaded later. If you manually
load plugins you risk that the loading will fail because a plugin
that it needs is not yet present.
<LI>
The user is able to override the plug-ins loaded by the plugin loader.
He or she can modify the config file or specify an alternative
plug-in on the commandline. There is no way to change what plugin is
loaded using CS_LOAD_PLUGIN() unless by recompilation (unless of course
you use some other way to read the config file and find out what plugin
to load).
</UL>
<P>
<LI>
How can I query the plug-in interface?
<P>
This is the last step before you can use the plug-in. It means that inside
your program you ask the object registry for an object registered with
the desired tag. The easiest way to do this is as follows:
<CODE>CS_QUERY_REGISTRY(<VAR>object_reg</VAR>,<VAR>iInterface</VAR>)</CODE>.
This macro will search the object registry for the default object
implementing the given interface (i.e. the object registered with the
tag equal to the interface name). Alternatively you can also use
<CODE>CS_QUERY_REGISTRY_TAG</CODE> to get an object with a specific tag.
</P><P>
<LI>
Conclusion
<P>
To sum it up, SCF is mainly used to provide common interfaces for
DLLs, but it can also be used by statically linked libraries. If you
want to know how to write a plug-in yourself, you should read the complete
SCF documentation. See section <A HREF="cs_134.html#SEC297">6.4 Shared Class Facility (SCF)</A>.
</UL>
<P>
For further information about modules and plug-in drivers, see the sections
on Libraries (see section <A HREF="cs_128.html#SEC290">6. Libraries</A>) and plug-in modules
(see section <A HREF="cs_159.html#SEC338">7. Plug-In Modules and Drivers</A>).
</P><P>
Now that you have learned some basics about the Crystal Space environment,
you can try writing your first program.
</P><P>
<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0>
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="cs_71.html#SEC159">5.1.1 Basic Crystal Space Concepts</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="cs_72.html#SEC170">5.1.2 Minimum Application Requirements</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
</TABLE></BLOCKQUOTE>
<P>
<A NAME="TutIntro Basic Concepts"></A>
<HR SIZE=1>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_69.html#SEC157"> < </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_71.html#SEC159"> > </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_69.html#SEC157"> << </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_69.html#SEC157"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_73.html#SEC171"> >> </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<BR>
<FONT SIZE="-1">
This document was generated
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>
</BODY>
</HTML>
|