File: cs_135.html

package info (click to toggle)
crystalspace 0.94-20020412-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 62,276 kB
  • ctags: 52,843
  • sloc: cpp: 274,783; ansic: 6,608; perl: 6,276; objc: 3,952; asm: 2,942; python: 2,354; php: 542; pascal: 530; sh: 430; makefile: 370; awk: 193
file content (197 lines) | stat: -rw-r--r-- 8,279 bytes parent folder | download
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"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_136.html#SEC299"> &gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_131.html#SEC294"> &lt;&lt; </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"> &gt;&gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <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>&nbsp;</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>&nbsp;</td><td class=example><pre>#include "idog.h"

class MyDog : public iDog
{
private:
  <small>...</small> private member functions &#38; 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 &#38; 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>&nbsp;</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>&nbsp;</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-&#62;GetName());
dog-&#62;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"> &lt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_136.html#SEC299"> &gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_131.html#SEC294"> &lt;&lt; </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"> &gt;&gt; </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <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>