Linux multi-monitor fullscreen support
[ryzomcore.git] / ryzom / common / src / game_share / generate_module_interface.xslt
blobee87f6ae49f18775440cf9211fa3287fb01bf0a1
1 <?xml version="1.0"?>
2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
4 <xsl:output method="text" indent="no"/>
6 <!-- Output : can be 'header', 'cpp' or 'php' -->
7 <xsl:param name="output" select="'header'"/>
8 <xsl:param name="filename"/>
10 <!-- A special template applyer that is mode aware -->
11 <xsl:template name="myApplyTemplate"><xsl:choose><xsl:when test="$output = 'header'"><xsl:apply-templates mode="header"/></xsl:when><xsl:when test="$output = 'cpp'"><xsl:apply-templates mode="cpp"/></xsl:when><xsl:when test="$output = 'php'"><xsl:apply-templates mode="php"/></xsl:when></xsl:choose></xsl:template>
13 <!-- some stupide template to remove unwanted text from output -->
14 <xsl:template match="text()" mode="php"/>
15 <xsl:template match="text()" mode="cpp"/>
16 <xsl:template match="text()" mode="header"/>
18 <!-- ######################################################### -->
19 <!-- ##### Root template matcher ####### -->
20 <!-- ######################################################### -->
21 <xsl:template match="generator">
22 <xsl:if test="$output != 'php'">
23 /////////////////////////////////////////////////////////////////
24 // WARNING : this is a generated file, don't change it !
25 /////////////////////////////////////////////////////////////////
26 </xsl:if>
27 <xsl:if test="$output = 'header'">
28 #ifndef <xsl:value-of select="@header_tag"/>
29 #define <xsl:value-of select="@header_tag"/>
30 #include "nel/misc/types_nl.h"
31 #include &lt;memory&gt;
32 #include "nel/misc/hierarchical_timer.h"
33 #include "nel/misc/string_conversion.h"
34 #include "nel/net/message.h"
35 #include "nel/net/module.h"
36 #include "nel/net/module_builder_parts.h"
37 #include "nel/net/module_message.h"
38 #include "nel/net/module_gateway.h"
39 <xsl:if test="//callback_interface">
40 <!--#include "nel/net/callback_server.h"
41 #include "nel/net/callback_client.h"-->
42 #include "game_share/callback_adaptor.h"
43 </xsl:if>
44 <xsl:if test="//class/database">
45 #include "nel/misc/string_common.h"
46 #include "server_share/mysql_wrapper.h"
47 </xsl:if>
48 <xsl:if test="//class/message">
49 #include "game_share/synchronised_message.h"
50 </xsl:if>
51 </xsl:if>
52 <!--<xsl:if test="$output = 'cpp'">
53 <xsl:apply-templates select="cpp-include"/>
54 #include "<xsl:value-of select="$filename"/>.h"
55 </xsl:if>-->
56 <xsl:call-template name="myApplyTemplate"/>
57 <xsl:if test="$output = 'header'">
58 #endif
59 </xsl:if>
60 </xsl:template>
62 <!-- ######################################################### -->
63 <!-- ##### Namespace specification ####### -->
64 <!-- ######################################################### -->
65 <xsl:template match="namespace" mode="header">
66 <!--#ifndef NLNET_INTERFACE_GET_MODULE
67 # define NLNET_INTERFACE_GET_MODULE NLNET::IModule *getModuleInstance() { return this; }
68 #endif
69 -->
70 namespace <xsl:value-of select="@name"/>
72 <!-- forward declaration of class -->
73 <xsl:for-each select="class">
74 class <xsl:value-of select="@name"/>;
75 <xsl:if test="database">
76 class <xsl:value-of select="@name"/>Ptr;</xsl:if></xsl:for-each>
77 <xsl:text>
78 </xsl:text>
79 <!-- declaration of smart ptr class -->
80 <xsl:for-each select="class">
81 <xsl:if test="database">
82 <xsl:call-template name="makePersistentPtrHeader">
83 <xsl:with-param name="className" select="@name"/>
84 </xsl:call-template>
85 <xsl:text>
86 </xsl:text>
87 </xsl:if>
88 </xsl:for-each>
89 <xsl:call-template name="myApplyTemplate"/>
91 </xsl:template>
93 <!-- _______________________________________ -->
94 <xsl:template match="namespace" mode="cpp">
95 #include "<xsl:value-of select="$filename"/>.h"
97 namespace <xsl:value-of select="@name"/>
99 <xsl:call-template name="myApplyTemplate"/>
101 </xsl:template>
103 <!-- _______________________________________ -->
104 <xsl:template match="namespace" mode="php"><xsl:apply-templates mode="php"/></xsl:template>
106 <!-- ######################################################### -->
107 <!-- ##### Additionnal includes ####### -->
108 <!-- ######################################################### -->
109 <xsl:template match="include" mode="header">
110 #include "<xsl:value-of select="@file"/>"
111 </xsl:template>
112 <xsl:template match="sys-include" mode="header">
113 #include &lt;<xsl:value-of select="@file"/>&gt;
114 </xsl:template>
116 <xsl:template match="cpp-include" mode="cpp">
117 #include "<xsl:value-of select="@file"/>"
118 </xsl:template>
120 <xsl:template match="php-include" mode="php">
121 <xsl:text>&lt;?php
122 require_once('</xsl:text><xsl:value-of select="@file"/><xsl:text>');
123 ?&gt;
124 </xsl:text>
125 </xsl:template>
127 <!-- ######################################################### -->
128 <!-- ##### Verbatim code ####### -->
129 <!-- ######################################################### -->
130 <xsl:template match="verbatim_header" mode="header">
131 <xsl:value-of select="."/>
132 </xsl:template>
134 <!-- ################################################################## -->
135 <!-- ##### Generate a module interface classes (Header Part)#### -->
136 <!-- ################################################################## -->
137 <xsl:template match="module_interface" mode="header">
138 /////////////////////////////////////////////////////////////////
139 // WARNING : this is a generated file, don't change it !
140 /////////////////////////////////////////////////////////////////
141 class <xsl:value-of select="@name"/>Skel
143 public:
144 /// the interceptor type
145 typedef NLNET::CInterceptorForwarder &lt; <xsl:value-of select="@name"/>Skel&gt; TInterceptor;
146 protected:
147 <xsl:value-of select="@name"/>Skel()
149 // do early run time check for message table
150 getMessageHandlers();
152 virtual ~<xsl:value-of select="@name"/>Skel()
156 void init(NLNET::IModule *module)
158 _Interceptor.init(this, module);
160 <!-- If the interface contains two-way invocation methods, we need a virtual to retreive the module instance -->
161 <xsl:if test="method/return">
162 public:
164 <!-- // Virtual to retreive the instance of the implementation module
165 // Use the macro NLNET_INTERFACE_GET_MODULE to simply declare the implementation in your module
166 virtual NLNET::IModule *getModuleInstance() =0;
168 </xsl:if>
169 // unused interceptors
170 std::string fwdBuildModuleManifest() const { return std::string(); }
171 void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) {}
172 void fwdOnModuleDown(NLNET::IModuleProxy *moduleProxy) {}
173 void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {}
175 // process module message interceptor
176 bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;message);
177 private:
179 typedef void (<xsl:value-of select="@name"/>Skel::*TMessageHandler)(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;message);
180 typedef std::map&lt;std::string, TMessageHandler&gt; TMessageHandlerMap;
182 const TMessageHandlerMap &amp;getMessageHandlers() const;
184 <xsl:for-each select="method">
185 <xsl:choose>
186 <xsl:when test="not(return)">
187 void <xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message);
188 </xsl:when>
189 <xsl:when test="return">
190 void <xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message);
191 </xsl:when>
192 </xsl:choose>
193 </xsl:for-each>
194 <xsl:text>
195 </xsl:text>// declare one interceptor member of the skeleton
196 TInterceptor _Interceptor;
198 // declare the interceptor forwarder as friend of this class
199 friend class NLNET::CInterceptorForwarder &lt; <xsl:value-of select="@name"/>Skel&gt;;
200 <xsl:text> public:
201 /////////////////////////////////////////////////////////////////
202 // WARNING : this is a generated file, don't change it !
203 /////////////////////////////////////////////////////////////////
205 </xsl:text>
206 <xsl:for-each select="method">
207 <xsl:choose>
208 <xsl:when test="not(return)">
209 <xsl:call-template name="makeMethodDoc"/>
210 <xsl:text> </xsl:text>virtual void <xsl:value-of select="@name"/>(NLNET::IModuleProxy *sender<xsl:call-template name="makeParamList"/>)<xsl:text> =0;
211 </xsl:text>
212 </xsl:when>
213 <xsl:when test="return">
214 <xsl:call-template name="makeMethodDoc"/>
215 <xsl:text> </xsl:text>virtual <xsl:value-of select="return/@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>(NLNET::IModuleProxy *sender<xsl:call-template name="makeParamList"/>)<xsl:text> =0;
216 </xsl:text>
217 </xsl:when>
218 </xsl:choose>
219 </xsl:for-each>
223 /////////////////////////////////////////////////////////////////
224 // WARNING : this is a generated file, don't change it !
225 /////////////////////////////////////////////////////////////////
226 <xsl:text> </xsl:text>class <xsl:value-of select="@name"/>Proxy
228 /// Smart pointer on the module proxy
229 NLNET::TModuleProxyPtr _ModuleProxy;
231 // Pointer on the local module that implement the interface (if the proxy is for a local module)
232 NLNET::TModulePtr _LocalModule;
233 // Direct pointer on the server implementation interface for collocated module
234 <xsl:value-of select="@name"/>Skel *_LocalModuleSkel;
237 public:
238 <xsl:value-of select="@name"/>Proxy(NLNET::IModuleProxy *proxy)
240 <xsl:if test="@module_class"> nlassert(proxy->getModuleClassName() == <xsl:value-of select="@module_class"/>);</xsl:if>
241 _ModuleProxy = proxy;
243 // initialize collocated servant interface
244 if (proxy->getModuleDistance() == 0)
246 _LocalModule = proxy->getLocalModule();
247 nlassert(_LocalModule != NULL);
248 <xsl:value-of select="@name"/>Skel::TInterceptor *interceptor = NULL;
249 interceptor = static_cast &lt; NLNET::CModuleBase* &gt;(_LocalModule.getPtr())->getInterceptor(interceptor);
250 nlassert(interceptor != NULL);
252 _LocalModuleSkel = interceptor->getParent();
253 nlassert(_LocalModuleSkel != NULL);
255 else
256 _LocalModuleSkel = 0;
259 virtual ~<xsl:value-of select="@name"/>Proxy()
263 NLNET::IModuleProxy *getModuleProxy()
265 return _ModuleProxy;
268 <xsl:for-each select="method">
269 <xsl:call-template name="makeMethodDoc"/>
270 <xsl:choose>
271 <xsl:when test="not(return)">
272 <xsl:text> </xsl:text>void <xsl:value-of select="@name"/>(NLNET::IModule *sender<xsl:call-template name="makeParamList"/>);
273 </xsl:when>
274 <xsl:when test="return">
275 <xsl:text> </xsl:text><xsl:value-of select="return/@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>(NLNET::IModule *sender<xsl:call-template name="makeParamList"/>);
276 </xsl:when>
277 </xsl:choose>
278 </xsl:for-each>
280 <xsl:for-each select="method[@broadcast = 'true']">
281 <xsl:call-template name="makeMethodDoc"/>
282 <xsl:text>
283 // This is the broadcast version of the method.
284 template &lt; class ProxyIterator &gt;
285 </xsl:text>static void broadcast_<xsl:value-of select="@name"/>(ProxyIterator first, ProxyIterator last, NLNET::IModule *sender<xsl:call-template name="makeParamList"/>)
287 NLNET::CMessage message;
289 // create the message to send to multiple dest
290 buildMessageFor_<xsl:value-of select="@name"/>(message <xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
292 for (; first != last; ++first)
294 NLNET::IModuleProxy *proxy = *first;
296 proxy->sendModuleMessage(sender, message);
299 }<xsl:text>
300 </xsl:text>
301 </xsl:for-each>
304 <xsl:for-each select="method">
305 <xsl:text>
306 // Message serializer. Return the message received in reference for easier integration
307 static const NLNET::CMessage &amp;buildMessageFor_</xsl:text><xsl:value-of select="@name"/>(NLNET::CMessage &amp;__message<xsl:call-template name="makeParamList"/>);
308 </xsl:for-each>
312 };<xsl:text>
313 </xsl:text>
315 </xsl:template>
317 <!-- ######################################################### -->
318 <!-- ##### Generate module interface, cpp part ####### -->
319 <!-- ######################################################### -->
320 <xsl:template match="module_interface" mode="cpp">
321 /////////////////////////////////////////////////////////////////
322 // WARNING : this is a generated file, don't change it !
323 /////////////////////////////////////////////////////////////////
324 <xsl:variable name="skelName" select="concat(@name, 'Skel')"/>
325 <xsl:variable name="proxyName" select="concat(@name, 'Proxy')"/>
327 const <xsl:value-of select="$skelName"/>::TMessageHandlerMap &amp;<xsl:value-of select="$skelName"/>::getMessageHandlers() const
329 static TMessageHandlerMap handlers;
330 static bool init = false;
332 if (!init)
334 std::pair &lt; TMessageHandlerMap::iterator, bool &gt; res;
335 <xsl:for-each select="method">
336 res = handlers.insert(std::make_pair(std::string("<xsl:value-of select="@msg"/>"), &amp;<xsl:value-of select="$skelName"/>::<xsl:value-of select="@name"/>_skel));
337 // if this assert, you have a doubly message name in your interface definition !
338 nlassert(res.second);
339 </xsl:for-each>
340 init = true;
343 return handlers;
345 bool <xsl:value-of select="@name"/>Skel::fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;message)
347 const TMessageHandlerMap &amp;mh = getMessageHandlers();
349 TMessageHandlerMap::const_iterator it(mh.find(message.getName()));
351 if (it == mh.end())
353 return false;
356 TMessageHandler cmd = it->second;
357 (this->*cmd)(sender, message);
359 return true;
362 <xsl:for-each select="method">
363 <xsl:choose>
364 <xsl:when test="not(return)">
365 void <xsl:value-of select="$skelName"/>::<xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message)
367 H_AUTO(<xsl:value-of select="$skelName"/>_<xsl:value-of select="@name"/>_<xsl:value-of select="@msg"/>);
368 <xsl:for-each select="param">
369 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
370 </xsl:text>
371 <xsl:call-template name="serialRead"><xsl:with-param name="message" select="'__message'"/></xsl:call-template>
372 </xsl:for-each>
374 <xsl:text> </xsl:text><xsl:value-of select="@name"/>(sender<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);<xsl:text>
375 </xsl:text>
376 <xsl:text> }
377 </xsl:text>
378 </xsl:when>
379 <xsl:when test="return">
380 void <xsl:value-of select="$skelName"/>::<xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message)
382 H_AUTO(<xsl:value-of select="$skelName"/>_<xsl:value-of select="@name"/>_<xsl:value-of select="@msg"/>);
383 <xsl:for-each select="param">
384 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
385 </xsl:text>
386 <xsl:call-template name="serialRead"><xsl:with-param name="message" select="'__message'"/></xsl:call-template>
387 </xsl:for-each>
389 <xsl:text> </xsl:text><xsl:value-of select="return/@type"/> __ret = <xsl:value-of select="@name"/>(sender<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
390 // encode the return message
391 NLNET::CMessage __retMsg;
392 __retMsg.setType("R_<xsl:value-of select="@msg"/>", NLNET::CMessage::Response);
393 nlWrite(__retMsg, serial<xsl:value-of select="return/@serial"/>, __ret);
395 // and send back the response
396 sender->sendModuleMessage(static_cast&lt;NLNET::IModule*&gt;(_Interceptor.getRegistrar()), __retMsg);
397 <xsl:text>
398 </xsl:text>
399 <xsl:text> }
400 </xsl:text>
401 </xsl:when>
402 </xsl:choose>
403 </xsl:for-each>
405 <xsl:for-each select="method">
406 <xsl:call-template name="makeMethodDoc"/>
407 <xsl:choose>
408 <xsl:when test="not(return)">
409 <xsl:text> </xsl:text>void <xsl:value-of select="$proxyName"/>::<xsl:value-of select="@name"/>(NLNET::IModule *sender<xsl:call-template name="makeParamList"/>)
411 if (_LocalModuleSkel &amp;&amp; _LocalModule->isImmediateDispatchingSupported())
413 // immediate local synchronous dispatching
414 _LocalModuleSkel-><xsl:value-of select="@name"/>(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender)<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
416 else
418 // send the message for remote dispatching and execution or local queing
419 NLNET::CMessage __message;
421 buildMessageFor_<xsl:value-of select="@name"/>(__message<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
423 _ModuleProxy->sendModuleMessage(sender, __message);
425 }<xsl:text>
426 </xsl:text>
427 </xsl:when>
428 <xsl:when test="return">
429 <xsl:text> </xsl:text><xsl:value-of select="return/@type"/><xsl:text> </xsl:text><xsl:value-of select="$proxyName"/>::<xsl:value-of select="@name"/>(NLNET::IModule *sender<xsl:call-template name="makeParamList"/>)
431 if (_LocalModuleSkel &amp;&amp; _LocalModule->isImmediateDispatchingSupported())
433 // immediate local synchronous dispatching
434 return _LocalModuleSkel-><xsl:value-of select="@name"/>(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender)<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
436 else
438 // send the message for remote dispatching and execution
440 NLNET::CMessage __message;
442 buildMessageFor_<xsl:value-of select="@name"/>(__message<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
444 NLNET::CMessage __retMsg;
445 sender->invokeModuleOperation(_ModuleProxy, __message, __retMsg);
447 // check the return message type
448 if (__retMsg.getName() != "R_<xsl:value-of select="@msg"/>")
449 throw NLNET::IModule::EInvokeBadReturn();
451 <xsl:value-of select="return/@type"/> __ret;
452 nlRead(__retMsg, serial, __ret);
454 return __ret;
456 }<xsl:text>
457 </xsl:text>
458 </xsl:when>
459 </xsl:choose>
460 </xsl:for-each>
462 <xsl:for-each select="method">
463 <xsl:text>
464 // Message serializer. Return the message received in reference for easier integration
465 const NLNET::CMessage &amp;</xsl:text><xsl:value-of select="$proxyName"/>::buildMessageFor_<xsl:value-of select="@name"/>(NLNET::CMessage &amp;__message<xsl:call-template name="makeParamList"/>)
467 __message.setType("<xsl:value-of select="@msg"/>"<xsl:if test="return">, NLNET::CMessage::Request</xsl:if>);
468 <xsl:for-each select="param"><xsl:call-template name="serialWrite"> <xsl:with-param name="message" select="'__message'"/></xsl:call-template>
469 </xsl:for-each>
471 return __message;
472 }<xsl:text>
473 </xsl:text>
474 </xsl:for-each>
477 </xsl:template>
479 <!-- ######################################################### -->
480 <!-- ##### Generate documentation ####### -->
481 <!-- ######################################################### -->
482 <xsl:template name="makeMethodDoc">
483 <xsl:for-each select="doc">
484 <xsl:text> // </xsl:text><xsl:value-of select="@line"/><xsl:text>
485 </xsl:text>
486 </xsl:for-each>
487 </xsl:template>
489 <xsl:template name="makeMasterDoc">
490 <xsl:for-each select="doc">
491 <xsl:text> // </xsl:text><xsl:value-of select="@line"/><xsl:text>
492 </xsl:text>
493 </xsl:for-each>
494 </xsl:template>
496 <!-- ######################################################### -->
497 <!-- ##### Generate parameter list ####### -->
498 <!-- #########################################################-->
499 <xsl:template name="makeParamList">
500 <xsl:if test="param">
501 <xsl:text>, </xsl:text><xsl:call-template name="makeParamListNoStartingComma"/>
502 </xsl:if>
503 </xsl:template>
505 <xsl:template name="makeParamListNoStartingComma">
506 <xsl:if test="param">
507 <xsl:for-each select="param">
508 <xsl:choose>
509 <xsl:when test="@array = 'true'">
510 <!-- generate vector for callback interface-->
511 <xsl:text>const std::vector&lt;</xsl:text><xsl:value-of select="@type"/>&gt; &amp;<xsl:value-of select="@name"/><xsl:if test="position() != last()">, </xsl:if>
512 </xsl:when>
513 <xsl:otherwise>
514 <xsl:if test="@byref = 'true' or @enum='smart'">const </xsl:if><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:if test="@byref = 'true' or @enum = 'smart'">&amp;</xsl:if><xsl:value-of select="@name"/><xsl:if test="position() != last()">, </xsl:if>
515 </xsl:otherwise>
516 </xsl:choose>
517 </xsl:for-each>
518 </xsl:if>
519 </xsl:template>
521 <!-- ######################################################### -->
522 <!-- ##### Write serialisation ####### -->
523 <!-- ######################################################### -->
524 <xsl:template name="serialWrite">
525 <xsl:param name="message" select="'message'"/>
526 <xsl:choose>
527 <xsl:when test="@byref = 'true'">
528 <xsl:text> </xsl:text>nlWrite(<xsl:value-of select="$message"/>, serial<xsl:value-of select="@serial"/>, const_cast &lt; <xsl:value-of select="@type"/>&amp; &gt; (<xsl:value-of select="@name"/>));<xsl:text>
529 </xsl:text>
530 </xsl:when>
531 <xsl:otherwise>
532 <xsl:if test="not(@array)">
533 <xsl:text> </xsl:text>nlWrite(<xsl:value-of select="$message"/>, serial<xsl:value-of select="@serial"/>, <xsl:value-of select="@name"/>);<xsl:text>
534 </xsl:text>
535 </xsl:if>
537 <xsl:if test="@array = 'true'">
538 <xsl:text> </xsl:text>nlWrite(<xsl:value-of select="$message"/>, serialCont, <xsl:value-of select="@name"/>);<xsl:text>
539 </xsl:text>
540 </xsl:if>
541 </xsl:otherwise>
542 </xsl:choose>
543 </xsl:template>
545 <!-- ######################################################### -->
546 <!-- ##### Read serialisation ####### -->
547 <!-- ######################################################### -->
548 <xsl:template name="serialRead">
549 <xsl:param name="message" select="'message'"/>
550 <xsl:if test="not(@array)">
551 <xsl:text> </xsl:text>nlRead(<xsl:value-of select="$message"/>, serial<xsl:value-of select="@serial"/>, <xsl:value-of select="@name"/>);<xsl:text>
552 </xsl:text>
553 </xsl:if>
554 <xsl:if test="@array = 'true'">
555 <xsl:text> </xsl:text>nlRead(<xsl:value-of select="$message"/>, serialCont, <xsl:value-of select="@name"/>);<xsl:text>
556 </xsl:text>
557 </xsl:if>
558 </xsl:template>
560 <!-- ######################################################### -->
561 <!-- ##### Enum generation ####### -->
562 <!-- ######################################################### -->
565 <xsl:template match="enum" mode="php">
566 <xsl:text>&lt;?php
567 /////////////////////////////////////////////////////////////////
568 // WARNING : this is a generated file, don't change it !
569 /////////////////////////////////////////////////////////////////
571 $arrayCounter = 0;
572 </xsl:text>
573 <xsl:for-each select="item">
574 <xsl:text> $</xsl:text><xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="../@name"/>_EnumValues[$arrayCounter++] = "<xsl:value-of select="@name"/><xsl:text>";
575 </xsl:text></xsl:for-each>
576 <xsl:text> $</xsl:text><xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues[$arrayCounter] = "invalid";
577 $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue = $arrayCounter;
579 class <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>
581 var $Value;
583 function <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>()
585 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
586 $this->Value = $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
589 function toString()
591 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues;
592 return $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues[$this->Value];
595 function fromString($strValue)
597 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues;
598 foreach ($<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues as $k => $v)
600 if ($strValue === $v)
602 $this->Value = $k;
603 return;
607 $this->Value = $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
610 function toInt()
612 return $this->Value;
615 function fromInt($intValue)
617 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
618 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues;
619 if (array_key_exists($intValue, $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues))
620 $this->Value = $intValue;
621 else
622 $this->Value = $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
625 <xsl:text>?&gt;
626 </xsl:text></xsl:template>
629 <xsl:template match="enum" mode="header">
630 <xsl:call-template name="makeMasterDoc"/>
631 <xsl:if test="@bitset='true'">
632 <xsl:call-template name="enumGen">
633 <xsl:with-param name="enumName" select="concat(@name, 'Enum')"/>
634 </xsl:call-template>
635 typedef NLMISC::CEnumBitset &lt; <xsl:value-of select="@name"/>Enum, uint32, <xsl:value-of select="@name"/>Enum::invalid_val, ',', NLMISC::TContainedEnum &lt; <xsl:value-of select="@name"/>Enum, uint32 &gt;, <xsl:value-of select="@name"/>Enum::TValues &gt; <xsl:value-of select="@name"/>;
636 </xsl:if>
637 <xsl:if test="not(@bitset='true')">
638 <xsl:call-template name="enumGen">
639 <xsl:with-param name="enumName" select="@name"/>
640 </xsl:call-template>
641 </xsl:if>
642 </xsl:template>
645 <xsl:template name="enumGen">
646 <xsl:param name="enumName"/>
648 <!-- check that we don't set a base value AND a value for the 1st enum item -->
649 <xsl:if test="@base and item[1]/@value">
650 <xsl:message terminate="yes">
651 ERROR : You can't set a base value AND a value for the first item on enum definition <xsl:value-of select="$enumName"/>
652 </xsl:message>
653 </xsl:if>
655 struct <xsl:value-of select="$enumName"/>
657 enum TValues
659 <xsl:for-each select="item">
660 <xsl:value-of select="@name"/><xsl:if test="@value"> = <xsl:value-of select="@value"/></xsl:if>
661 <xsl:if test="position() = 1 and ../@base"> = <xsl:value-of select="../@base"/></xsl:if>,
662 </xsl:for-each>
663 <!-- generate a value 'past the end' and 'last_enum_item' if no values are set other than on first item-->
664 <xsl:if test="count(item/@value) = 0 or (count(item/@value) = 1 and item[1]/@value)">
665 <xsl:text>/// the highest valid value in the enum
666 last_enum_item = </xsl:text><xsl:value-of select="item[last()]/@name"/>,
667 /// a value equal to the last enum item +1
668 end_of_enum,
669 </xsl:if>
670 <!-- generate an invalid and undefined value-->
671 invalid_val,
672 <!-- generate a count of node -->
673 /// Number of enumerated values
674 nb_enum_items = <xsl:value-of select="count(item)"/>
676 <!-- generate an index table if the enum is 'linear' -->
677 <xsl:if test="count(item/@value) = 0 or (count(item/@value) = 1 and item[1]/@value)">
678 /// Index table to convert enum value to linear index table
679 const std::map&lt;TValues, uint32&gt; &amp;getIndexTable() const
681 static std::map&lt;TValues, uint32&gt; indexTable;
682 static bool init = false;
683 if (!init)
685 // fill the index table
686 <xsl:for-each select="item">
687 <xsl:text> indexTable.insert(std::make_pair(</xsl:text><xsl:value-of select="@name"/>, <xsl:value-of select="position()-1"/>));
688 </xsl:for-each>
689 init = true;
692 return indexTable;
694 </xsl:if>
696 static const NLMISC::CStringConversion&lt;TValues&gt; &amp;getConversionTable()
698 NL_BEGIN_STRING_CONVERSION_TABLE(TValues)
699 <xsl:for-each select="item"> NL_STRING_CONVERSION_TABLE_ENTRY(<xsl:value-of select="@name"/>)
700 </xsl:for-each> NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val)
702 static NLMISC::CStringConversion&lt;TValues&gt;
703 conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table)
704 / sizeof(TValues_nl_string_conversion_table[0]), invalid_val);
706 return conversionTable;
709 TValues _Value;
711 public:
712 <xsl:value-of select="$enumName"/>()
713 : _Value(invalid_val)
716 <xsl:value-of select="$enumName"/>(TValues value)
717 : _Value(value)
721 <xsl:value-of select="$enumName"/>(const std::string &amp;str)
723 _Value = getConversionTable().fromString(str);
726 void serial(NLMISC::IStream &amp;s)
728 s.serialEnum(_Value);
731 bool operator == (const <xsl:value-of select="$enumName"/> &amp;other) const
733 return _Value == other._Value;
735 bool operator != (const <xsl:value-of select="$enumName"/> &amp;other) const
737 return ! (_Value == other._Value);
739 bool operator &lt; (const <xsl:value-of select="$enumName"/> &amp;other) const
741 return _Value &lt; other._Value;
744 bool operator &lt;= (const <xsl:value-of select="$enumName"/> &amp;other) const
746 return _Value &lt;= other._Value;
749 bool operator &gt; (const <xsl:value-of select="$enumName"/> &amp;other) const
751 return !(_Value &lt;= other._Value);
753 bool operator &gt;= (const <xsl:value-of select="$enumName"/> &amp;other) const
755 return !(_Value &lt; other._Value);
758 const std::string &amp;toString() const
760 return getConversionTable().toString(_Value);
762 static const std::string &amp;toString(TValues value)
764 return getConversionTable().toString(value);
767 TValues getValue() const
769 return _Value;
772 // return true if the actual value of the enum is valid, otherwise false
773 bool isValid()
775 if (_Value == invalid_val)
776 return false;
778 // not invalid, check other enum value
779 return getConversionTable().isValid(_Value);
782 <!-- generate an index table if the enum is 'linear' -->
783 <xsl:if test="count(item/@value) = 0 or (count(item/@value) = 1 and item[1]/@value)">
784 uint32 asIndex()
786 std::map&lt;TValues, uint32&gt;::const_iterator it(getIndexTable().find(_Value));
787 nlassert(it != getIndexTable().end());
788 return it->second;
790 </xsl:if>
792 <!-- insert user code if any -->
793 <xsl:if test="header_code">
794 <xsl:value-of select="header_code"/>
795 </xsl:if>
797 </xsl:template>
801 <!-- ######################################################### -->
802 <!-- ##### Class generation (db mapping, serial and message)### -->
803 <!-- ######################################################### -->
805 <xsl:template name="makeProperty">
806 <xsl:param name="property"/>
807 <xsl:text> </xsl:text>// <xsl:value-of select="$property/@doc"/><xsl:text>
808 </xsl:text>
809 <xsl:text> </xsl:text><xsl:value-of select="$property/@type"/><xsl:text> _</xsl:text><xsl:value-of select="$property/@name"/><xsl:text>;
810 </xsl:text>
811 </xsl:template>
813 <!--/////////////////////////////////////////////////////////-->
814 <xsl:template name="makePropertyAccessor">
815 <xsl:param name="property"/>
816 <xsl:text> </xsl:text>// <xsl:value-of select="$property/@doc"/><xsl:text>
817 </xsl:text>
818 <xsl:choose>
819 <xsl:when test="$property/@byref = 'true'">
820 <xsl:text> </xsl:text>const <xsl:value-of select="$property/@type"/> &amp;get<xsl:value-of select="$property/@name"/>() const
822 return _<xsl:value-of select="$property/@name"/>;
825 <xsl:if test="not(../database) and $property/@byref = 'true'">
826 <!-- for non database 'by reference' property, generate a non const get accessor -->
827 <xsl:text> </xsl:text><xsl:value-of select="$property/@type"/> &amp;get<xsl:value-of select="$property/@name"/>()
829 return _<xsl:value-of select="$property/@name"/>;
831 </xsl:if>
833 void set<xsl:value-of select="$property/@name"/>(const <xsl:value-of select="$property/@type"/> &amp;value)
835 <xsl:if test="../database">
836 if (_<xsl:value-of select="$property/@name"/> != value)
838 if (getPersistentState() != NOPE::os_transient)
839 setPersistentState(NOPE::os_dirty);
840 </xsl:if>
842 <xsl:variable name="relation" select="parent[@db_col = $property/@db_col]"/>
843 <xsl:if test="$relation">
844 <!-- this property is a child/parent relation, update the parent -->
846 <xsl:value-of select="$relation/@class"/>Ptr parent = <xsl:value-of select="$relation/@class"/>::loadFromCache(_<xsl:value-of select="$property/@name"/>);
848 if (parent &amp;&amp; getPersistentState() != NOPE::os_transient )
849 parent->remove<xsl:value-of select="$relation/@child_name"/>Child(this);
850 </xsl:if>
852 _<xsl:value-of select="$property/@name"/> = value;
854 <xsl:if test="$relation">
855 <!-- this property is a child/parent relation, update the parent -->
857 <xsl:value-of select="$relation/@class"/>Ptr parent = <xsl:value-of select="$relation/@class"/>::loadFromCache(_<xsl:value-of select="$property/@name"/>);
858 if (parent &amp;&amp; getPersistentState() != NOPE::os_transient)
859 parent->insert<xsl:value-of select="$relation/@child_name"/>Child(this);
860 </xsl:if>
861 <xsl:if test="../database">
863 </xsl:if>
865 </xsl:when>
866 <xsl:otherwise>
867 <xsl:text> </xsl:text><xsl:value-of select="$property/@type"/> get<xsl:value-of select="$property/@name"/>() const
869 return _<xsl:value-of select="$property/@name"/>;
872 void set<xsl:value-of select="$property/@name"/>(<xsl:value-of select="$property/@type"/> value)
874 <xsl:if test="../database">
875 if (_<xsl:value-of select="$property/@name"/> != value)
877 if (getPersistentState() != NOPE::os_transient)
878 setPersistentState(NOPE::os_dirty);
879 </xsl:if>
880 _<xsl:value-of select="$property/@name"/> = value;
881 <xsl:if test="../database">
883 </xsl:if>
885 </xsl:otherwise>
886 </xsl:choose>
887 </xsl:template>
890 <!--/////////////////////////////////////////////////////////-->
891 <xsl:template name="makeChildAccessor">
892 <xsl:param name="childClass"/>
893 <xsl:if test="@cont">
894 <xsl:choose>
895 <xsl:when test="@cont = 'vector'">
896 /** Return a const reference to the vector of child.
897 * If you want to modify the element inside, you need to
898 * use on of the two following methods who return non const pointer
899 * on contained elements.
901 const std::vector&lt;<xsl:value-of select="@type"/>Ptr&gt; &amp;get<xsl:value-of select="@name"/>() const;
902 /** Return the ith element of the child vector
903 * index must be valid (ie less than size of the vector)
905 <xsl:value-of select="@type"/>Ptr &amp;get<xsl:value-of select="@name"/>ByIndex(uint32 index) const;
906 /** Return the identified element by looking in the vector
907 * If no element match the id, NULL pointer is returned
909 <xsl:value-of select="@type"/>Ptr &amp;get<xsl:value-of select="@name"/>ById(uint32 id) const;
911 </xsl:when>
912 <xsl:when test="@cont = 'map'">
913 /** Return a const reference to the map of child.
914 * If you want to modify the element inside, you need to
915 * use on of the two following method who return non const pointer
916 * on contained elements.
918 const std::map&lt;uint32, <xsl:value-of select="@type"/>Ptr&gt; &amp;get<xsl:value-of select="@name"/>() const;
919 /** Return the identified element by looking in the map
920 * If no element match the id, NULL pointer is returned
922 <xsl:value-of select="@type"/>Ptr &amp;get<xsl:value-of select="@name"/>ById(uint32 id) const;
924 </xsl:when>
925 <xsl:otherwise>
926 <xsl:message terminate="yes">
927 ERROR : Invalide container, child must be either map or vector for child <xsl:value-of select="@name"/> in class <xsl:value-of select="../@name"/>
929 </xsl:message>
930 </xsl:otherwise>
931 </xsl:choose>
932 </xsl:if>
934 <xsl:if test="not(@cont)">
935 /** Return the one child object (or null if not) */
936 <xsl:value-of select="@type"/>Ptr get<xsl:value-of select="@name"/>();
937 </xsl:if>
938 </xsl:template>
941 <!--/////////////////////////////////////////////////////////-->
942 <xsl:template name="makeColumList">
943 <xsl:param name="uniqueId"/>
944 <xsl:choose>
945 <xsl:when test="property[@name = $uniqueId and @db_col]/@autogen = 'true'">
946 qs += "<xsl:for-each select="property[@name != $uniqueId]">
947 <xsl:value-of select="@db_col"/>
948 <xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if>
949 </xsl:for-each><xsl:text>";</xsl:text>
950 </xsl:when>
951 <xsl:otherwise>
952 qs += "<xsl:for-each select="property[@db_col]">
953 <xsl:value-of select="@db_col"/>
954 <xsl:if test="position() != last()">, </xsl:if>
955 </xsl:for-each><xsl:text>";</xsl:text>
956 </xsl:otherwise>
957 </xsl:choose>
958 </xsl:template>
960 <xsl:template name="makeColumListWithId">
961 qs += "<xsl:for-each select="property[@db_col]">
962 <xsl:value-of select="@db_col"/>
963 <xsl:if test="position() != last()">, </xsl:if>
964 </xsl:for-each>
965 <xsl:text>";
966 </xsl:text>
967 </xsl:template>
969 <xsl:template name="makeValueList">
970 <xsl:param name="uniqueId"/>
971 <xsl:choose>
972 <xsl:when test="property[@name = $uniqueId]/@autogen = 'true'">
973 <xsl:for-each select="property[@name != $uniqueId and @db_col]">
974 <xsl:choose>
975 <xsl:when test="@enum='true' or @enum='smart'">
976 qs += "'"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
977 </xsl:text>
978 </xsl:when>
979 <xsl:when test="@date='true'">
980 qs += "'"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
981 </xsl:text>
982 </xsl:when>
983 <xsl:when test="@md5='true'">
984 qs += "'"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
985 </xsl:text>
986 </xsl:when>
987 <xsl:otherwise>
988 qs += "'"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
989 </xsl:text>
990 </xsl:otherwise>
991 </xsl:choose>
992 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
993 </xsl:for-each>
994 </xsl:when>
995 <xsl:otherwise>
996 <xsl:for-each select="property[@db_col]">
997 <xsl:choose>
998 <xsl:when test="@enum='true' or @enum='smart'">
999 qs += "'"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
1000 </xsl:text>
1001 </xsl:when>
1002 <xsl:when test="@date='true'">
1003 qs += "'"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1004 </xsl:text>
1005 </xsl:when>
1006 <xsl:when test="@md5='true'">
1007 qs += "'"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1008 </xsl:text>
1009 </xsl:when>
1010 <xsl:otherwise>
1011 qs += "'"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1012 </xsl:text>
1013 </xsl:otherwise>
1014 </xsl:choose>
1015 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1016 </xsl:for-each>
1017 </xsl:otherwise>
1018 </xsl:choose>
1019 </xsl:template>
1021 <xsl:template name="makeValueListWithId">
1022 <xsl:for-each select="property[@db_col]">
1023 <xsl:choose>
1024 <xsl:when test="@enum='true' or @enum='smart'">
1025 qs += "'"+_<xsl:value-of select="@name"/>.toString()+"'";
1026 </xsl:when>
1027 <xsl:when test="@date='true'">
1028 qs += "'"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1029 </xsl:text>
1030 </xsl:when>
1031 <xsl:when test="@md5='true'">
1032 qs += "'"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1033 </xsl:text>
1034 </xsl:when>
1035 <xsl:otherwise>
1036 qs += "'"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)+"'";
1037 </xsl:otherwise>
1038 </xsl:choose>
1039 <xsl:if test="position() != last()">qs += ", ";</xsl:if>
1040 </xsl:for-each>
1041 </xsl:template>
1043 <xsl:template name="makeSetList">
1044 <xsl:param name="uniqueId"/>
1045 <xsl:choose>
1046 <xsl:when test="property[@name = $uniqueId and @db_col]/@autogen = 'true'">
1047 <xsl:for-each select="property[@name != $uniqueId and @db_col]">
1048 <xsl:choose>
1049 <xsl:when test="@enum='true' or @enum='smart'">
1050 qs += "<xsl:value-of select="@db_col"/> = '"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
1051 </xsl:text>
1052 </xsl:when>
1053 <xsl:when test="@date='true'">
1054 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1055 </xsl:text>
1056 </xsl:when>
1057 <xsl:when test="@md5='true'">
1058 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1059 </xsl:text>
1060 </xsl:when>
1061 <xsl:otherwise>
1062 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1063 </xsl:text>
1064 </xsl:otherwise>
1065 </xsl:choose>
1066 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1067 </xsl:for-each>
1068 </xsl:when>
1069 <xsl:otherwise>
1070 <xsl:for-each select="property[@db_col]">
1071 <xsl:choose>
1072 <xsl:when test="@enum='true' or @enum='smart'">
1073 qs += "<xsl:value-of select="@db_col"/> = '"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
1074 </xsl:text>
1075 </xsl:when>
1076 <xsl:when test="@date='true'">
1077 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1078 </xsl:text>
1079 </xsl:when>
1080 <xsl:when test="@md5='true'">
1081 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1082 </xsl:text>
1083 </xsl:when>
1084 <xsl:otherwise>
1085 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1086 </xsl:text>
1087 </xsl:otherwise>
1088 </xsl:choose>
1089 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1090 </xsl:for-each>
1091 </xsl:otherwise>
1092 </xsl:choose>
1093 </xsl:template>
1095 <xsl:template name="makeWhereClause">
1096 <xsl:param name="uniqueId"/>
1097 qs += " WHERE <xsl:value-of select="property[@name = $uniqueId]/@db_col"/> = '"+NLMISC::toString(_<xsl:value-of select="property[@name = $uniqueId]/@name"/>)+"'";
1098 </xsl:template>
1100 <xsl:template name="makeWhereClauseWithId">
1101 <xsl:param name="uniqueId"/>
1102 <xsl:param name="id"/>
1103 qs += " WHERE <xsl:value-of select="property[@name = $uniqueId]/@db_col"/> = '"+NLMISC::toString(<xsl:value-of select="$id"/>)+"'";
1104 </xsl:template>
1108 <!-- ######################################################### -->
1109 <!-- ##### Class generation (db mapping, serial and message)### -->
1110 <!-- ######################################################### -->
1111 <!-- ##### Include file #### -->
1112 <xsl:template match="class" mode="header">
1113 <xsl:if test="count(property[@unique_id = 'true' and @db_col]) != 1 and datase">
1114 <xsl:message terminate="yes">
1115 ERROR : You must have ONE and ONLY one unique_id property in class '_<xsl:value-of select="@name"/>'
1116 </xsl:message>
1117 </xsl:if>
1119 <xsl:choose>
1120 <xsl:when test="database">
1121 <xsl:call-template name="makeClassHeader">
1122 <xsl:with-param name="className" select="@name"/>
1123 <xsl:with-param name="uniqueId" select="property[@unique_id = 'true']/@name"/>
1124 </xsl:call-template>
1125 </xsl:when>
1126 <xsl:otherwise>
1127 <xsl:call-template name="makeClassHeader">
1128 <xsl:with-param name="className" select="@name"/>
1129 <xsl:with-param name="uniqueId" select="''"/>
1130 </xsl:call-template>
1131 </xsl:otherwise>
1132 </xsl:choose>
1133 </xsl:template>
1135 <xsl:template name="makeClassHeader">
1136 <xsl:param name="className"/>
1137 <xsl:param name="uniqueId"/>
1139 <!--<xsl:if test="database">
1140 <xsl:call-template name="makePersistentPtrHeader">
1141 <xsl:with-param name="className" select="@name"/>
1142 </xsl:call-template>
1143 </xsl:if>
1145 <xsl:call-template name="makeMasterDoc"/>
1146 <xsl:text> /////////////////////////////////////////////////////////////////
1147 // WARNING : this is a generated file, don't change it !
1148 /////////////////////////////////////////////////////////////////
1149 class </xsl:text><xsl:value-of select="$className"/>
1151 <xsl:text> protected:
1152 </xsl:text> <xsl:for-each select="property">
1153 <xsl:call-template name="makeProperty">
1154 <xsl:with-param name="property" select="."/>
1155 </xsl:call-template>
1156 </xsl:for-each>
1157 <xsl:for-each select="child_class[@relation = 'one-to-many']">
1158 friend class <xsl:value-of select="@type"/>;
1159 <xsl:choose>
1160 <xsl:when test="@cont = 'map'">
1161 std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; *_<xsl:value-of select="@name"/>;
1162 </xsl:when>
1163 <xsl:when test="@cont = 'vector'">
1164 std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; *_<xsl:value-of select="@name"/>;
1165 </xsl:when>
1166 <xsl:otherwise>
1167 <xsl:message terminate="yes">
1168 ERROR : You must define the cont="" property with either 'vector' or 'map' value in the child_class element for class '<xsl:value-of select="../@name"/>' , child '_<xsl:value-of select="@name"/>'
1169 </xsl:message>
1170 </xsl:otherwise>
1171 </xsl:choose>
1172 </xsl:for-each>
1173 <xsl:for-each select="child_class[@relation = 'one-to-one']">
1174 <xsl:text> friend class </xsl:text><xsl:value-of select="@type"/>;
1175 bool _<xsl:value-of select="@name"/>Loaded;
1176 <xsl:value-of select="@type"/>Ptr _<xsl:value-of select="@name"/>;
1177 </xsl:for-each>
1179 <xsl:text> public:
1180 </xsl:text> <xsl:for-each select="property[@name != $uniqueId]">
1181 <xsl:call-template name="makePropertyAccessor">
1182 <xsl:with-param name="property" select="."/>
1183 </xsl:call-template>
1184 </xsl:for-each>
1186 <xsl:for-each select="child_class">
1187 <xsl:call-template name="makeChildAccessor">
1188 <xsl:with-param name="childClass" select="."/>
1189 </xsl:call-template>
1190 </xsl:for-each>
1191 bool operator == (const <xsl:value-of select="@name"/> &amp;other) const
1193 return <xsl:for-each select="property">_<xsl:value-of select="@name"/> == other._<xsl:value-of select="@name"/><xsl:if test="position() != last()">
1194 &amp;&amp; </xsl:if></xsl:for-each>;
1197 <xsl:if test="not(database)">
1198 <xsl:text>
1199 // constructor
1200 </xsl:text><xsl:value-of select="$className"/>()
1202 <xsl:if test="property[@default]"> // Default initialisation
1203 </xsl:if>
1204 <xsl:for-each select="property[@default]">
1205 <xsl:text> </xsl:text>_<xsl:value-of select="@name"/> = <xsl:value-of select="@default"/>;
1206 </xsl:for-each>
1208 </xsl:if>
1210 <xsl:if test="message">
1211 <!-- generate a serialisable and sendable nel message -->
1212 void send(const std::string &amp;serviceName)
1214 NLNET::CMessage msg("<xsl:value-of select="@name"/>");
1215 serial(msg);
1216 sendMessageViaMirror( serviceName, msg );
1219 void send(NLNET::TServiceId serviceId)
1221 NLNET::CMessage msg("<xsl:value-of select="@name"/>");
1222 serial(msg);
1223 sendMessageViaMirror( serviceId, msg );
1225 </xsl:if>
1227 <xsl:if test="database">
1228 <xsl:text>
1229 private:
1230 // private constructor, you must use 'createTransient' to get an instance
1231 </xsl:text><xsl:value-of select="$className"/>()
1232 : _PtrList(NULL),
1233 _ObjectState(NOPE::os_transient),
1234 _<xsl:value-of select="$uniqueId"/>(NOPE::INVALID_OBJECT_ID)
1236 <xsl:if test="property[@default]"> // Default initialisation
1237 </xsl:if>
1238 <xsl:for-each select="property[@default]">
1239 <xsl:text> </xsl:text>_<xsl:value-of select="@name"/> = <xsl:value-of select="@default"/>;
1240 </xsl:for-each>
1241 <xsl:for-each select="child_class[@relation = 'one-to-many']">
1242 <xsl:text> _</xsl:text><xsl:value-of select="@name"/> = NULL;
1243 </xsl:for-each>
1244 <xsl:for-each select="child_class[@relation = 'one-to-one']">
1245 <xsl:text> _</xsl:text><xsl:value-of select="@name"/>Loaded = false;
1246 </xsl:for-each>
1247 // register the cache for this class (if not already done)
1248 registerUpdatable();
1251 // Destructor, delete any children
1252 ~<xsl:value-of select="@name"/>();
1254 /// utility func to remove this object from the released object container
1255 void removeFromReleased();
1258 public:
1259 /// Create a new instance in the transient space
1260 static <xsl:value-of select="$className"/>Ptr createTransient(const char *filename, uint32 lineNum)
1262 return <xsl:value-of select="$className"/>Ptr(new <xsl:value-of select="$className"/>(), filename, lineNum);
1265 /** Create a new object in the database from the current object data.
1266 * The object MUST be in transient state (i.e, it must be a new
1267 * object created by user and not comming from the databse).
1268 * If identifier is autogenerated, the generated id can be read after
1269 * this call.
1271 bool create(MSW::CConnection &amp;connection);
1272 /** Update the database with the current object state.
1273 * The object MUST be either in clean or dirty state.
1274 * Return true if the object has been effectively stored
1275 * in the database.
1276 * After this call, the object is in 'clean' state.
1278 bool update(MSW::CConnection &amp;connection);
1279 /** Remove the current object from the persistent storage.
1280 * The object must be in clean or dirty state.
1281 * Return true if the object has been correctly
1282 * updated in the database.
1283 * After the call, the object is in 'clean' state.
1285 bool remove(MSW::CConnection &amp;connection);
1286 /** Remove an object from the persistent storage by specifying
1287 * the id to remove.
1288 * Return true if an entry as been effectively removed from
1289 * the database.
1290 * After the call, the object is in 'removed' state and should
1291 * no more be used. A good pratice should be to delete
1292 * the transient object just after the remove call.
1294 static bool removeById(MSW::CConnection &amp;connection, uint32 id);
1296 /** Load an instance from the database.
1297 * This call allocate a new object and load the property value
1298 * from the database.
1299 * Return NULL if the object id is not found.
1301 static <xsl:value-of select="$className"/>Ptr load(MSW::CConnection &amp;connection, uint32 id, const char *filename, uint32 lineNum);
1303 <xsl:for-each select="parent[@relation = 'one-to-many']">
1304 /** Load all objects children of <xsl:value-of select="@class"/> and
1305 * return them by using the specified output iterator.
1307 <xsl:choose>
1308 <xsl:when test="@cont = 'vector'">
1309 static bool loadChildrenOf<xsl:value-of select="@class"/>(MSW::CConnection &amp;connection, uint32 parentId, std::vector &lt; <xsl:value-of select="$className"/>Ptr &gt; &amp;children, const char *filename, uint32 lineNum);
1310 </xsl:when>
1311 <xsl:when test="@cont = 'map'">
1312 static bool loadChildrenOf<xsl:value-of select="@class"/>(MSW::CConnection &amp;connection, uint32 parentId, std::map &lt; uint32, <xsl:value-of select="$className"/>Ptr &gt; &amp;children, const char *filename, uint32 lineNum);
1313 </xsl:when>
1314 <xsl:otherwise>
1315 <xsl:message terminate="yes">
1316 ERROR : parent/child relation support only 'map' or 'vector' cont specification in <xsl:value-of select="$className"/> definition
1317 </xsl:message>
1318 </xsl:otherwise>
1319 </xsl:choose>
1320 </xsl:for-each>
1321 <xsl:for-each select="parent[@relation = 'one-to-one']">
1322 /** Load the object child of <xsl:value-of select="@class"/> and
1323 * return true if no error, false in case of error (in SQL maybe).
1324 * If no such object is found, fill the child pointer with NULL.
1326 static bool loadChildOf<xsl:value-of select="@class"/>(MSW::CConnection &amp;connection, uint32 parentId, <xsl:value-of select="../@name"/>Ptr &amp;childPtr, const char *filename, uint32 lineNum);
1327 </xsl:for-each>
1330 <!-- <child_class type="CKnownUser" name="KnownUsers" relation="one-to-many" cont="vector"/>-->
1331 <xsl:for-each select="child_class">
1332 /// Load <xsl:value-of select="@name"/> child(ren) object(s).
1333 bool load<xsl:value-of select="@name"/>(MSW::CConnection &amp;connection, const char *filename, uint32 lineNum);
1334 </xsl:for-each>
1335 </xsl:if>
1337 <!-- generate serial -->
1338 <xsl:if test="serial or message">
1339 <xsl:text>
1340 void serial(NLMISC::IStream &amp;s)
1342 </xsl:text>
1343 <xsl:for-each select="property">
1344 <xsl:text> s.serial</xsl:text><xsl:value-of select="@serial"/>(_<xsl:value-of select="@name"/>)<xsl:text>;
1345 </xsl:text>
1346 </xsl:for-each>
1348 </xsl:if>
1350 private:
1351 <!-- generate private child container modifier -->
1352 <xsl:for-each select="child_class[relation = 'one-to-many' and cont='vector']">
1354 /// add a child in the container
1355 void insert<xsl:value-of select="@name"/>Child(<xsl:value-of select="@type"/> &amp;child)
1357 nlassert(std::find(_<xsl:value-of select="@name"/>.begin(), _<xsl:value-of select="@name"/>.end(), child) == _<xsl:value-of select="@name"/>.end());
1359 _<xsl:value-of select="@name"/>.push_back(child);
1362 // remove a child from the container
1363 void removeXXChild()
1367 </xsl:for-each>
1370 <xsl:if test="database">
1371 private:
1372 friend class CPersistentCache;
1373 friend class <xsl:value-of select="$className"/>Ptr;
1375 typedef std::map&lt;uint32, <xsl:value-of select="$className"/>*&gt; TObjectCache;
1376 typedef std::set&lt;<xsl:value-of select="$className"/>*&gt; TObjectSet;
1377 typedef std::map&lt;time_t, TObjectSet&gt; TReleasedObject;
1379 /// The complete set of object currently in memory (either active or released) excluding transient instance
1380 static TObjectCache _ObjectCache;
1381 /// The set of object in memory ut released (no pointer on them) and waiting for decommit
1382 static TReleasedObject _ReleasedObject;
1384 /// The current object state
1385 NOPE::TObjectState _ObjectState;
1387 /// For object in released state, this is the release date (used to trigger deletion of the object from memory)
1388 time_t _ReleaseDate;
1390 /// The linked list of pointer on this object
1391 <xsl:value-of select="$className"/>Ptr *_PtrList;
1393 // Try to load the specified object from the memory cache, return NULL if the object is not in the cache
1394 static <xsl:value-of select="$className"/> *loadFromCache(uint32 objectId, bool unrelease);
1396 // Receive and execute command from the cache manager.
1397 static uint32 cacheCmd(NOPE::TCacheCmd cmd);
1399 static void dump();
1401 static void updateCache();
1403 public:
1404 static void clearCache();
1405 private:
1406 void registerUpdatable();
1408 // set the pointer on the first pointer of the pointer list (set to null when there is no more pointer)
1409 void setFirstPtr(<xsl:value-of select="$className"/>Ptr *ptr);
1411 // return the first pointer of the pointer list (can be null)
1412 <xsl:value-of select="$className"/>Ptr *getFirstPtr()
1414 return _PtrList;
1417 public:
1419 /** Return the object identifier (witch is unique)
1420 * You can only call this method on a persistent instance.
1421 * (because transient instance can have invalid id)
1423 uint32 getObjectId() const
1425 <xsl:if test="property[@name = $uniqueId]/@autogen = 'true'">
1426 nlassert(getPersistentState() != NOPE::os_transient);</xsl:if>
1427 return _<xsl:value-of select="$uniqueId"/>;
1430 /** Set the object unique ID.
1431 * You can only set the object id on a transient object
1432 * having a non autogenerated unique id.
1433 * Furthermore, you MUST set the id before calling create()
1434 * if the id is not autogenerated.
1436 void setObjectId(uint32 objectId)
1438 // can only be set when in transient state
1439 nlassert(getPersistentState() == NOPE::os_transient);
1440 // can only be set once
1441 nlassert(_<xsl:value-of select="$uniqueId"/> == NOPE::INVALID_OBJECT_ID);
1442 _<xsl:value-of select="$uniqueId"/> = objectId;
1445 /** Return the current persistent state of the object.*/
1446 NOPE::TObjectState getPersistentState() const
1448 return _ObjectState;
1451 private:
1452 // Set the persistent state of the object and do some house keeping
1453 void setPersistentState(NOPE::TObjectState state);
1455 </xsl:if>
1460 </xsl:template>
1463 <!-- ######################################################### -->
1464 <!-- ##### Class generation (db mapping, serial and message)### -->
1465 <!-- ######################################################### -->
1466 <!-- ##### cpp file #### -->
1467 <xsl:template match="class" mode="cpp">
1468 <xsl:if test="count(property[@unique_id = 'true' and @db_col]) != 1 and database">
1469 <xsl:message terminate="yes">
1470 ERROR : You must have ONE and ONLY one unique_id property in class '_<xsl:value-of select="@name"/>'
1471 </xsl:message>
1472 </xsl:if>
1474 <xsl:choose>
1475 <xsl:when test="database">
1476 <xsl:call-template name="makeClassCpp">
1477 <xsl:with-param name="className" select="@name"/>
1478 <xsl:with-param name="uniqueId" select="property[@unique_id = 'true']/@name"/>
1479 </xsl:call-template>
1480 </xsl:when>
1481 <xsl:otherwise>
1482 <xsl:call-template name="makeClassCpp">
1483 <xsl:with-param name="className" select="@name"/>
1484 <xsl:with-param name="uniqueId" select="''"/>
1485 </xsl:call-template>
1486 </xsl:otherwise>
1487 </xsl:choose>
1488 </xsl:template>
1490 <xsl:template name="makeClassCpp">
1491 <xsl:param name="className"/>
1492 <xsl:param name="uniqueId"/>
1494 <xsl:if test="database">
1495 <xsl:call-template name="makePersistentPtrCpp">
1496 <xsl:with-param name="className" select="@name"/>
1497 </xsl:call-template>
1498 </xsl:if>
1501 <xsl:if test="database">
1502 <xsl:text>
1504 </xsl:text> <xsl:value-of select="$className"/>::TObjectCache <xsl:value-of select="$className"/>::_ObjectCache;
1505 <xsl:value-of select="$className"/>::TReleasedObject <xsl:value-of select="$className"/>::_ReleasedObject;
1506 <xsl:text>
1508 // Destructor, delete any children
1509 </xsl:text><xsl:value-of select="$className"/>::~<xsl:value-of select="@name"/>()
1511 // release childs reference
1512 <xsl:for-each select="child_class[@relation = 'one-to-many']">
1513 <xsl:text> if (_</xsl:text><xsl:value-of select="@name"/> != NULL)
1514 delete _<xsl:value-of select="@name"/>;
1515 </xsl:for-each>
1517 if (_PtrList != NULL)
1519 nlwarning("ERROR : someone try to delete this object, but there are still ptr on it !");
1520 <xsl:value-of select="$className"/>Ptr *ptr = _PtrList;
1523 nlwarning(" Pointer created from '%s', line %u", ptr->_FileName, ptr->_LineNum);
1524 ptr = _PtrList->getNextPtr();
1525 } while(ptr != _PtrList);
1526 nlstop;
1528 // remove object from cache map
1529 if (_<xsl:value-of select="$uniqueId"/> != NOPE::INVALID_OBJECT_ID
1530 &amp;&amp; _ObjectState != NOPE::os_removed
1531 &amp;&amp; _ObjectState != NOPE::os_transient)
1533 nldebug("NOPE: clearing <xsl:value-of select="$className"/> @%p from cache with id %u", this, static_cast&lt;uint32&gt;(_<xsl:value-of select="$uniqueId"/>));
1534 nlverify(_ObjectCache.erase(_<xsl:value-of select="$uniqueId"/>) == 1);
1536 else if (_ObjectState != NOPE::os_transient)
1538 nlassert(_ObjectCache.find(_<xsl:value-of select="$uniqueId"/>) == _ObjectCache.end());
1540 if (_ObjectState == NOPE::os_released)
1542 removeFromReleased();
1544 else
1546 TReleasedObject::iterator it(_ReleasedObject.find(_ReleaseDate));
1547 if (it != _ReleasedObject.end())
1549 nlassert(it->second.find(this) == it->second.end());
1554 void <xsl:value-of select="$className"/>::removeFromReleased()
1556 TReleasedObject::iterator it(_ReleasedObject.find(_ReleaseDate));
1557 nlassert(it != _ReleasedObject.end());
1558 TObjectSet &amp;os = it->second;
1560 nlverify(os.erase(this) == 1);
1562 // nb : _ReleasedObject time entry are removed by the cache update
1565 bool <xsl:value-of select="$className"/>::create(MSW::CConnection &amp;connection)
1567 nlassert(getPersistentState() == NOPE::os_transient);
1568 <xsl:if test="not(property[@name = $uniqueId]/@autogen = 'true')">
1569 nlassert(_<xsl:value-of select="property[@name = $uniqueId]/@name"/> != 0);</xsl:if>
1570 std::string qs;
1571 qs = "INSERT INTO <xsl:value-of select="database/@table"/> (";
1572 <xsl:call-template name="makeColumList">
1573 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1574 </xsl:call-template>
1575 qs += ") VALUES (";
1576 <xsl:call-template name="makeValueList">
1577 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1578 </xsl:call-template>
1579 qs += ")";
1581 if (connection.query(qs))
1583 <xsl:if test="property[@name = $uniqueId]/@autogen = 'true'">
1584 <xsl:text> uint32 _id_ = connection.getLastGeneratedId();
1585 setObjectId(_id_);
1586 </xsl:text></xsl:if>
1588 setPersistentState(NOPE::os_clean);
1590 // update the parent class instance in cache if any
1591 <xsl:for-each select="parent[@relation = 'one-to-many']">
1592 <xsl:variable name="db_col" select="@db_col"/>
1593 <xsl:variable name="parentId" select="concat('_', ../property[@db_col = $db_col]/@name)"/>
1594 if (<xsl:value-of select="$parentId"/> != 0)
1596 // need to update the parent class child list if it is in the cache
1597 <xsl:value-of select="@class"/> *parent = <xsl:value-of select="@class"/>::loadFromCache(<xsl:value-of select="$parentId"/>, false);
1598 if (parent &amp;&amp; parent->_<xsl:value-of select="@child_name"/> != NULL)
1600 <xsl:choose>
1601 <xsl:when test="@cont = 'map'">
1602 nlverify(parent->_<xsl:value-of select="@child_name"/>->insert(std::make_pair(getObjectId(), <xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__))).second);
1603 </xsl:when>
1604 <xsl:when test="@cont = 'vector'">
1605 nlassert(std::find(parent->_<xsl:value-of select="@child_name"/>->begin(), parent->_<xsl:value-of select="@child_name"/>->end(), <xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__)) == parent->_<xsl:value-of select="@child_name"/>->end());
1606 parent->_<xsl:value-of select="@child_name"/>->push_back(<xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__));
1607 </xsl:when>
1608 </xsl:choose>
1611 </xsl:for-each>
1613 <xsl:for-each select="parent[@relation = 'one-to-one']">
1614 <xsl:variable name="db_col" select="@db_col"/>
1615 <xsl:variable name="parentId" select="concat('_', ../property[@db_col = $db_col]/@name)"/>
1616 if (<xsl:value-of select="$parentId"/> != 0)
1618 // need to update the parent class child if it is in the cache
1619 <xsl:value-of select="@class"/> *parent = <xsl:value-of select="@class"/>::loadFromCache(<xsl:value-of select="$parentId"/>, false);
1620 if (parent &amp;&amp; parent->_<xsl:value-of select="@child_name"/>Loaded)
1622 nlassert(parent->_<xsl:value-of select="@child_name"/> == NULL);
1623 parent->_<xsl:value-of select="@child_name"/> = <xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__);
1626 </xsl:for-each>
1627 return true;
1630 return false;
1633 bool <xsl:value-of select="$className"/>::update(MSW::CConnection &amp;connection)
1635 nlassert(getPersistentState() == NOPE::os_dirty || getPersistentState() == NOPE::os_clean);
1637 if (getPersistentState() == NOPE::os_clean)
1638 // the object is clean, just ignore the save
1639 return true;
1641 std::string qs;
1642 qs = "UPDATE <xsl:value-of select="database/@table"/> SET ";
1643 <xsl:call-template name="makeSetList">
1644 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1645 </xsl:call-template>
1646 <xsl:call-template name="makeWhereClause">
1647 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1648 </xsl:call-template>
1650 if (connection.query(qs))
1652 if (connection.getAffectedRows() == 1)
1654 setPersistentState(NOPE::os_clean);
1655 return true;
1659 return false;
1662 bool <xsl:value-of select="$className"/>::remove(MSW::CConnection &amp;connection)
1664 nlassert(getPersistentState() == NOPE::os_dirty || getPersistentState() == NOPE::os_clean);
1666 std::string qs;
1667 qs = "DELETE FROM <xsl:value-of select="database/@table"/> ";
1668 <xsl:call-template name="makeWhereClause">
1669 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1670 </xsl:call-template>
1672 if (connection.query(qs))
1674 if (connection.getAffectedRows() == 1)
1676 <xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='vector']">
1678 // cascading deletion for vector child <xsl:value-of select="@name"/>
1679 nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
1681 const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1683 while (!childs.empty())
1685 get<xsl:value-of select="@name"/>ByIndex(childs.size()-1)->remove(connection);
1689 </xsl:for-each>
1690 <xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='map']">
1692 // cascading deletion for map child <xsl:value-of select="@name"/>
1693 nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
1695 const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1697 while (!childs.empty())
1699 get<xsl:value-of select="@name"/>ById(childs.begin()->first)->remove(connection);
1702 </xsl:for-each>
1703 <xsl:for-each select="child_class[@on-delete = 'cascade' and @relation='one-to-one']">
1705 // cascading deletion for single child <xsl:value-of select="@name"/>
1706 nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
1708 if (get<xsl:value-of select="@name"/>() != NULL)
1709 get<xsl:value-of select="@name"/>()->remove(connection);
1711 </xsl:for-each>
1712 <xsl:for-each select="child_class[@on-delete = 'update' and @cont='vector']">
1714 // unreference (and update) for vector child <xsl:value-of select="@name"/>
1715 nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
1717 const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1719 for (uint i=0; i &lt; childs.size(); ++i)
1721 <xsl:variable name="type" select="@type"/>
1722 <xsl:variable name="child_name" select="@name"/>
1723 <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
1724 get<xsl:value-of select="@name"/>ByIndex(i)->set<xsl:value-of select="$parent_prop"/>(0);
1725 get<xsl:value-of select="@name"/>ByIndex(i)->update(connection);
1728 </xsl:for-each>
1729 <xsl:for-each select="child_class[@on-delete = 'update' and @cont='map']">
1731 // unreference (and update) for map child <xsl:value-of select="@name"/>
1732 nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
1734 const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1735 std::map&lt; uint32, <xsl:value-of select="@type"/>Ptr &gt;::const_iterator first(childs.begin()), last(childs.end());
1737 for (; first != last; ++first)
1739 <xsl:variable name="type" select="@type"/>
1740 <xsl:variable name="child_name" select="@name"/>
1741 <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
1742 get<xsl:value-of select="@name"/>ById(it->first)->set<xsl:value-of select="$parent_prop"/>(0);
1743 get<xsl:value-of select="@name"/>ById(it->first)->update(connection);
1746 </xsl:for-each>
1747 <xsl:for-each select="child_class[@on-delete = 'update' and @relation='one-to-one']">
1749 // unreference (and update) for single child <xsl:value-of select="@name"/>
1750 nlassert(load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__));
1752 <xsl:variable name="type" select="@type"/>
1753 <xsl:variable name="child_name" select="@name"/>
1754 <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
1755 if (get<xsl:value-of select="@name"/>() != NULL)
1757 get<xsl:value-of select="@name"/>()->set<xsl:value-of select="parent_prop"/>(0);
1758 get<xsl:value-of select="@name"/>()->update(connection);
1761 </xsl:for-each>
1763 // change the persistant state to 'removed'.
1764 setPersistentState(NOPE::os_removed);
1766 // need to remove ref from parent class container (if any)
1767 <xsl:for-each select="parent[@relation = 'one-to-many']">
1769 <xsl:variable name="db_col" select="@db_col"/>
1770 <xsl:if test="count(../property[@db_col = $db_col]) = 0">
1771 <xsl:message terminate="yes">
1772 ERROR : parent/child relation : can't find parent param with db_col '<xsl:value-of select="$db_col"/>' in <xsl:value-of select="$className"/> definition
1773 </xsl:message>
1774 </xsl:if>
1775 <xsl:value-of select="@class"/>Ptr parent(<xsl:value-of select="@class"/>::loadFromCache(_<xsl:value-of select="../property[@db_col = $db_col]/@name"/>, true), __FILE__, __LINE__);
1776 if (parent != NULL &amp;&amp; parent->_<xsl:value-of select="@child_name"/> != NULL)
1778 <xsl:choose>
1779 <xsl:when test="@cont = 'map'">
1780 parent->_<xsl:value-of select="@child_name"/>->erase(getObjectId());
1781 </xsl:when>
1782 <xsl:when test="@cont = 'vector'">
1783 std::vector &lt; <xsl:value-of select="$className"/>Ptr &gt;::iterator it = std::find(parent->_<xsl:value-of select="@child_name"/>->begin(), parent->_<xsl:value-of select="@child_name"/>->end(), this);
1784 if (it != parent->_<xsl:value-of select="@child_name"/>->end())
1786 parent->_<xsl:value-of select="@child_name"/>->erase(it);
1788 </xsl:when>
1789 <xsl:otherwise>
1790 <xsl:message terminate="yes">
1791 ERROR : parent/child relation support only 'map' or 'vector' cont specification in <xsl:value-of select="$className"/> definition
1792 </xsl:message>
1793 </xsl:otherwise>
1794 </xsl:choose>
1797 </xsl:for-each>
1798 // need to remove ref from parent (if any)
1799 <xsl:for-each select="parent[@relation = 'one-to-one']">
1801 <xsl:variable name="db_col" select="@db_col"/>
1802 <xsl:value-of select="@class"/>Ptr parent(<xsl:value-of select="@class"/>::loadFromCache(_<xsl:value-of select="../property[@db_col = $db_col]/@name"/>, true), __FILE__, __LINE__);
1803 if (parent != NULL &amp;&amp; parent->_<xsl:value-of select="@child_name"/>Loaded)
1805 // assign a new NULL pointer
1806 parent->_<xsl:value-of select="@child_name"/>.assign(<xsl:value-of select="$className"/>Ptr(), __FILE__, __LINE__);
1809 </xsl:for-each>
1811 return true;
1814 return false;
1817 bool <xsl:value-of select="$className"/>::removeById(MSW::CConnection &amp;connection, uint32 id)
1819 <xsl:value-of select="$className"/> *object = loadFromCache(id, true);
1820 if (object != NULL)
1822 return object->remove(connection);
1824 // not in cache, run a SQL query
1825 std::string qs;
1826 qs = "DELETE FROM <xsl:value-of select="database/@table"/> ";
1827 <xsl:call-template name="makeWhereClauseWithId">
1828 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1829 <xsl:with-param name="id" select="'id'"/>
1830 </xsl:call-template>
1832 if (connection.query(qs))
1834 if (connection.getAffectedRows() == 1)
1836 // ok, the row is removed
1837 return true;
1841 return false;
1845 // Try to load the specified object from the memory cache, return NULL if the object is not in the cache
1846 <xsl:value-of select="$className"/> *<xsl:value-of select="$className"/>::loadFromCache(uint32 objectId, bool unrelease)
1848 // look in the cache
1849 TObjectCache::iterator it(_ObjectCache.find(objectId));
1850 if (it == _ObjectCache.end())
1852 // not found, return null
1853 return NULL;
1855 else
1857 <xsl:value-of select="$className"/> *object = it->second;
1859 if (object->_ObjectState == NOPE::os_released)
1861 if (unrelease)
1863 // we need to remove this object from the released object set.
1864 object->removeFromReleased();
1865 object->_ObjectState = NOPE::os_clean;
1869 return it->second;
1872 // Receive and execute command from the cache manager.
1873 uint32 <xsl:value-of select="$className"/>::cacheCmd(NOPE::TCacheCmd cmd)
1875 if (cmd == NOPE::cc_update)
1877 updateCache();
1879 else if (cmd == NOPE::cc_clear)
1881 clearCache();
1883 else if (cmd == NOPE::cc_dump)
1885 dump();
1887 else if (cmd == NOPE::cc_instance_count)
1889 return _ObjectCache.size();
1892 // default return value
1893 return 0;
1896 void <xsl:value-of select="$className"/>::dump()
1898 nlinfo(" Cache info for class <xsl:value-of select="$className"/> :");
1899 nlinfo(" There are %u object instances in cache", _ObjectCache.size());
1901 // count the number of object in the released object set
1902 uint32 nbReleased = 0;
1904 TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end());
1905 for (; first != last; ++first)
1907 nbReleased += first->second.size();
1910 nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased);
1913 void <xsl:value-of select="$className"/>::updateCache()
1915 if (_ReleasedObject.empty())
1916 return;
1918 // 30 s hold in cache
1919 const time_t MAX_CACHE_OLD_TIME = 30;
1921 time_t now = NLMISC::CTime::getSecondsSince1970();
1923 // look for object set older than MAX_CACHE_OLD_TIME and delete them
1924 while (!_ReleasedObject.empty() &amp;&amp; _ReleasedObject.begin()-&gt;first &lt; now-MAX_CACHE_OLD_TIME)
1926 TObjectSet &amp;delSet = _ReleasedObject.begin()->second;
1927 // unload this objects
1928 while (!delSet.empty())
1930 <xsl:value-of select="$className"/> *object = *delSet.begin();
1931 delete object;
1934 _ReleasedObject.erase(_ReleasedObject.begin());
1938 void <xsl:value-of select="$className"/>::clearCache()
1940 // remove any unreferenced object from the cache
1941 while (!_ReleasedObject.empty())
1943 TObjectSet &amp;delSet = _ReleasedObject.begin()->second;
1944 // unload this objects
1945 while (!delSet.empty())
1947 <xsl:value-of select="$className"/> *object = *delSet.begin();
1948 delete object;
1951 _ReleasedObject.erase(_ReleasedObject.begin());
1955 void <xsl:value-of select="$className"/>::registerUpdatable()
1957 static bool registered = false;
1958 if (!registered)
1960 NOPE::CPersistentCache::getInstance().registerCache(&amp;<xsl:value-of select="$className"/>::cacheCmd);
1962 registered = true;
1966 // set the pointer on the first pointer of the pointer list (set to null when there is no more pointer)
1967 void <xsl:value-of select="$className"/>::setFirstPtr(<xsl:value-of select="$className"/>Ptr *ptr)
1969 _PtrList = ptr;
1971 if (ptr == NULL)
1973 // this is the last pointer !
1974 if (_ObjectState == NOPE::os_transient
1975 || _ObjectState == NOPE::os_removed)
1977 // not a persistent object, or removed object, just delet it
1978 delete this;
1980 else if (_ObjectState != NOPE::os_removed)
1982 setPersistentState(NOPE::os_released);
1987 // Set the persistent state of the object and do some house keeping
1988 void <xsl:value-of select="$className"/>::setPersistentState(NOPE::TObjectState state)
1990 nlassert(NOPE::AllowedTransition[_ObjectState][state] == true);
1992 if(_ObjectState == NOPE::os_released &amp;&amp; state == NOPE::os_removed)
1994 // a release object gets removed (e.g. by remove by id)
1996 // delete the object
1997 delete this;
1999 // no more to do
2000 return;
2003 if (_ObjectState == NOPE::os_transient &amp;&amp; state != NOPE::os_transient)
2005 nldebug("NOPE: inserting <xsl:value-of select="$className"/> @%p in cache with id %u", this, static_cast&lt;uint32&gt;(_<xsl:value-of select="$uniqueId"/>));
2006 nlverify(_ObjectCache.insert(std::make_pair(_<xsl:value-of select="$uniqueId"/>, this)).second);
2009 if (_ObjectState != NOPE::os_transient)
2010 nlassert(_ObjectCache.find(_<xsl:value-of select="$uniqueId"/>) != _ObjectCache.end());
2012 _ObjectState = state;
2014 if (state == NOPE::os_released)
2016 _ReleaseDate = NLMISC::CTime::getSecondsSince1970();
2017 nlverify(_ReleasedObject[_ReleaseDate].insert(this).second);
2019 else if (state == NOPE::os_removed)
2021 nldebug("NOPE: erasing <xsl:value-of select="$className"/> @%p in cache with id %u", this, static_cast&lt;uint32&gt;(_<xsl:value-of select="$uniqueId"/>));
2022 nlverify(_ObjectCache.erase(_<xsl:value-of select="$uniqueId"/>) == 1);
2027 <xsl:value-of select="$className"/>Ptr <xsl:value-of select="$className"/>::load(MSW::CConnection &amp;connection, uint32 id, const char *filename, uint32 lineNum)
2029 <xsl:value-of select="$className"/> *inCache = loadFromCache(id, true);
2030 if (inCache != NULL)
2032 return <xsl:value-of select="$className"/>Ptr(inCache, filename, lineNum);
2035 std::string qs;
2036 qs = "SELECT ";
2037 <xsl:call-template name="makeColumListWithId"/>
2038 qs += " FROM <xsl:value-of select="database/@table"/>";
2039 <xsl:call-template name="makeWhereClauseWithId">
2040 <xsl:with-param name="uniqueId" select="$uniqueId"/>
2041 <xsl:with-param name="id" select="'id'"/>
2042 </xsl:call-template>
2044 <xsl:value-of select="$className"/>Ptr ret;
2045 if (!connection.query(qs))
2047 return ret;
2050 MSW::CStoreResult *result = connection.storeResult().release();
2052 nlassert(result->getNumRows() &lt;= 1);
2053 if (result->getNumRows() == 1)
2055 ret.assign(new <xsl:value-of select="$className"/>, filename, lineNum);
2056 // ok, we have an object
2057 result->fetchRow();<xsl:text>
2059 </xsl:text> <xsl:for-each select="property[@db_col]">
2060 <xsl:choose>
2061 <xsl:when test="@enum='true' or @enum='smart'">
2062 <xsl:text> {
2063 std::string s;
2064 result->getField(</xsl:text><xsl:value-of select="position()-1"/>, s);
2065 ret->_<xsl:value-of select="@name"/> = <xsl:value-of select="@type"/><xsl:text>(s);
2067 </xsl:text>
2068 </xsl:when>
2069 <xsl:when test="@date='true'">
2070 <xsl:text> result->getDateField(</xsl:text><xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>)<xsl:text>;
2071 </xsl:text>
2072 </xsl:when>
2073 <xsl:when test="@md5='true'">
2074 <xsl:text> result->getMD5Field(</xsl:text><xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>)<xsl:text>;
2075 </xsl:text>
2076 </xsl:when>
2077 <xsl:otherwise>
2078 <xsl:text> result->getField(</xsl:text><xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>)<xsl:text>;
2079 </xsl:text>
2080 </xsl:otherwise>
2081 </xsl:choose>
2082 </xsl:for-each>
2084 ret->setPersistentState(NOPE::os_clean);
2087 delete result;
2089 return ret;
2092 <xsl:for-each select="parent[@relation = 'one-to-many']">
2093 <xsl:choose>
2094 <xsl:when test="@cont='map'">
2095 bool <xsl:value-of select="$className"/>::loadChildrenOf<xsl:value-of select="@class"/>(MSW::CConnection &amp;connection, uint32 parentId, std::map &lt; uint32, <xsl:value-of select="$className"/>Ptr &gt; &amp; container, const char *filename, uint32 lineNum)
2096 </xsl:when>
2097 <xsl:when test="@cont='vector'">
2098 bool <xsl:value-of select="$className"/>::loadChildrenOf<xsl:value-of select="@class"/>(MSW::CConnection &amp;connection, uint32 parentId, std::vector &lt; <xsl:value-of select="$className"/>Ptr &gt; &amp; container, const char *filename, uint32 lineNum)
2099 </xsl:when>
2100 <xsl:otherwise>
2101 <xsl:message terminate="yes">
2102 ERROR : parent/child relation support only 'map' or 'vector' cont specification in <xsl:value-of select="$className"/>, <xsl:value-of select="@class"/> parent definition
2103 </xsl:message>
2104 </xsl:otherwise>
2105 </xsl:choose>
2107 std::string qs;
2108 qs = "SELECT ";
2109 <xsl:for-each select="..">
2110 <xsl:call-template name="makeColumListWithId"/>
2111 </xsl:for-each>
2112 qs += " FROM <xsl:value-of select="../database/@table"/>";
2113 qs += " WHERE <xsl:value-of select="@db_col"/> = '"+NLMISC::toString(parentId)+"'";
2115 if (!connection.query(qs))
2117 return false;
2120 std::auto_ptr&lt;MSW::CStoreResult&gt; result = connection.storeResult();
2122 for (uint i=0; i&lt;result->getNumRows(); ++i)
2124 <xsl:value-of select="$className"/> *ret = new <xsl:value-of select="$className"/>();
2125 // ok, we have an object
2126 result->fetchRow();
2127 <xsl:for-each select="../property[@db_col]">
2128 <xsl:choose>
2129 <xsl:when test="@enum='true' or @enum='smart'">
2131 std::string s;
2132 result->getField(<xsl:value-of select="position()-1"/>, s);
2133 ret->_<xsl:value-of select="@name"/> = <xsl:value-of select="@type"/>(s);
2135 </xsl:when>
2136 <xsl:when test="@date='true'">
2137 result->getDateField(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2138 </xsl:when>
2139 <xsl:when test="@md5='true'">
2140 result->getMD5Field(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2141 </xsl:when>
2142 <xsl:otherwise>
2143 result->getField(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2144 </xsl:otherwise>
2145 </xsl:choose>
2146 </xsl:for-each>
2148 <xsl:value-of select="$className"/> *inCache = loadFromCache(ret->_<xsl:value-of select="$uniqueId"/>, true);
2149 if (inCache != NULL)
2151 <xsl:choose>
2152 <xsl:when test="@cont='map'">
2153 container.insert(std::make_pair(inCache->getObjectId(), <xsl:value-of select="$className"/>Ptr(inCache, filename, lineNum)));
2154 </xsl:when>
2155 <xsl:when test="@cont='vector'">
2156 container.push_back(<xsl:value-of select="$className"/>Ptr(inCache, filename, lineNum));
2157 </xsl:when>
2158 </xsl:choose>
2159 // no more needed
2160 delete ret;
2162 else
2164 ret->setPersistentState(NOPE::os_clean);
2165 <xsl:choose>
2166 <xsl:when test="@cont='map'">
2167 container.insert(std::make_pair(ret->getObjectId(), <xsl:value-of select="$className"/>Ptr(ret, filename, lineNum)));
2168 </xsl:when>
2169 <xsl:when test="@cont='vector'">
2170 container.push_back(<xsl:value-of select="$className"/>Ptr(ret, filename, lineNum));
2171 </xsl:when>
2172 </xsl:choose>
2176 return true;
2178 </xsl:for-each>
2180 <xsl:for-each select="parent[@relation = 'one-to-one']">
2181 <xsl:text> bool </xsl:text><xsl:value-of select="$className"/>::loadChildOf<xsl:value-of select="@class"/>(MSW::CConnection &amp;connection, uint32 parentId, <xsl:value-of select="../@name"/>Ptr &amp;childPtr, const char *filename, uint32 lineNum)
2183 std::string qs;
2184 qs = "SELECT ";
2185 <xsl:for-each select="..">
2186 <xsl:call-template name="makeColumListWithId"/>
2187 </xsl:for-each>
2188 qs += " FROM <xsl:value-of select="../database/@table"/>";
2189 qs += " WHERE <xsl:value-of select="@db_col"/> = '"+NLMISC::toString(parentId)+"'";
2191 <xsl:value-of select="$className"/>Ptr ret;
2192 if (!connection.query(qs))
2194 childPtr = <xsl:value-of select="../@name"/>Ptr();
2195 return false;
2198 std::auto_ptr&lt;MSW::CStoreResult&gt; result = connection.storeResult();
2200 // check that the data description is consistent with database content
2201 nlassert(result->getNumRows() &lt;= 1);
2203 if (result->getNumRows() == 1)
2205 <xsl:value-of select="$className"/> *object = new <xsl:value-of select="$className"/>;
2206 // ok, we have an object
2207 result->fetchRow();
2208 <xsl:for-each select="../property[@db_col]">
2209 <xsl:choose>
2210 <xsl:when test="@enum='true' or @enum='smart'">
2212 std::string s;
2213 result->getField(<xsl:value-of select="position()-1"/>, s);
2214 object->_<xsl:value-of select="@name"/> = <xsl:value-of select="@type"/>(s);
2216 </xsl:when>
2217 <xsl:when test="@date='true'">
2218 result->getDateField(<xsl:value-of select="position()-1"/>, object->_<xsl:value-of select="@name"/>);
2219 </xsl:when>
2220 <xsl:when test="@md5='true'">
2221 result->getMD5Field(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2222 </xsl:when>
2223 <xsl:otherwise>
2224 result->getField(<xsl:value-of select="position()-1"/>, object->_<xsl:value-of select="@name"/>);
2225 </xsl:otherwise>
2226 </xsl:choose>
2227 </xsl:for-each>
2229 <xsl:value-of select="$className"/> *inCache = loadFromCache(object->_<xsl:value-of select="$uniqueId"/>, true);
2230 if (inCache != NULL)
2232 ret.assign(inCache, filename, lineNum);
2233 // no more needed
2234 delete object;
2236 else
2238 object->setPersistentState(NOPE::os_clean);
2239 ret.assign(object, filename, lineNum);
2242 childPtr = ret;
2243 return true;
2246 // no result, but no error
2247 childPtr = <xsl:value-of select="../@name"/>Ptr();
2248 return true;
2250 </xsl:for-each>
2253 <xsl:for-each select="child_class[@relation = 'one-to-many']">
2254 bool <xsl:value-of select="$className"/>::load<xsl:value-of select="@name"/>(MSW::CConnection &amp;connection, const char *filename, uint32 lineNum)
2256 bool ret = true;
2257 if (_<xsl:value-of select="@name"/> != NULL)
2259 // the children are already loaded, just return true
2260 return true;
2263 // allocate the container
2264 <xsl:choose>
2265 <xsl:when test="@cont = 'map'"> _<xsl:value-of select="@name"/> = new std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt;;</xsl:when>
2266 <xsl:when test="@cont = 'vector'"> _<xsl:value-of select="@name"/> = new std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt;;</xsl:when>
2267 </xsl:choose>
2269 // load the childs
2270 ret &amp;= <xsl:value-of select="@type"/>::loadChildrenOf<xsl:value-of select="../@name"/>(connection, getObjectId(), *_<xsl:value-of select="@name"/>, filename, lineNum);
2271 return ret;
2274 <xsl:choose>
2275 <xsl:when test="@cont = 'vector'">
2276 const std::vector&lt;<xsl:value-of select="@type"/>Ptr&gt; &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>() const
2278 nlassert(_<xsl:value-of select="@name"/> != NULL);
2279 return *_<xsl:value-of select="@name"/>;
2282 <xsl:value-of select="@type"/>Ptr &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>ByIndex(uint32 index) const
2284 nlassert(_<xsl:value-of select="@name"/> != NULL);
2285 nlassert(index &lt; _<xsl:value-of select="@name"/>->size());
2286 return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(_<xsl:value-of select="@name"/>->operator[](index));
2289 <xsl:value-of select="@type"/>Ptr &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>ById(uint32 id) const
2291 nlassert(_<xsl:value-of select="@name"/> != NULL);
2292 std::vector&lt;<xsl:value-of select="@type"/>Ptr &gt;::const_iterator first(_<xsl:value-of select="@name"/>->begin()), last(_<xsl:value-of select="@name"/>->end());
2293 for (; first != last; ++first)
2295 const <xsl:value-of select="@type"/>Ptr &amp;child = *first;
2296 if (child->getObjectId() == id)
2298 return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(child);
2302 // no object with this id, return a null pointer
2303 static <xsl:value-of select="@type"/>Ptr nil;
2305 return nil;
2308 </xsl:when>
2309 <xsl:when test="@cont = 'map'">
2310 const std::map&lt;uint32, <xsl:value-of select="@type"/>Ptr&gt; &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>() const
2312 nlassert(_<xsl:value-of select="@name"/> != NULL);
2313 return *_<xsl:value-of select="@name"/>;
2316 <xsl:value-of select="@type"/>Ptr &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>ById(uint32 id) const
2318 nlassert(_<xsl:value-of select="@name"/> != NULL);
2319 std::map&lt;uint32, <xsl:value-of select="@type"/>Ptr&gt;::const_iterator it(_<xsl:value-of select="@name"/>->find(id));
2321 if (it == _<xsl:value-of select="@name"/>->end())
2323 // no object with this id, return a null pointer
2324 static <xsl:value-of select="@type"/>Ptr nil;
2325 return nil;
2328 return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(it->second);
2331 </xsl:when>
2332 <xsl:otherwise>
2333 <xsl:message terminate="yes">
2334 ERROR : Invalide container, child must be either map or vector for child <xsl:value-of select="@name"/> in class <xsl:value-of select="../@name"/><xsl:text>
2335 </xsl:text>
2336 </xsl:message>
2337 </xsl:otherwise>
2338 </xsl:choose>
2341 </xsl:for-each>
2342 <xsl:for-each select="child_class[@relation = 'one-to-one']">
2343 bool <xsl:value-of select="$className"/>::load<xsl:value-of select="@name"/>(MSW::CConnection &amp;connection, const char *filename, uint32 lineNum)
2345 if (_<xsl:value-of select="@name"/>Loaded)
2347 // the child is already loaded, just return true
2348 return true;
2350 bool ret = <xsl:value-of select="@type"/>::loadChildOf<xsl:value-of select="../@name"/>(connection, getObjectId(), _<xsl:value-of select="@name"/>, filename, lineNum);
2351 _<xsl:value-of select="@name"/>Loaded = true;
2352 return ret;
2355 /** Return the one child object (or null if not) */
2356 <xsl:value-of select="@type"/>Ptr <xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>()
2358 nlassert(_<xsl:value-of select="@name"/>Loaded);
2359 return _<xsl:value-of select="@name"/>;
2362 </xsl:for-each>
2363 </xsl:if>
2364 </xsl:template>
2368 <!-- ################################################################# -->
2369 <!-- ##### C++ Layer 3 interface generation (server mode) ### -->
2370 <!-- ################################################################# -->
2371 <!-- ##### header file #### -->
2372 <xsl:template match="callback_interface" mode="header">
2373 <xsl:call-template name="makeMasterDoc"/>
2374 <xsl:choose>
2375 <xsl:when test="@extend">
2376 class <xsl:value-of select="@name"/>Itf : public <xsl:value-of select="@extend"/>Itf
2377 </xsl:when>
2378 <xsl:otherwise>
2379 class <xsl:value-of select="@name"/>Itf <!--: public NLNET::CCallbackServer-->
2380 </xsl:otherwise>
2381 </xsl:choose>
2383 protected:
2384 <xsl:if test="not(@extend)">
2385 /// the callback server adaptor
2386 std::auto_ptr&lt;ICallbackServerAdaptor&gt; _CallbackServer;
2387 </xsl:if>
2388 void getCallbakArray(NLNET::TCallbackItem *&amp;arrayPtr, uint32 &amp;arraySize)
2390 static NLNET::TCallbackItem callbackArray[] =
2392 <xsl:for-each select="invoke"> { "<xsl:value-of select="@msg"/>", <xsl:value-of select="../@name"/>Itf::cb_<xsl:value-of select="@name"/> },
2393 </xsl:for-each>
2396 arrayPtr = callbackArray;
2397 arraySize = sizeofarray(callbackArray);
2400 static void _cbConnection(NLNET::TSockId from, void *arg)
2402 H_AUTO(<xsl:value-of select="@name"/>__cbConnection);
2403 <xsl:value-of select="@name"/>Itf *_this = reinterpret_cast&lt;<xsl:value-of select="@name"/>Itf *&gt;(arg);
2405 _this->on_<xsl:value-of select="@name"/>_Connection(from);
2408 static void _cbDisconnection(NLNET::TSockId from, void *arg)
2410 H_AUTO(<xsl:value-of select="@name"/>__cbDisconnection);
2411 <xsl:value-of select="@name"/>Itf *_this = reinterpret_cast&lt;<xsl:value-of select="@name"/>Itf *&gt;(arg);
2413 _this->on_<xsl:value-of select="@name"/>_Disconnection(from);
2417 public:
2418 /** Constructor, if you specify a replacement adaptor, then the object
2419 * become owner of the adaptor (and it will be released with the
2420 * interface).
2422 <xsl:if test="@extend">
2423 <xsl:text> </xsl:text><xsl:value-of select="@name"/>Itf(ICallbackServerAdaptor *replacementAdaptor = NULL)
2424 : <xsl:value-of select="@extend"/>Itf(replacementAdaptor)
2426 </xsl:if>
2427 <xsl:if test="not(@extend)">
2428 <xsl:text> </xsl:text><xsl:value-of select="@name"/>Itf(ICallbackServerAdaptor *replacementAdaptor = NULL)
2430 if (replacementAdaptor == NULL)
2432 // use default callback server
2433 _CallbackServer = std::auto_ptr&lt;ICallbackServerAdaptor&gt;(new CNelCallbackServerAdaptor(this));
2435 else
2437 // use the replacement one
2438 _CallbackServer = std::auto_ptr&lt;ICallbackServerAdaptor&gt;(replacementAdaptor);
2441 </xsl:if>
2442 virtual ~<xsl:value-of select="@name"/>Itf()
2446 /// Open the interface socket in the specified port
2447 void openItf(uint16 port)
2449 NLNET::TCallbackItem *arrayPtr;
2450 uint32 arraySize;
2452 <xsl:if test="@extend">
2453 // add callback array of the base interface class
2454 <xsl:value-of select="@extend"/>Itf::getCallbakArray(arrayPtr, arraySize);
2455 _CallbackServer->addCallbackArray(arrayPtr, arraySize);
2456 </xsl:if>
2458 getCallbakArray(arrayPtr, arraySize);
2459 _CallbackServer->addCallbackArray(arrayPtr, arraySize);
2461 _CallbackServer->setConnectionCallback (_cbConnection, this);
2462 _CallbackServer->setDisconnectionCallback (_cbDisconnection, this);
2464 _CallbackServer->init(port);
2467 /** Must be called evenly, update the network subclass to receive message
2468 * and dispatch method invokation.
2470 void update()
2472 H_AUTO(<xsl:value-of select="@name"/>_update);
2476 _CallbackServer->update();
2478 catch (...)
2480 nlwarning("<xsl:value-of select="@name"/> : Exception launch in callback server update");
2484 <xsl:for-each select="return">
2485 <xsl:call-template name="makeMethodDoc"/>
2486 void <xsl:value-of select="@name"/>(NLNET::TSockId dest<xsl:call-template name="makeParamList"/>)
2488 H_AUTO(<xsl:value-of select="@name"/>_<xsl:value-of select="@name"/>);
2489 #ifdef NL_DEBUG
2490 nldebug("<xsl:value-of select="../@name"/>::<xsl:value-of select="@name"/> called");
2491 #endif
2492 NLNET::CMessage message("<xsl:value-of select="@msg"/>");
2493 <xsl:for-each select="param">
2494 <xsl:call-template name="serialWrite"/>
2495 </xsl:for-each>
2496 _CallbackServer->send(message, dest);
2498 </xsl:for-each>
2500 <xsl:for-each select="invoke">
2501 static void cb_<xsl:value-of select="@name"/> (NLNET::CMessage &amp;message, NLNET::TSockId from, NLNET::CCallbackNetBase &amp;netbase)
2503 H_AUTO(<xsl:value-of select="@name"/>_on_<xsl:value-of select="@name"/>);
2504 #ifdef NL_DEBUG
2505 nldebug("<xsl:value-of select="../@name"/>::cb_<xsl:value-of select="@name"/> received from class '%s'", typeid(netbase).name());
2506 #endif
2507 ICallbackServerAdaptor *adaptor = static_cast&lt; ICallbackServerAdaptor *&gt;(netbase.getUserData());
2509 <xsl:value-of select="../@name"/>Itf *callback = (<xsl:value-of select="../@name"/>Itf *)adaptor->getContainerClass();
2511 if (callback == NULL)
2512 return;
2513 <xsl:for-each select="param">
2514 <xsl:if test="not(@array)">
2515 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
2516 </xsl:text>
2517 </xsl:if>
2518 <xsl:if test="@array = 'true'">
2519 <xsl:text> </xsl:text>std::vector&lt;<xsl:value-of select="@type"/>&gt;<xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
2520 </xsl:text>
2521 </xsl:if>
2522 </xsl:for-each>
2523 <xsl:for-each select="param">
2524 <xsl:call-template name="serialRead"/>
2525 </xsl:for-each>
2527 #ifdef NL_DEBUG
2528 nldebug("<xsl:value-of select="../@name"/>::cb_<xsl:value-of select="@name"/> : calling on_<xsl:value-of select="@name"/>");
2529 #endif
2531 <xsl:if test="not(return)">
2532 callback->on_<xsl:value-of select="@name"/>(from<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
2533 </xsl:if>
2534 <xsl:if test="return">
2535 <xsl:if test="not(return/@array)">
2536 <xsl:text> </xsl:text><xsl:value-of select="return/@type"/> retValue;
2537 </xsl:if>
2538 <xsl:if test="return/@array">
2539 <xsl:text> std::vector&lt;</xsl:text><xsl:value-of select="return/@type"/>&gt; retValue;
2540 </xsl:if>
2541 retValue = callback->on_<xsl:value-of select="@name"/>(from<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
2543 NLNET::CMessage retMsg("R_<xsl:value-of select="@msg"/>");
2544 <xsl:if test="not(return/@array)">
2545 nlWrite(retMsg, serial<xsl:value-of select="return/@serial"/>, retValue);
2546 </xsl:if>
2547 <xsl:if test="return/@array">
2548 nlWrite(retMsg, serialCont, retValue);
2549 </xsl:if>
2551 callback->_CallbackServer->send(retMsg, from);
2552 </xsl:if>
2554 </xsl:for-each>
2556 /// Connection callback : a new interface client connect
2557 virtual void on_<xsl:value-of select="@name"/>_Connection(NLNET::TSockId from) =0;
2558 /// Disconnection callback : one of the interface client disconnect
2559 virtual void on_<xsl:value-of select="@name"/>_Disconnection(NLNET::TSockId from) =0;
2561 <xsl:for-each select="invoke"><xsl:text>
2562 </xsl:text><xsl:call-template name="makeMethodDoc"/>
2563 <xsl:if test="not(return)">
2564 <xsl:text> virtual void on_</xsl:text><xsl:value-of select="@name"/>(NLNET::TSockId from<xsl:call-template name="makeParamList"/>) =0;
2565 </xsl:if>
2566 <xsl:if test="return">
2567 <xsl:if test="not(return/@array)">
2568 <xsl:text> virtual </xsl:text><xsl:value-of select="return/@type"/> on_<xsl:value-of select="@name"/>(NLNET::TSockId from<xsl:call-template name="makeParamList"/>) =0;
2569 </xsl:if>
2570 <xsl:if test="return/@array">
2571 <xsl:text> virtual std::vector&lt;</xsl:text><xsl:value-of select="return/@type"/>&gt; on_<xsl:value-of select="@name"/>(NLNET::TSockId from<xsl:call-template name="makeParamList"/>) =0;
2572 </xsl:if>
2573 </xsl:if>
2574 </xsl:for-each>
2577 <!-- Callback interface client class -->
2578 <xsl:call-template name="makeMasterDoc"/>
2579 /** This is the client side of the interface
2580 * Derive from this class to invoke method on the callback server
2582 <xsl:choose>
2583 <xsl:when test="@extend">
2584 class <xsl:value-of select="@name"/>ClientItf : public <xsl:value-of select="@extend"/>ClientItf
2585 </xsl:when>
2586 <xsl:otherwise>
2587 class <xsl:value-of select="@name"/>ClientItf <!--: public NLNET::CCallbackClient-->
2588 </xsl:otherwise>
2589 </xsl:choose>
2591 protected:
2592 <xsl:if test="not(@extend)">
2593 /// the callback client adaptor
2594 std::auto_ptr &lt; ICallbackClientAdaptor &gt; _CallbackClient;
2595 </xsl:if>
2597 void getCallbakArray(NLNET::TCallbackItem *&amp;arrayPtr, uint32 &amp;arraySize)
2599 <xsl:if test="not(return)">
2600 arrayPtr = NULL;
2601 arraySize = 0;
2602 </xsl:if>
2604 <xsl:if test="return">
2605 static NLNET::TCallbackItem callbackArray[] =
2607 <xsl:for-each select="return"> { "<xsl:value-of select="@msg"/>", <xsl:value-of select="../@name"/>ClientItf::cb_<xsl:value-of select="@name"/> },
2608 </xsl:for-each>
2611 arrayPtr = callbackArray;
2612 arraySize = sizeofarray(callbackArray);
2613 </xsl:if>
2616 static void _cbDisconnection(NLNET::TSockId from, void *arg)
2618 <xsl:value-of select="@name"/>ClientItf *_this = reinterpret_cast&lt;<xsl:value-of select="@name"/>ClientItf *&gt;(arg);
2620 _this->on_<xsl:value-of select="@name"/>Client_Disconnection(from);
2624 public:
2625 /// Retreive the message name for a given callback name
2626 static const std::string &amp;getMessageName(const std::string &amp;methodName)
2628 static std::map&lt;std::string, std::string&gt; messageNames;
2629 static bool initialized = false;
2630 if (!initialized)
2632 <xsl:for-each select="return"> messageNames.insert(std::make_pair(std::string("on_<xsl:value-of select="@name"/>"), std::string("<xsl:value-of select="@msg"/>")));
2633 </xsl:for-each>
2634 initialized = true;
2637 std::map &lt; std::string, std::string&gt;::const_iterator it(messageNames.find(methodName));
2638 if (it != messageNames.end())
2639 return it->second;
2641 <xsl:if test="@extend">
2642 // try with the base class
2643 return <xsl:value-of select="@extend"/>ClientItf::getMessageName(methodName);
2644 </xsl:if>
2645 <xsl:if test="not(@extend)">
2646 static std::string emptyString;
2648 return emptyString;
2649 </xsl:if>
2652 <xsl:if test="@extend">
2653 <xsl:text> </xsl:text><xsl:value-of select="@name"/>ClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL)
2654 : <xsl:value-of select="@extend"/>ClientItf(adaptorReplacement)
2656 </xsl:if>
2657 <xsl:if test="not(@extend)">
2658 <xsl:text> </xsl:text><xsl:value-of select="@name"/>ClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL)
2660 if (adaptorReplacement == NULL)
2662 // use the default Nel adaptor
2663 _CallbackClient = std::auto_ptr &lt; ICallbackClientAdaptor &gt;(new CNelCallbackClientAdaptor(this));
2665 else
2667 // use the replacement one
2668 _CallbackClient = std::auto_ptr &lt; ICallbackClientAdaptor &gt;(adaptorReplacement);
2671 </xsl:if>
2672 /// Connect the interface client to the callback server at the specified address and port
2673 virtual void connectItf(NLNET::CInetAddress address)
2675 NLNET::TCallbackItem *arrayPtr;
2676 uint32 arraySize;
2678 static bool callbackAdded = false;
2679 if (!callbackAdded)
2681 <xsl:if test="@extend">
2682 // add callback array of the base interface class
2683 <xsl:value-of select="@extend"/>ClientItf::getCallbakArray(arrayPtr, arraySize);
2684 _CallbackClient->addCallbackArray(arrayPtr, arraySize);
2685 callbackAdded = true;
2686 // add callback array of this interface
2687 </xsl:if>
2688 getCallbakArray(arrayPtr, arraySize);
2689 _CallbackClient->addCallbackArray(arrayPtr, arraySize);
2692 _CallbackClient->setDisconnectionCallback (_cbDisconnection, this);
2694 _CallbackClient->connect(address);
2697 /** Must be called evenly, update the network subclass to receive message
2698 * and dispatch invokation returns.
2700 virtual void update()
2702 H_AUTO(<xsl:value-of select="@name"/>_update);
2706 _CallbackClient->update();
2708 catch (...)
2710 nlwarning("<xsl:value-of select="@name"/> : Exception launch in callback client update");
2714 <xsl:for-each select="invoke">
2715 <xsl:call-template name="makeMethodDoc"/>
2716 void <xsl:value-of select="@name"/>(<xsl:call-template name="makeParamListNoStartingComma"/>)
2718 #ifdef NL_DEBUG
2719 nldebug("<xsl:value-of select="../@name"/>Client::<xsl:value-of select="@name"/> called");
2720 #endif
2721 NLNET::CMessage message("<xsl:value-of select="@msg"/>");
2722 <xsl:for-each select="param">
2723 <xsl:call-template name="serialWrite"/>
2724 </xsl:for-each>
2725 _CallbackClient->send(message);
2727 </xsl:for-each>
2729 <xsl:for-each select="return">
2730 static void cb_<xsl:value-of select="@name"/> (NLNET::CMessage &amp;message, NLNET::TSockId from, NLNET::CCallbackNetBase &amp;netbase)
2732 #ifdef NL_DEBUG
2733 nldebug("<xsl:value-of select="../@name"/>Client::cb_<xsl:value-of select="@name"/> received from class '%s'", typeid(netbase).name());
2734 #endif
2735 ICallbackClientAdaptor *adaptor = static_cast&lt; ICallbackClientAdaptor *&gt;(netbase.getUserData());
2737 <xsl:value-of select="../@name"/>ClientItf *callback = (<xsl:value-of select="../@name"/>ClientItf *)adaptor->getContainerClass();
2739 if (callback == NULL)
2740 return;
2741 <xsl:for-each select="param">
2743 <xsl:if test="not(@array)">
2744 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
2745 </xsl:text>
2746 </xsl:if>
2748 <xsl:if test="@array = 'true'">
2749 <xsl:text> </xsl:text>std::vector&lt;<xsl:value-of select="@type"/>&gt; <xsl:value-of select="@name"/>;<xsl:text>
2750 </xsl:text>
2751 </xsl:if>
2753 </xsl:for-each>
2754 <xsl:for-each select="param">
2755 <xsl:call-template name="serialRead"/>
2756 </xsl:for-each>
2758 #ifdef NL_DEBUG
2759 nldebug("<xsl:value-of select="../@name"/>Client::cb_<xsl:value-of select="@name"/> : calling on_<xsl:value-of select="@name"/>");
2760 #endif
2762 callback->on_<xsl:value-of select="@name"/>(from<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
2764 </xsl:for-each>
2766 /// Disconnection callback : the connection to the server is lost
2767 virtual void on_<xsl:value-of select="@name"/>Client_Disconnection(NLNET::TSockId from) =0;
2769 <xsl:for-each select="return"><xsl:text>
2770 </xsl:text><xsl:call-template name="makeMethodDoc"/>
2771 <xsl:text> virtual void on_</xsl:text><xsl:value-of select="@name"/>(NLNET::TSockId from<xsl:call-template name="makeParamList"/>) =0;
2772 </xsl:for-each>
2774 </xsl:template>
2777 <!-- ######################################################### -->
2778 <!-- ##### PHP Layer 3 interface generation ### -->
2779 <!-- ######################################################### -->
2780 <!-- ##### php file #### -->
2781 <xsl:template match="callback_interface[@caller = 'php']" mode="php">
2782 <xsl:if test=".//param[@type != 'uint32'
2783 and @type != 'uint8'
2784 and @type != 'std::string'
2785 and @enum != 'smart']">
2786 <xsl:message terminate="yes">
2787 ERROR : PHP interface only support uint8, uint32, enum and std::string parameter in callback interface '<xsl:value-of select="@name"/>.<xsl:value-of select=".//param[@type != 'uint32' and @type != 'uint8' and @type != 'std::string']/../@name"/>'
2788 </xsl:message>
2789 </xsl:if>
2790 <xsl:text>&lt;?php
2791 /////////////////////////////////////////////////////////////////
2792 // WARNING : this is a generated file, don't change it !
2793 /////////////////////////////////////////////////////////////////
2795 require_once('../tools/nel_message.php');
2797 class </xsl:text><xsl:value-of select="@name"/> extends CCallbackClient
2799 <xsl:for-each select="invoke">
2800 function <xsl:value-of select="@name"/>(<xsl:call-template name="makePhpArgListNoFollow"/>)
2802 $msg = new CMessage;
2803 $msg->setName("<xsl:value-of select="@msg"/>");
2806 <xsl:for-each select="param">
2808 <xsl:choose>
2809 <xsl:when test="@php_serial">
2810 <xsl:call-template name="makeWriteSerial">
2811 <xsl:with-param name="msgName" select="'$msg'"/>
2812 <xsl:with-param name="varName" select="@name"/>
2813 <xsl:with-param name="serialName" select="concat('serial', @php_serial)"/>
2814 </xsl:call-template>
2815 </xsl:when>
2816 <xsl:when test="@enum">
2817 <xsl:call-template name="makeWriteSerial">
2818 <xsl:with-param name="msgName" select="'$msg'"/>
2819 <xsl:with-param name="varName" select="@name"/>
2820 <xsl:with-param name="serialName" select="'serialEnum'"/>
2821 </xsl:call-template>
2822 </xsl:when>
2823 <xsl:otherwise>
2824 <xsl:call-template name="makeWriteSerial">
2825 <xsl:with-param name="msgName" select="'$msg'"/>
2826 <xsl:with-param name="varName" select="@name"/>
2827 <xsl:with-param name="serialName" select="'serialUint32'"/>
2828 </xsl:call-template>
2829 </xsl:otherwise>
2830 </xsl:choose>
2831 </xsl:for-each>
2833 <xsl:if test="not(return)">
2834 return parent::sendMessage($msg);
2835 </xsl:if>
2836 <xsl:if test="return">
2837 <!-- this is a two way call -->
2838 $ret = "";
2839 $ret = parent::sendMessage($msg);
2840 if ($ret == false)
2842 // error during send
2843 $this->invokeError("<xsl:value-of select="@name"/>", "Error in 'sendMessage'");
2844 return false;
2847 $retMsg = parent::waitMessage();
2848 if ($ret == false)
2850 // error during send
2851 $this->invokeError("<xsl:value-of select="@name"/>", "Error in 'waitMessage'");
2852 return false;
2854 if (!($retMsg->MsgName === "R_<xsl:value-of select="@msg"/>"))
2856 // error during send
2857 $this->invokeError("<xsl:value-of select="@name"/>", "Invalid response, awaited 'R_<xsl:value-of select="@msg"/>', received '".$retMsg->MsgName."'");
2858 return false;
2861 // serial the return value
2862 <xsl:choose>
2863 <xsl:when test="return/@php_serial">
2864 <xsl:call-template name="makeReadSerial">
2865 <xsl:with-param name="paramNode" select="return"/>
2866 <xsl:with-param name="msgName" select="'$retMsg'"/>
2867 <xsl:with-param name="varName" select="'retValue'"/>
2868 <xsl:with-param name="serialName" select="concat('serial', return/@php_serial)"/>
2869 </xsl:call-template>
2870 </xsl:when>
2871 <xsl:when test="return/@enum">
2872 $<xsl:value-of select="@varName"/> = new <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@type"/>;
2873 <xsl:call-template name="makeReadSerial">
2874 <xsl:with-param name="paramNode" select="return"/>
2875 <xsl:with-param name="return"/>
2876 <xsl:with-param name="msgName" select="'$retMsg'"/>
2877 <xsl:with-param name="varName" select="'retValue'"/>
2878 <xsl:with-param name="serialName" select="'serialEnum'"/>
2879 </xsl:call-template>
2880 </xsl:when>
2881 <xsl:otherwise>
2882 <xsl:call-template name="makeReadSerial">
2883 <xsl:with-param name="paramNode" select="return"/>
2884 <xsl:with-param name="return"/>
2885 <xsl:with-param name="msgName" select="'$retMsg'"/>
2886 <xsl:with-param name="varName" select="'retValue'"/>
2887 <xsl:with-param name="serialName" select="'serialUint32'"/>
2888 </xsl:call-template>
2889 </xsl:otherwise>
2890 </xsl:choose>
2892 // return the return value
2893 return $retValue;
2894 </xsl:if>
2897 </xsl:for-each>
2899 function waitCallback()
2901 $message = parent::waitMessage();
2903 if ($message == false)
2904 return false;
2906 switch($message->MsgName)
2908 <xsl:for-each select="return"> case "<xsl:value-of select="@msg"/>":
2909 $this-><xsl:value-of select="@name"/>_skel($message);
2910 break;
2911 </xsl:for-each> default:
2912 return false;
2915 return true;
2918 <xsl:for-each select="return">
2919 function <xsl:value-of select="@name"/>_skel(&amp;$message)
2921 <xsl:for-each select="param">
2922 <xsl:text> </xsl:text>
2923 <xsl:choose>
2924 <xsl:when test="@php_serial">
2925 <xsl:call-template name="makeReadSerial">
2926 <xsl:with-param name="paramNode" select="."/>
2927 <xsl:with-param name="msgName" select=" '$message'"/>
2928 <xsl:with-param name="varName" select="@name"/>
2929 <xsl:with-param name="serialName" select="concat('serial', @php_serial)"/>
2930 </xsl:call-template>
2931 </xsl:when>
2932 <xsl:when test="@enum">
2933 $<xsl:value-of select="@name"/> = new <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@type"/>;
2934 <xsl:call-template name="makeReadSerial">
2935 <xsl:with-param name="paramNode" select="."/>
2936 <xsl:with-param name="msgName" select=" '$message'"/>
2937 <xsl:with-param name="varName" select="@name"/>
2938 <xsl:with-param name="serialName" select="'serialEnum'"/>
2939 </xsl:call-template>
2940 </xsl:when>
2941 <xsl:otherwise>
2942 <xsl:call-template name="makeReadSerial">
2943 <xsl:with-param name="paramNode" select="."/>
2944 <xsl:with-param name="msgName" select=" '$message'"/>
2945 <xsl:with-param name="varName" select="@name"/>
2946 <xsl:with-param name="serialName" select="'serialUint32'"/>
2947 </xsl:call-template>
2948 </xsl:otherwise>
2949 </xsl:choose>
2950 </xsl:for-each>
2951 <xsl:text>
2952 $this-&gt;</xsl:text><xsl:value-of select="@name"/>(<xsl:call-template name="makePhpArgListNoFollow"/>);
2954 </xsl:for-each>
2956 /////////////////////////////////////////////////////////////////
2957 // Copy paste this part of code in your derived class
2958 // and implement code to ract to incoming message
2959 /////////////////////////////////////////////////////////////////
2960 <xsl:for-each select="return">
2961 <xsl:call-template name="makeMethodDoc"/>
2962 function <xsl:value-of select="@name"/>(<xsl:call-template name="makePhpArgListNoFollow"/>)
2966 </xsl:for-each> }
2967 <xsl:text>?&gt;
2968 </xsl:text>
2969 </xsl:template>
2972 <!-- ######################################### -->
2973 <!-- ##### PHP Read serialisation code ###### -->
2974 <!-- ######################################### -->
2976 <xsl:template name="makeReadSerial">
2977 <xsl:param name="paramNode"/>
2978 <xsl:param name="msgName"/>
2979 <xsl:param name="varName"/>
2980 <xsl:param name="serialName"/>
2983 <xsl:choose>
2984 <xsl:when test="$paramNode/@array"> $nbElem = 0;
2985 <xsl:value-of select="$msgName"/>->serialUInt32($nbElem);
2986 $<xsl:value-of select="$varName"/> = array();
2987 for ($i=0; $i&lt;$nbElem;$i++)
2989 <xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($item);
2990 $<xsl:value-of select="$varName"/>[] = $item;
2992 </xsl:when>
2993 <xsl:otherwise> <xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($<xsl:value-of select="$varName"/>);
2994 </xsl:otherwise>
2995 </xsl:choose>
2997 </xsl:template>
2999 <!-- ######################################### -->
3000 <!-- ##### PHP Write serialisation code ###### -->
3001 <!-- ######################################### -->
3003 <xsl:template name="makeWriteSerial">
3004 <xsl:param name="msgName"/>
3005 <xsl:param name="varName"/>
3006 <xsl:param name="serialName"/>
3008 <xsl:choose>
3009 <xsl:when test="@array"><xsl:text> </xsl:text><xsl:value-of select="$msgName"/>->serialUint32(count($<xsl:value-of select="@name"/>));
3010 foreach($<xsl:value-of select="$varName"/> as $key=>$value)
3011 <xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($value);
3012 </xsl:when>
3013 <xsl:otherwise><xsl:text> </xsl:text><xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($<xsl:value-of select="$varName"/>);
3014 </xsl:otherwise>
3015 </xsl:choose>
3016 </xsl:template>
3019 <!-- ######################################### -->
3020 <!-- ##### Make a php parameter list ###### -->
3021 <!-- ######################################### -->
3022 <xsl:template name="makePhpArgList">
3023 <xsl:for-each select="param">$<xsl:value-of select="@name"/>, </xsl:for-each>
3024 </xsl:template>
3026 <xsl:template name="makePhpArgListNoFollow">
3027 <xsl:for-each select="param">$<xsl:value-of select="@name"/><xsl:if test="position() != last()">, </xsl:if></xsl:for-each>
3028 </xsl:template>
3030 <!-- ################################################### -->
3031 <!-- ##### Generate a cpp non template smart ptr ###### -->
3032 <!-- ################################################### -->
3034 <xsl:template name="makePersistentPtrHeader">
3035 <xsl:param name="className"/>
3037 <xsl:variable name="ptrName" select="concat($className, 'Ptr')"/>
3040 class <xsl:value-of select="$ptrName"/>
3042 friend class <xsl:value-of select="$className"/>;
3044 const char *_FileName;
3045 uint32 _LineNum;
3047 // linked list of smart ptr
3048 <xsl:value-of select="$ptrName"/> *_NextPtr;
3049 <xsl:value-of select="$ptrName"/> *_PrevPtr;
3051 <xsl:value-of select="$className"/> *_Ptr;
3053 void linkPtr();
3055 void unlinkPtr();
3057 public:
3058 <xsl:value-of select="$ptrName"/>()
3059 : _FileName(NULL),
3060 _LineNum(0),
3061 _Ptr(NULL),
3062 _NextPtr(NULL),
3063 _PrevPtr(NULL)
3067 <xsl:value-of select="$ptrName"/>(const <xsl:value-of select="$ptrName"/> &amp;other, const char *filename, uint32 lineNum)
3068 : _FileName(filename),
3069 _LineNum(lineNum),
3070 _NextPtr(NULL),
3071 _PrevPtr(NULL)
3073 // point the same object
3074 _Ptr = other._Ptr;
3075 // insert the pointer in the list
3076 linkPtr();
3079 <xsl:value-of select="$ptrName"/>(const <xsl:value-of select="$ptrName"/> &amp;other)
3080 : _FileName(other._FileName),
3081 _LineNum(other._LineNum),
3082 _NextPtr(NULL),
3083 _PrevPtr(NULL)
3085 // point the same object
3086 _Ptr = other._Ptr;
3087 // insert the pointer in the list
3088 linkPtr();
3091 <xsl:value-of select="$ptrName"/>(<xsl:value-of select="$className"/> *objectPtr, const char *filename, uint32 lineNum)
3092 : _FileName(filename),
3093 _LineNum(lineNum),
3094 _NextPtr(NULL),
3095 _PrevPtr(NULL)
3097 _Ptr = objectPtr;
3099 linkPtr();
3102 <xsl:value-of select="$ptrName"/> &amp;assign(const <xsl:value-of select="$ptrName"/> &amp;other, const char *filename, uint32 lineNum)
3104 _FileName = filename;
3105 _LineNum = lineNum;
3107 unlinkPtr();
3108 _Ptr = other._Ptr;
3109 linkPtr();
3111 return *this;
3114 ~<xsl:value-of select="$ptrName"/>()
3116 unlinkPtr();
3119 <xsl:value-of select="$ptrName"/> &amp;assign(<xsl:value-of select="$className"/> *objectPtr, const char *filename, uint32 lineNum)
3121 _FileName = filename;
3122 _LineNum = lineNum;
3124 unlinkPtr();
3125 _Ptr = objectPtr;
3126 linkPtr();
3128 return *this;
3131 <xsl:value-of select="$ptrName"/> &amp;operator =(const <xsl:value-of select="$ptrName"/> &amp;other)
3133 return assign(other, __FILE__, __LINE__);
3136 <xsl:value-of select="$className"/> *operator ->()
3138 return _Ptr;
3140 const <xsl:value-of select="$className"/> *operator ->() const
3142 return _Ptr;
3145 bool operator == (const <xsl:value-of select="$ptrName"/> &amp;other) const
3147 return _Ptr == other._Ptr;
3149 bool operator != (const <xsl:value-of select="$ptrName"/> &amp;other) const
3151 return !operator ==(other);
3154 bool operator == (const <xsl:value-of select="$className"/> *object) const
3156 return _Ptr == object;
3158 bool operator != (const <xsl:value-of select="$className"/> *object) const
3160 return !operator ==(object);
3163 /// Less then comparator : comparison on pointer object address
3164 bool operator &lt; (const <xsl:value-of select="$ptrName"/> &amp;other) const
3166 return _Ptr &lt; other._Ptr;
3169 /// Used to walk thrue the linked list of pointer
3170 <xsl:value-of select="$ptrName"/> *getNextPtr()
3172 return _NextPtr;
3176 </xsl:template>
3178 <xsl:template name="makePersistentPtrCpp">
3179 <xsl:param name="className"/>
3180 <xsl:variable name="ptrName" select="concat($className, 'Ptr')"/>
3181 void <xsl:value-of select="$ptrName"/>::linkPtr()
3183 nlassert(_NextPtr == NULL);
3184 nlassert(_PrevPtr == NULL);
3185 if (_Ptr != NULL)
3187 _NextPtr = _Ptr->getFirstPtr();
3188 if (_NextPtr != NULL)
3190 _PrevPtr = _NextPtr->_PrevPtr;
3191 _PrevPtr->_NextPtr = this;
3192 _NextPtr->_PrevPtr = this;
3194 else
3196 _NextPtr = this;
3197 _PrevPtr = this;
3198 _Ptr->setFirstPtr(this);
3203 void <xsl:value-of select="$ptrName"/>::unlinkPtr()
3205 if (_NextPtr == NULL)
3207 nlassert(_PrevPtr == NULL);
3208 return;
3211 if (_Ptr != NULL)
3213 if (_NextPtr == this)
3215 nlassert(_PrevPtr == this);
3216 // last pointer !
3217 _Ptr->setFirstPtr(NULL);
3219 else
3221 if (_Ptr->getFirstPtr() == this)
3223 // the first ptr is the current one, we need to switch to next one
3224 _Ptr->setFirstPtr(_NextPtr);
3229 if (_NextPtr != this)
3231 nlassert(_PrevPtr != this);
3233 _NextPtr->_PrevPtr = _PrevPtr;
3234 _PrevPtr->_NextPtr = _NextPtr;
3236 _NextPtr = NULL;
3237 _PrevPtr = NULL;
3239 </xsl:template>
3240 </xsl:stylesheet>