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
|
<!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: SCF Explained</TITLE>
<META NAME="description" CONTENT="Crystal Space: SCF Explained">
<META NAME="keywords" CONTENT="Crystal Space: SCF Explained">
<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="SEC298"></A>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_134.html#SEC297"> < </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_136.html#SEC299"> > </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_131.html#SEC294"> << </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_134.html#SEC297"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_142.html#SEC310"> >> </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>
<H3> 6.4.1 How it Works </H3>
<!--docid::SEC298::-->
<P>
This paragraph contains technical details about SCF. If you're not
interested in details, you can skip directly to the next chapter which
explains how SCF should be used from the end-users' point of view.
</P><P>
SCF is somewhat similar to COM. This is because historically
Crystal Space initially used COM for inter-module communications. Thanks
to Dan Ogles for the initial implementation of a cross-platform COM
library; his implementation was a good testbed for this SCF
implementation.
</P><P>
The differences between COM and SCF are due to the increased need
for an easier-to-use and maybe a more lightweight interface than COM.
The COM implementation caused some problems (because of bugs in
EGCS 1.1.x and incompatibilities with the Objective-C language used by
NeXT). Also it has some problems due to the native Windows types used in
COM; this experience has been taken into account while developing
SCF.
</P><P>
The main paradigm of SCF, as in COM/CORBA/Java/etc is the
interface. You define an <EM>interface</EM>, that is, a set of abstract methods
that you want to access within some object. SCF interfaces are plain C++
structs (or classes, it doesn't matter much except that if you're using
classes to which you will have to add the `<SAMP>public:</SAMP>' keyword).
Theoretically interfaces can contain even member variables and inline methods
(but no non-virtual methods and constructors), <EM>but</EM> this practice is
not encouraged because later someone may want to add a COM, CORBA,
etc. layer between the client and the actual object, and this will not be
possible if the interfaces were to contain variables or inline methods. If
you don't plan to use COM or CORBA later, then you can use
variables and inline functions as much as you like.
</P><P>
Here is an example of an interface:
</P><P>
<TABLE><tr><td> </td><td class=example><pre>struct iDog
{
virtual bool IsAlive() = 0;
virtual char const* GetName() = 0;
virtual void SetName (char const* iName) = 0;
virtual void Shout(int iHowLoud) = 0;
virtual void Run(int iSpeed, float iDirection) = 0;
virtual bool GetChildren(iObjVector* oBrood) = 0;
};
</pre></td></tr></table></P><P>
Note the last method that gets a pointer of <CODE>iObjVector</CODE> type.
<CODE>iObjVector</CODE> is yet another interface. We could pass a pointer to an
<CODE>csObjVector</CODE> (the implementation of that interface) as well, but this
will mean both modules (caller and callee) should have same idea about what a
<CODE>csObjVector</CODE> is and if it happened that you compiled the shared library
with a slightly different version of <CODE>csObjVector</CODE> (that, say, had one
member variable fewer) you will end up with a SIGSEGV crash.
</P><P>
Now let's write a particular <EM>implementation</EM> of the above interface.
</P><P>
<TABLE><tr><td> </td><td class=example><pre>#include "idog.h"
class MyDog : public iDog
{
private:
<small>...</small> private member functions & variables <small>...</small>
char* Name;
public:
virtual bool IsAlive();
virtual char const* GetName();
virtual void SetName(char const* iName);
virtual void Shout(int iHowLoud);
virtual void Run(int iSpeed, float iDirection);
virtual bool GetChildren(iObjVector* oBrood);
<small>...</small> public member functions & variables <small>...</small>
};
bool MyDog::IsAlive()
{
return true;
};
char const* MyDog::GetName()
{
return Name;
}
void MyDog::SetName(char const* iName)
{
if (Name)
free (Name);
Name = strcpy (iName);
}
<small>...</small> and so on <small>...</small>
</pre></td></tr></table></P><P>
Now we put the actual implementation into a separate module (i.e. into a
shared library), and include within the client just the interface file
`<TT>idog.h</TT>'. Now, since the client don't have any idea how we should build
an object of the `<SAMP>MyDog</SAMP>' class, we also provide a function that will
return a newly-allocated object of that class. This is called the
<EM>class factory</EM> (in fact, a class factory is a bit more than just this,
but more about this later). Here is how to do it:
</P><P>
<TABLE><tr><td> </td><td class=example><pre>static iDog* Create_iDog()
{
return new MyDog();
}
</pre></td></tr></table></P><P>
Okay, we did it. Now back to the client. To work with an object that
implements the `<SAMP>iDog</SAMP>' interface we need to load the shared library, get
a pointer to the <CODE>Create_MyDog()</CODE> function, call it and get a new
`<SAMP>MyDog</SAMP>' object. Further we work with this pointer as if it were pointing
to an `<SAMP>iDog</SAMP>' object:
</P><P>
<TABLE><tr><td> </td><td class=example><pre>handle = LoadLibrary("libdog.so");
iDog (*Create_iDog)() = GetLibrarySymbol("Create_IDog");
iDog* dog = Create_iDog();
printf("Doggy's name is %s\n", dog->GetName());
dog->Shout(100);
<small>...</small>
</pre></td></tr></table></P><P>
Of course, you don't have to do all this stuff manually with current SCF
implementation. The SCF library provides a number of macros and
functions that almost hides the implementation details from end-user.
</P><P>
<A NAME="SCF Using"></A>
<HR SIZE=1>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_134.html#SEC297"> < </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_136.html#SEC299"> > </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_131.html#SEC294"> << </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_134.html#SEC297"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_142.html#SEC310"> >> </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>
|