Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / ryzom / common / src / game_share / generate_module_interface.xslt
blob94750a59ea62875786cae1011b38283ce73446b6
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'">// Ryzom - MMORPG Framework &lt;http://dev.ryzom.com/projects/ryzom/&gt;
23 // Copyright (C) 2010-2021 Winch Gate Property Limited
25 // This program is free software: you can redistribute it and/or modify
26 // it under the terms of the GNU Affero General Public License as
27 // published by the Free Software Foundation, either version 3 of the
28 // License, or (at your option) any later version.
30 // This program is distributed in the hope that it will be useful,
31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 // GNU Affero General Public License for more details.
35 // You should have received a copy of the GNU Affero General Public License
36 // along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
38 /////////////////////////////////////////////////////////////////
39 // WARNING : this is a generated file, don't change it !
40 /////////////////////////////////////////////////////////////////
41 </xsl:if>
42 <xsl:if test="$output = 'header'">
43 #ifndef <xsl:value-of select="@header_tag"/>
44 #define <xsl:value-of select="@header_tag"/>
45 #include "nel/misc/types_nl.h"
46 #include &lt;memory&gt;
47 #include "nel/misc/hierarchical_timer.h"
48 #include "nel/misc/string_conversion.h"
49 #include "nel/net/message.h"
50 #include "nel/net/module.h"
51 #include "nel/net/module_builder_parts.h"
52 #include "nel/net/module_message.h"
53 #include "nel/net/module_gateway.h"
54 <xsl:if test="//callback_interface">
55 <!--#include "nel/net/callback_server.h"
56 #include "nel/net/callback_client.h"-->
57 #include "game_share/callback_adaptor.h"
58 </xsl:if>
59 <xsl:if test="//class/database">
60 #include "nel/misc/string_common.h"
61 #include "server_share/mysql_wrapper.h"
62 </xsl:if>
63 <xsl:if test="//class/message">
64 #include "game_share/synchronised_message.h"
65 </xsl:if>
66 </xsl:if>
67 <!--<xsl:if test="$output = 'cpp'">
68 <xsl:apply-templates select="cpp-include"/>
69 #include "<xsl:value-of select="$filename"/>.h"
70 </xsl:if>-->
71 <xsl:call-template name="myApplyTemplate"/>
72 <xsl:if test="$output = 'header'">
73 #endif
74 </xsl:if>
75 </xsl:template>
77 <!-- ######################################################### -->
78 <!-- ##### Namespace specification ####### -->
79 <!-- ######################################################### -->
80 <xsl:template match="namespace" mode="header">
81 <!--#ifndef NLNET_INTERFACE_GET_MODULE
82 # define NLNET_INTERFACE_GET_MODULE NLNET::IModule *getModuleInstance() { return this; }
83 #endif
84 -->
85 namespace <xsl:value-of select="@name"/>
87 <!-- forward declaration of class -->
88 <xsl:for-each select="class">
89 class <xsl:value-of select="@name"/>;
90 <xsl:if test="database">
91 class <xsl:value-of select="@name"/>Ptr;</xsl:if></xsl:for-each>
92 <xsl:text>
93 </xsl:text>
94 <!-- declaration of smart ptr class -->
95 <xsl:for-each select="class">
96 <xsl:if test="database">
97 <xsl:call-template name="makePersistentPtrHeader">
98 <xsl:with-param name="className" select="@name"/>
99 </xsl:call-template>
100 <xsl:text>
101 </xsl:text>
102 </xsl:if>
103 </xsl:for-each>
104 <xsl:call-template name="myApplyTemplate"/>
106 </xsl:template>
108 <!-- _______________________________________ -->
109 <xsl:template match="namespace" mode="cpp">
110 #include "<xsl:value-of select="$filename"/>.h"
112 namespace <xsl:value-of select="@name"/>
114 <xsl:call-template name="myApplyTemplate"/>
116 </xsl:template>
118 <!-- _______________________________________ -->
119 <xsl:template match="namespace" mode="php"><xsl:apply-templates mode="php"/></xsl:template>
121 <!-- ######################################################### -->
122 <!-- ##### Additionnal includes ####### -->
123 <!-- ######################################################### -->
124 <xsl:template match="include" mode="header">
125 #include "<xsl:value-of select="@file"/>"
126 </xsl:template>
127 <xsl:template match="sys-include" mode="header">
128 #include &lt;<xsl:value-of select="@file"/>&gt;
129 </xsl:template>
131 <xsl:template match="cpp-include" mode="cpp">
132 #include "<xsl:value-of select="@file"/>"
133 </xsl:template>
135 <xsl:template match="php-include" mode="php">
136 <xsl:text>&lt;?php
137 require_once('</xsl:text><xsl:value-of select="@file"/><xsl:text>');
138 ?&gt;
139 </xsl:text>
140 </xsl:template>
142 <!-- ######################################################### -->
143 <!-- ##### Verbatim code ####### -->
144 <!-- ######################################################### -->
145 <xsl:template match="verbatim_header" mode="header">
146 <xsl:value-of select="."/>
147 </xsl:template>
149 <!-- ################################################################## -->
150 <!-- ##### Generate a module interface classes (Header Part)#### -->
151 <!-- ################################################################## -->
152 <xsl:template match="module_interface" mode="header">
153 /////////////////////////////////////////////////////////////////
154 // WARNING : this is a generated file, don't change it !
155 /////////////////////////////////////////////////////////////////
156 class <xsl:value-of select="@name"/>Skel
158 public:
159 /// the interceptor type
160 typedef NLNET::CInterceptorForwarder &lt; <xsl:value-of select="@name"/>Skel&gt; TInterceptor;
161 protected:
162 <xsl:value-of select="@name"/>Skel()
164 // do early run time check for message table
165 getMessageHandlers();
167 virtual ~<xsl:value-of select="@name"/>Skel()
171 void init(NLNET::IModule *module)
173 _Interceptor.init(this, module);
175 <!-- If the interface contains two-way invocation methods, we need a virtual to retreive the module instance -->
176 <xsl:if test="method/return">
177 public:
179 <!-- // Virtual to retreive the instance of the implementation module
180 // Use the macro NLNET_INTERFACE_GET_MODULE to simply declare the implementation in your module
181 virtual NLNET::IModule *getModuleInstance() =0;
183 </xsl:if>
184 // unused interceptors
185 std::string fwdBuildModuleManifest() const { return std::string(); }
186 void fwdOnModuleUp(NLNET::IModuleProxy *moduleProxy) {}
187 void fwdOnModuleDown(NLNET::IModuleProxy *moduleProxy) {}
188 void fwdOnModuleSecurityChange(NLNET::IModuleProxy *moduleProxy) {}
190 // process module message interceptor
191 bool fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;message);
192 private:
194 typedef void (<xsl:value-of select="@name"/>Skel::*TMessageHandler)(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;message);
195 typedef std::map&lt;std::string, TMessageHandler&gt; TMessageHandlerMap;
197 const TMessageHandlerMap &amp;getMessageHandlers() const;
199 <xsl:for-each select="method">
200 <xsl:choose>
201 <xsl:when test="not(return)">
202 void <xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message);
203 </xsl:when>
204 <xsl:when test="return">
205 void <xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message);
206 </xsl:when>
207 </xsl:choose>
208 </xsl:for-each>
209 <xsl:text>
210 </xsl:text>// declare one interceptor member of the skeleton
211 TInterceptor _Interceptor;
213 // declare the interceptor forwarder as friend of this class
214 friend class NLNET::CInterceptorForwarder &lt; <xsl:value-of select="@name"/>Skel&gt;;
215 <xsl:text> public:
216 /////////////////////////////////////////////////////////////////
217 // WARNING : this is a generated file, don't change it !
218 /////////////////////////////////////////////////////////////////
220 </xsl:text>
221 <xsl:for-each select="method">
222 <xsl:choose>
223 <xsl:when test="not(return)">
224 <xsl:call-template name="makeMethodDoc"/>
225 <xsl:text> </xsl:text>virtual void <xsl:value-of select="@name"/>(NLNET::IModuleProxy *sender<xsl:call-template name="makeParamList"/>)<xsl:text> =0;
226 </xsl:text>
227 </xsl:when>
228 <xsl:when test="return">
229 <xsl:call-template name="makeMethodDoc"/>
230 <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;
231 </xsl:text>
232 </xsl:when>
233 </xsl:choose>
234 </xsl:for-each>
238 /////////////////////////////////////////////////////////////////
239 // WARNING : this is a generated file, don't change it !
240 /////////////////////////////////////////////////////////////////
241 <xsl:text> </xsl:text>class <xsl:value-of select="@name"/>Proxy
243 /// Smart pointer on the module proxy
244 NLNET::TModuleProxyPtr _ModuleProxy;
246 // Pointer on the local module that implement the interface (if the proxy is for a local module)
247 NLNET::TModulePtr _LocalModule;
248 // Direct pointer on the server implementation interface for collocated module
249 <xsl:value-of select="@name"/>Skel *_LocalModuleSkel;
252 public:
253 <xsl:value-of select="@name"/>Proxy(NLNET::IModuleProxy *proxy)
255 <xsl:if test="@module_class"> nlassert(proxy->getModuleClassName() == <xsl:value-of select="@module_class"/>);</xsl:if>
256 _ModuleProxy = proxy;
258 // initialize collocated servant interface
259 if (proxy->getModuleDistance() == 0)
261 _LocalModule = proxy->getLocalModule();
262 nlassert(_LocalModule != NULL);
263 <xsl:value-of select="@name"/>Skel::TInterceptor *interceptor = NULL;
264 interceptor = static_cast &lt; NLNET::CModuleBase* &gt;(_LocalModule.getPtr())->getInterceptor(interceptor);
265 nlassert(interceptor != NULL);
267 _LocalModuleSkel = interceptor->getParent();
268 nlassert(_LocalModuleSkel != NULL);
270 else
271 _LocalModuleSkel = 0;
274 virtual ~<xsl:value-of select="@name"/>Proxy()
278 NLNET::IModuleProxy *getModuleProxy()
280 return _ModuleProxy;
283 <xsl:for-each select="method">
284 <xsl:call-template name="makeMethodDoc"/>
285 <xsl:choose>
286 <xsl:when test="not(return)">
287 <xsl:text> </xsl:text>void <xsl:value-of select="@name"/>(NLNET::IModule *sender<xsl:call-template name="makeParamList"/>);
288 </xsl:when>
289 <xsl:when test="return">
290 <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"/>);
291 </xsl:when>
292 </xsl:choose>
293 </xsl:for-each>
295 <xsl:for-each select="method[@broadcast = 'true']">
296 <xsl:call-template name="makeMethodDoc"/>
297 <xsl:text>
298 // This is the broadcast version of the method.
299 template &lt; class ProxyIterator &gt;
300 </xsl:text>static void broadcast_<xsl:value-of select="@name"/>(ProxyIterator first, ProxyIterator last, NLNET::IModule *sender<xsl:call-template name="makeParamList"/>)
302 NLNET::CMessage message;
304 // create the message to send to multiple dest
305 buildMessageFor_<xsl:value-of select="@name"/>(message <xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
307 for (; first != last; ++first)
309 NLNET::IModuleProxy *proxy = *first;
311 proxy->sendModuleMessage(sender, message);
314 }<xsl:text>
315 </xsl:text>
316 </xsl:for-each>
319 <xsl:for-each select="method">
320 <xsl:text>
321 // Message serializer. Return the message received in reference for easier integration
322 static const NLNET::CMessage &amp;buildMessageFor_</xsl:text><xsl:value-of select="@name"/>(NLNET::CMessage &amp;__message<xsl:call-template name="makeParamList"/>);
323 </xsl:for-each>
327 };<xsl:text>
328 </xsl:text>
330 </xsl:template>
332 <!-- ######################################################### -->
333 <!-- ##### Generate module interface, cpp part ####### -->
334 <!-- ######################################################### -->
335 <xsl:template match="module_interface" mode="cpp">
336 /////////////////////////////////////////////////////////////////
337 // WARNING : this is a generated file, don't change it !
338 /////////////////////////////////////////////////////////////////
339 <xsl:variable name="skelName" select="concat(@name, 'Skel')"/>
340 <xsl:variable name="proxyName" select="concat(@name, 'Proxy')"/>
342 const <xsl:value-of select="$skelName"/>::TMessageHandlerMap &amp;<xsl:value-of select="$skelName"/>::getMessageHandlers() const
344 static TMessageHandlerMap handlers;
345 static bool init = false;
347 if (!init)
349 std::pair &lt; TMessageHandlerMap::iterator, bool &gt; res;
350 <xsl:for-each select="method">
351 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));
352 // if this assert, you have a doubly message name in your interface definition !
353 nlassert(res.second);
354 </xsl:for-each>
355 init = true;
358 return handlers;
360 bool <xsl:value-of select="@name"/>Skel::fwdOnProcessModuleMessage(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;message)
362 const TMessageHandlerMap &amp;mh = getMessageHandlers();
364 TMessageHandlerMap::const_iterator it(mh.find(message.getName()));
366 if (it == mh.end())
368 return false;
371 TMessageHandler cmd = it->second;
372 (this->*cmd)(sender, message);
374 return true;
377 <xsl:for-each select="method">
378 <xsl:choose>
379 <xsl:when test="not(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="@name"/>(sender<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);<xsl:text>
390 </xsl:text>
391 <xsl:text> }
392 </xsl:text>
393 </xsl:when>
394 <xsl:when test="return">
395 void <xsl:value-of select="$skelName"/>::<xsl:value-of select="@name"/>_skel(NLNET::IModuleProxy *sender, const NLNET::CMessage &amp;__message)
397 H_AUTO(<xsl:value-of select="$skelName"/>_<xsl:value-of select="@name"/>_<xsl:value-of select="@msg"/>);
398 <xsl:for-each select="param">
399 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
400 </xsl:text>
401 <xsl:call-template name="serialRead"><xsl:with-param name="message" select="'__message'"/></xsl:call-template>
402 </xsl:for-each>
404 <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>);
405 // encode the return message
406 NLNET::CMessage __retMsg;
407 __retMsg.setType("R_<xsl:value-of select="@msg"/>", NLNET::CMessage::Response);
408 nlWrite(__retMsg, serial<xsl:value-of select="return/@serial"/>, __ret);
410 // and send back the response
411 sender->sendModuleMessage(static_cast&lt;NLNET::IModule*&gt;(_Interceptor.getRegistrar()), __retMsg);
412 <xsl:text>
413 </xsl:text>
414 <xsl:text> }
415 </xsl:text>
416 </xsl:when>
417 </xsl:choose>
418 </xsl:for-each>
420 <xsl:for-each select="method">
421 <xsl:call-template name="makeMethodDoc"/>
422 <xsl:choose>
423 <xsl:when test="not(return)">
424 <xsl:text> </xsl:text>void <xsl:value-of select="$proxyName"/>::<xsl:value-of select="@name"/>(NLNET::IModule *sender<xsl:call-template name="makeParamList"/>)
426 if (_LocalModuleSkel &amp;&amp; _LocalModule->isImmediateDispatchingSupported())
428 // immediate local synchronous dispatching
429 _LocalModuleSkel-><xsl:value-of select="@name"/>(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender)<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
431 else
433 // send the message for remote dispatching and execution or local queing
434 NLNET::CMessage __message;
436 buildMessageFor_<xsl:value-of select="@name"/>(__message<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
438 _ModuleProxy->sendModuleMessage(sender, __message);
440 }<xsl:text>
441 </xsl:text>
442 </xsl:when>
443 <xsl:when test="return">
444 <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"/>)
446 if (_LocalModuleSkel &amp;&amp; _LocalModule->isImmediateDispatchingSupported())
448 // immediate local synchronous dispatching
449 return _LocalModuleSkel-><xsl:value-of select="@name"/>(_ModuleProxy->getModuleGateway()->getPluggedModuleProxy(sender)<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
451 else
453 // send the message for remote dispatching and execution
455 NLNET::CMessage __message;
457 buildMessageFor_<xsl:value-of select="@name"/>(__message<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
459 NLNET::CMessage __retMsg;
460 sender->invokeModuleOperation(_ModuleProxy, __message, __retMsg);
462 // check the return message type
463 if (__retMsg.getName() != "R_<xsl:value-of select="@msg"/>")
464 throw NLNET::IModule::EInvokeBadReturn();
466 <xsl:value-of select="return/@type"/> __ret;
467 nlRead(__retMsg, serial, __ret);
469 return __ret;
471 }<xsl:text>
472 </xsl:text>
473 </xsl:when>
474 </xsl:choose>
475 </xsl:for-each>
477 <xsl:for-each select="method">
478 <xsl:text>
479 // Message serializer. Return the message received in reference for easier integration
480 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"/>)
482 __message.setType("<xsl:value-of select="@msg"/>"<xsl:if test="return">, NLNET::CMessage::Request</xsl:if>);
483 <xsl:for-each select="param"><xsl:call-template name="serialWrite"> <xsl:with-param name="message" select="'__message'"/></xsl:call-template>
484 </xsl:for-each>
486 return __message;
487 }<xsl:text>
488 </xsl:text>
489 </xsl:for-each>
492 </xsl:template>
494 <!-- ######################################################### -->
495 <!-- ##### Generate documentation ####### -->
496 <!-- ######################################################### -->
497 <xsl:template name="makeMethodDoc">
498 <xsl:for-each select="doc">
499 <xsl:text> // </xsl:text><xsl:value-of select="@line"/><xsl:text>
500 </xsl:text>
501 </xsl:for-each>
502 </xsl:template>
504 <xsl:template name="makeMasterDoc">
505 <xsl:for-each select="doc">
506 <xsl:text> // </xsl:text><xsl:value-of select="@line"/><xsl:text>
507 </xsl:text>
508 </xsl:for-each>
509 </xsl:template>
511 <!-- ######################################################### -->
512 <!-- ##### Generate parameter list ####### -->
513 <!-- #########################################################-->
514 <xsl:template name="makeParamList">
515 <xsl:if test="param">
516 <xsl:text>, </xsl:text><xsl:call-template name="makeParamListNoStartingComma"/>
517 </xsl:if>
518 </xsl:template>
520 <xsl:template name="makeParamListNoStartingComma">
521 <xsl:if test="param">
522 <xsl:for-each select="param">
523 <xsl:choose>
524 <xsl:when test="@array = 'true'">
525 <!-- generate vector for callback interface-->
526 <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>
527 </xsl:when>
528 <xsl:otherwise>
529 <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>
530 </xsl:otherwise>
531 </xsl:choose>
532 </xsl:for-each>
533 </xsl:if>
534 </xsl:template>
536 <!-- ######################################################### -->
537 <!-- ##### Write serialisation ####### -->
538 <!-- ######################################################### -->
539 <xsl:template name="serialWrite">
540 <xsl:param name="message" select="'message'"/>
541 <xsl:choose>
542 <xsl:when test="@byref = 'true'">
543 <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>
544 </xsl:text>
545 </xsl:when>
546 <xsl:otherwise>
547 <xsl:if test="not(@array)">
548 <xsl:text> </xsl:text>nlWrite(<xsl:value-of select="$message"/>, serial<xsl:value-of select="@serial"/>, <xsl:value-of select="@name"/>);<xsl:text>
549 </xsl:text>
550 </xsl:if>
552 <xsl:if test="@array = 'true'">
553 <xsl:text> </xsl:text>nlWrite(<xsl:value-of select="$message"/>, serialCont, <xsl:value-of select="@name"/>);<xsl:text>
554 </xsl:text>
555 </xsl:if>
556 </xsl:otherwise>
557 </xsl:choose>
558 </xsl:template>
560 <!-- ######################################################### -->
561 <!-- ##### Read serialisation ####### -->
562 <!-- ######################################################### -->
563 <xsl:template name="serialRead">
564 <xsl:param name="message" select="'message'"/>
565 <xsl:if test="not(@array)">
566 <xsl:text> </xsl:text>nlRead(<xsl:value-of select="$message"/>, serial<xsl:value-of select="@serial"/>, <xsl:value-of select="@name"/>);<xsl:text>
567 </xsl:text>
568 </xsl:if>
569 <xsl:if test="@array = 'true'">
570 <xsl:text> </xsl:text>nlRead(<xsl:value-of select="$message"/>, serialCont, <xsl:value-of select="@name"/>);<xsl:text>
571 </xsl:text>
572 </xsl:if>
573 </xsl:template>
575 <!-- ######################################################### -->
576 <!-- ##### Enum generation ####### -->
577 <!-- ######################################################### -->
580 <xsl:template match="enum" mode="php">
581 <xsl:text>&lt;?php
582 /////////////////////////////////////////////////////////////////
583 // WARNING : this is a generated file, don't change it !
584 /////////////////////////////////////////////////////////////////
586 $arrayCounter = 0;
587 </xsl:text>
588 <xsl:for-each select="item">
589 <xsl:text> $</xsl:text><xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="../@name"/>_EnumValues[$arrayCounter++] = "<xsl:value-of select="@name"/><xsl:text>";
590 </xsl:text></xsl:for-each>
591 <xsl:text> $</xsl:text><xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues[$arrayCounter] = "invalid";
592 $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue = $arrayCounter;
594 class <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>
596 var $Value;
598 function <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>()
600 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
601 $this->Value = $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
604 function toString()
606 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues;
607 return $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues[$this->Value];
610 function fromString($strValue)
612 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues;
613 foreach ($<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues as $k => $v)
615 if ($strValue === $v)
617 $this->Value = $k;
618 return;
622 $this->Value = $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
625 function toInt()
627 return $this->Value;
630 function fromInt($intValue)
632 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
633 global $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues;
634 if (array_key_exists($intValue, $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_EnumValues))
635 $this->Value = $intValue;
636 else
637 $this->Value = $<xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@name"/>_InvalidValue;
640 <xsl:text>?&gt;
641 </xsl:text></xsl:template>
644 <xsl:template match="enum" mode="header">
645 <xsl:call-template name="makeMasterDoc"/>
646 <xsl:if test="@bitset='true'">
647 <xsl:call-template name="enumGen">
648 <xsl:with-param name="enumName" select="concat(@name, 'Enum')"/>
649 </xsl:call-template>
650 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"/>;
651 </xsl:if>
652 <xsl:if test="not(@bitset='true')">
653 <xsl:call-template name="enumGen">
654 <xsl:with-param name="enumName" select="@name"/>
655 </xsl:call-template>
656 </xsl:if>
657 </xsl:template>
660 <xsl:template name="enumGen">
661 <xsl:param name="enumName"/>
663 <!-- check that we don't set a base value AND a value for the 1st enum item -->
664 <xsl:if test="@base and item[1]/@value">
665 <xsl:message terminate="yes">
666 ERROR : You can't set a base value AND a value for the first item on enum definition <xsl:value-of select="$enumName"/>
667 </xsl:message>
668 </xsl:if>
670 struct <xsl:value-of select="$enumName"/>
672 enum TValues
674 <xsl:for-each select="item">
675 <xsl:value-of select="@name"/><xsl:if test="@value"> = <xsl:value-of select="@value"/></xsl:if>
676 <xsl:if test="position() = 1 and ../@base"> = <xsl:value-of select="../@base"/></xsl:if>,
677 </xsl:for-each>
678 <!-- generate a value 'past the end' and 'last_enum_item' if no values are set other than on first item-->
679 <xsl:if test="count(item/@value) = 0 or (count(item/@value) = 1 and item[1]/@value)">
680 <xsl:text>/// the highest valid value in the enum
681 last_enum_item = </xsl:text><xsl:value-of select="item[last()]/@name"/>,
682 /// a value equal to the last enum item +1
683 end_of_enum,
684 </xsl:if>
685 <!-- generate an invalid and undefined value-->
686 invalid_val,
687 <!-- generate a count of node -->
688 /// Number of enumerated values
689 nb_enum_items = <xsl:value-of select="count(item)"/>
691 <!-- generate an index table if the enum is 'linear' -->
692 <xsl:if test="count(item/@value) = 0 or (count(item/@value) = 1 and item[1]/@value)">
693 /// Index table to convert enum value to linear index table
694 const std::map&lt;TValues, uint32&gt; &amp;getIndexTable() const
696 static std::map&lt;TValues, uint32&gt; indexTable;
697 static bool init = false;
698 if (!init)
700 // fill the index table
701 <xsl:for-each select="item">
702 <xsl:text> indexTable.insert(std::make_pair(</xsl:text><xsl:value-of select="@name"/>, <xsl:value-of select="position()-1"/>));
703 </xsl:for-each>
704 init = true;
707 return indexTable;
709 </xsl:if>
711 static const NLMISC::CStringConversion&lt;TValues&gt; &amp;getConversionTable()
713 NL_BEGIN_STRING_CONVERSION_TABLE(TValues)
714 <xsl:for-each select="item"> NL_STRING_CONVERSION_TABLE_ENTRY(<xsl:value-of select="@name"/>)
715 </xsl:for-each> NL_STRING_CONVERSION_TABLE_ENTRY(invalid_val)
717 static NLMISC::CStringConversion&lt;TValues&gt;
718 conversionTable(TValues_nl_string_conversion_table, sizeof(TValues_nl_string_conversion_table)
719 / sizeof(TValues_nl_string_conversion_table[0]), invalid_val);
721 return conversionTable;
724 TValues _Value;
726 public:
727 <xsl:value-of select="$enumName"/>()
728 : _Value(invalid_val)
731 <xsl:value-of select="$enumName"/>(TValues value)
732 : _Value(value)
736 <xsl:value-of select="$enumName"/>(const std::string &amp;str)
738 _Value = getConversionTable().fromString(str);
741 void serial(NLMISC::IStream &amp;s)
743 s.serialEnum(_Value);
746 bool operator == (const <xsl:value-of select="$enumName"/> &amp;other) const
748 return _Value == other._Value;
750 bool operator != (const <xsl:value-of select="$enumName"/> &amp;other) const
752 return ! (_Value == other._Value);
754 bool operator &lt; (const <xsl:value-of select="$enumName"/> &amp;other) const
756 return _Value &lt; other._Value;
759 bool operator &lt;= (const <xsl:value-of select="$enumName"/> &amp;other) const
761 return _Value &lt;= other._Value;
764 bool operator &gt; (const <xsl:value-of select="$enumName"/> &amp;other) const
766 return !(_Value &lt;= other._Value);
768 bool operator &gt;= (const <xsl:value-of select="$enumName"/> &amp;other) const
770 return !(_Value &lt; other._Value);
773 const std::string &amp;toString() const
775 return getConversionTable().toString(_Value);
777 static const std::string &amp;toString(TValues value)
779 return getConversionTable().toString(value);
782 TValues getValue() const
784 return _Value;
787 // return true if the actual value of the enum is valid, otherwise false
788 bool isValid()
790 if (_Value == invalid_val)
791 return false;
793 // not invalid, check other enum value
794 return getConversionTable().isValid(_Value);
797 <!-- generate an index table if the enum is 'linear' -->
798 <xsl:if test="count(item/@value) = 0 or (count(item/@value) = 1 and item[1]/@value)">
799 uint32 asIndex()
801 std::map&lt;TValues, uint32&gt;::const_iterator it(getIndexTable().find(_Value));
802 nlassert(it != getIndexTable().end());
803 return it->second;
805 </xsl:if>
807 <!-- insert user code if any -->
808 <xsl:if test="header_code">
809 <xsl:value-of select="header_code"/>
810 </xsl:if>
812 </xsl:template>
816 <!-- ######################################################### -->
817 <!-- ##### Class generation (db mapping, serial and message)### -->
818 <!-- ######################################################### -->
820 <xsl:template name="makeProperty">
821 <xsl:param name="property"/>
822 <xsl:text> </xsl:text>// <xsl:value-of select="$property/@doc"/><xsl:text>
823 </xsl:text>
824 <xsl:text> </xsl:text><xsl:value-of select="$property/@type"/><xsl:text> _</xsl:text><xsl:value-of select="$property/@name"/><xsl:text>;
825 </xsl:text>
826 </xsl:template>
828 <!--/////////////////////////////////////////////////////////-->
829 <xsl:template name="makePropertyAccessor">
830 <xsl:param name="property"/>
831 <xsl:text> </xsl:text>// <xsl:value-of select="$property/@doc"/><xsl:text>
832 </xsl:text>
833 <xsl:choose>
834 <xsl:when test="$property/@byref = 'true'">
835 <xsl:text> </xsl:text>const <xsl:value-of select="$property/@type"/> &amp;get<xsl:value-of select="$property/@name"/>() const
837 return _<xsl:value-of select="$property/@name"/>;
840 <xsl:if test="not(../database) and $property/@byref = 'true'">
841 <!-- for non database 'by reference' property, generate a non const get accessor -->
842 <xsl:text> </xsl:text><xsl:value-of select="$property/@type"/> &amp;get<xsl:value-of select="$property/@name"/>()
844 return _<xsl:value-of select="$property/@name"/>;
846 </xsl:if>
848 void set<xsl:value-of select="$property/@name"/>(const <xsl:value-of select="$property/@type"/> &amp;value)
850 <xsl:if test="../database">
851 if (_<xsl:value-of select="$property/@name"/> != value)
853 if (getPersistentState() != NOPE::os_transient)
854 setPersistentState(NOPE::os_dirty);
855 </xsl:if>
857 <xsl:variable name="relation" select="parent[@db_col = $property/@db_col]"/>
858 <xsl:if test="$relation">
859 <!-- this property is a child/parent relation, update the parent -->
861 <xsl:value-of select="$relation/@class"/>Ptr parent = <xsl:value-of select="$relation/@class"/>::loadFromCache(_<xsl:value-of select="$property/@name"/>);
863 if (parent &amp;&amp; getPersistentState() != NOPE::os_transient )
864 parent->remove<xsl:value-of select="$relation/@child_name"/>Child(this);
865 </xsl:if>
867 _<xsl:value-of select="$property/@name"/> = value;
869 <xsl:if test="$relation">
870 <!-- this property is a child/parent relation, update the parent -->
872 <xsl:value-of select="$relation/@class"/>Ptr parent = <xsl:value-of select="$relation/@class"/>::loadFromCache(_<xsl:value-of select="$property/@name"/>);
873 if (parent &amp;&amp; getPersistentState() != NOPE::os_transient)
874 parent->insert<xsl:value-of select="$relation/@child_name"/>Child(this);
875 </xsl:if>
876 <xsl:if test="../database">
878 </xsl:if>
880 </xsl:when>
881 <xsl:otherwise>
882 <xsl:text> </xsl:text><xsl:value-of select="$property/@type"/> get<xsl:value-of select="$property/@name"/>() const
884 return _<xsl:value-of select="$property/@name"/>;
887 void set<xsl:value-of select="$property/@name"/>(<xsl:value-of select="$property/@type"/> value)
889 <xsl:if test="../database">
890 if (_<xsl:value-of select="$property/@name"/> != value)
892 if (getPersistentState() != NOPE::os_transient)
893 setPersistentState(NOPE::os_dirty);
894 </xsl:if>
895 _<xsl:value-of select="$property/@name"/> = value;
896 <xsl:if test="../database">
898 </xsl:if>
900 </xsl:otherwise>
901 </xsl:choose>
902 </xsl:template>
905 <!--/////////////////////////////////////////////////////////-->
906 <xsl:template name="makeChildAccessor">
907 <xsl:param name="childClass"/>
908 <xsl:if test="@cont">
909 <xsl:choose>
910 <xsl:when test="@cont = 'vector'">
911 /** Return a const reference to the vector of child.
912 * If you want to modify the element inside, you need to
913 * use on of the two following methods who return non const pointer
914 * on contained elements.
916 const std::vector&lt;<xsl:value-of select="@type"/>Ptr&gt; &amp;get<xsl:value-of select="@name"/>() const;
917 /** Return the ith element of the child vector
918 * index must be valid (ie less than size of the vector)
920 <xsl:value-of select="@type"/>Ptr &amp;get<xsl:value-of select="@name"/>ByIndex(uint32 index) const;
921 /** Return the identified element by looking in the vector
922 * If no element match the id, NULL pointer is returned
924 <xsl:value-of select="@type"/>Ptr &amp;get<xsl:value-of select="@name"/>ById(uint32 id) const;
926 </xsl:when>
927 <xsl:when test="@cont = 'map'">
928 /** Return a const reference to the map of child.
929 * If you want to modify the element inside, you need to
930 * use on of the two following method who return non const pointer
931 * on contained elements.
933 const std::map&lt;uint32, <xsl:value-of select="@type"/>Ptr&gt; &amp;get<xsl:value-of select="@name"/>() const;
934 /** Return the identified element by looking in the map
935 * If no element match the id, NULL pointer is returned
937 <xsl:value-of select="@type"/>Ptr &amp;get<xsl:value-of select="@name"/>ById(uint32 id) const;
939 </xsl:when>
940 <xsl:otherwise>
941 <xsl:message terminate="yes">
942 ERROR : Invalide container, child must be either map or vector for child <xsl:value-of select="@name"/> in class <xsl:value-of select="../@name"/>
944 </xsl:message>
945 </xsl:otherwise>
946 </xsl:choose>
947 </xsl:if>
949 <xsl:if test="not(@cont)">
950 /** Return the one child object (or null if not) */
951 <xsl:value-of select="@type"/>Ptr get<xsl:value-of select="@name"/>();
952 </xsl:if>
953 </xsl:template>
956 <!--/////////////////////////////////////////////////////////-->
957 <xsl:template name="makeColumList">
958 <xsl:param name="uniqueId"/>
959 <xsl:choose>
960 <xsl:when test="property[@name = $uniqueId and @db_col]/@autogen = 'true'">
961 qs += "<xsl:for-each select="property[@name != $uniqueId]">
962 <xsl:value-of select="@db_col"/>
963 <xsl:if test="position() != last()"><xsl:text>, </xsl:text></xsl:if>
964 </xsl:for-each><xsl:text>";</xsl:text>
965 </xsl:when>
966 <xsl:otherwise>
967 qs += "<xsl:for-each select="property[@db_col]">
968 <xsl:value-of select="@db_col"/>
969 <xsl:if test="position() != last()">, </xsl:if>
970 </xsl:for-each><xsl:text>";</xsl:text>
971 </xsl:otherwise>
972 </xsl:choose>
973 </xsl:template>
975 <xsl:template name="makeColumListWithId">
976 qs += "<xsl:for-each select="property[@db_col]">
977 <xsl:value-of select="@db_col"/>
978 <xsl:if test="position() != last()">, </xsl:if>
979 </xsl:for-each>
980 <xsl:text>";
981 </xsl:text>
982 </xsl:template>
984 <xsl:template name="makeValueList">
985 <xsl:param name="uniqueId"/>
986 <xsl:choose>
987 <xsl:when test="property[@name = $uniqueId]/@autogen = 'true'">
988 <xsl:for-each select="property[@name != $uniqueId and @db_col]">
989 <xsl:choose>
990 <xsl:when test="@enum='true' or @enum='smart'">
991 qs += "'"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
992 </xsl:text>
993 </xsl:when>
994 <xsl:when test="@date='true'">
995 qs += "'"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
996 </xsl:text>
997 </xsl:when>
998 <xsl:when test="@md5='true'">
999 qs += "'"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1000 </xsl:text>
1001 </xsl:when>
1002 <xsl:otherwise>
1003 qs += "'"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1004 </xsl:text>
1005 </xsl:otherwise>
1006 </xsl:choose>
1007 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1008 </xsl:for-each>
1009 </xsl:when>
1010 <xsl:otherwise>
1011 <xsl:for-each select="property[@db_col]">
1012 <xsl:choose>
1013 <xsl:when test="@enum='true' or @enum='smart'">
1014 qs += "'"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
1015 </xsl:text>
1016 </xsl:when>
1017 <xsl:when test="@date='true'">
1018 qs += "'"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1019 </xsl:text>
1020 </xsl:when>
1021 <xsl:when test="@md5='true'">
1022 qs += "'"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1023 </xsl:text>
1024 </xsl:when>
1025 <xsl:otherwise>
1026 qs += "'"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1027 </xsl:text>
1028 </xsl:otherwise>
1029 </xsl:choose>
1030 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1031 </xsl:for-each>
1032 </xsl:otherwise>
1033 </xsl:choose>
1034 </xsl:template>
1036 <xsl:template name="makeValueListWithId">
1037 <xsl:for-each select="property[@db_col]">
1038 <xsl:choose>
1039 <xsl:when test="@enum='true' or @enum='smart'">
1040 qs += "'"+_<xsl:value-of select="@name"/>.toString()+"'";
1041 </xsl:when>
1042 <xsl:when test="@date='true'">
1043 qs += "'"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1044 </xsl:text>
1045 </xsl:when>
1046 <xsl:when test="@md5='true'">
1047 qs += "'"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1048 </xsl:text>
1049 </xsl:when>
1050 <xsl:otherwise>
1051 qs += "'"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)+"'";
1052 </xsl:otherwise>
1053 </xsl:choose>
1054 <xsl:if test="position() != last()">qs += ", ";</xsl:if>
1055 </xsl:for-each>
1056 </xsl:template>
1058 <xsl:template name="makeSetList">
1059 <xsl:param name="uniqueId"/>
1060 <xsl:choose>
1061 <xsl:when test="property[@name = $uniqueId and @db_col]/@autogen = 'true'">
1062 <xsl:for-each select="property[@name != $uniqueId and @db_col]">
1063 <xsl:choose>
1064 <xsl:when test="@enum='true' or @enum='smart'">
1065 qs += "<xsl:value-of select="@db_col"/> = '"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
1066 </xsl:text>
1067 </xsl:when>
1068 <xsl:when test="@date='true'">
1069 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1070 </xsl:text>
1071 </xsl:when>
1072 <xsl:when test="@md5='true'">
1073 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1074 </xsl:text>
1075 </xsl:when>
1076 <xsl:otherwise>
1077 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1078 </xsl:text>
1079 </xsl:otherwise>
1080 </xsl:choose>
1081 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1082 </xsl:for-each>
1083 </xsl:when>
1084 <xsl:otherwise>
1085 <xsl:for-each select="property[@db_col]">
1086 <xsl:choose>
1087 <xsl:when test="@enum='true' or @enum='smart'">
1088 qs += "<xsl:value-of select="@db_col"/> = '"+_<xsl:value-of select="@name"/><xsl:text>.toString()+"'";
1089 </xsl:text>
1090 </xsl:when>
1091 <xsl:when test="@date='true'">
1092 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::encodeDate(_<xsl:value-of select="@name"/>)<xsl:text>+"'";
1093 </xsl:text>
1094 </xsl:when>
1095 <xsl:when test="@md5='true'">
1096 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(_<xsl:value-of select="@name"/>.toString(), connection)<xsl:text>+"'";
1097 </xsl:text>
1098 </xsl:when>
1099 <xsl:otherwise>
1100 qs += "<xsl:value-of select="@db_col"/> = '"+MSW::escapeString(NLMISC::toString(_<xsl:value-of select="@name"/>), connection)<xsl:text>+"'";
1101 </xsl:text>
1102 </xsl:otherwise>
1103 </xsl:choose>
1104 <xsl:if test="position() != last()"><xsl:text> qs += ", ";</xsl:text></xsl:if>
1105 </xsl:for-each>
1106 </xsl:otherwise>
1107 </xsl:choose>
1108 </xsl:template>
1110 <xsl:template name="makeWhereClause">
1111 <xsl:param name="uniqueId"/>
1112 qs += " WHERE <xsl:value-of select="property[@name = $uniqueId]/@db_col"/> = '"+NLMISC::toString(_<xsl:value-of select="property[@name = $uniqueId]/@name"/>)+"'";
1113 </xsl:template>
1115 <xsl:template name="makeWhereClauseWithId">
1116 <xsl:param name="uniqueId"/>
1117 <xsl:param name="id"/>
1118 qs += " WHERE <xsl:value-of select="property[@name = $uniqueId]/@db_col"/> = '"+NLMISC::toString(<xsl:value-of select="$id"/>)+"'";
1119 </xsl:template>
1123 <!-- ######################################################### -->
1124 <!-- ##### Class generation (db mapping, serial and message)### -->
1125 <!-- ######################################################### -->
1126 <!-- ##### Include file #### -->
1127 <xsl:template match="class" mode="header">
1128 <xsl:if test="count(property[@unique_id = 'true' and @db_col]) != 1 and datase">
1129 <xsl:message terminate="yes">
1130 ERROR : You must have ONE and ONLY one unique_id property in class '_<xsl:value-of select="@name"/>'
1131 </xsl:message>
1132 </xsl:if>
1134 <xsl:choose>
1135 <xsl:when test="database">
1136 <xsl:call-template name="makeClassHeader">
1137 <xsl:with-param name="className" select="@name"/>
1138 <xsl:with-param name="uniqueId" select="property[@unique_id = 'true']/@name"/>
1139 </xsl:call-template>
1140 </xsl:when>
1141 <xsl:otherwise>
1142 <xsl:call-template name="makeClassHeader">
1143 <xsl:with-param name="className" select="@name"/>
1144 <xsl:with-param name="uniqueId" select="''"/>
1145 </xsl:call-template>
1146 </xsl:otherwise>
1147 </xsl:choose>
1148 </xsl:template>
1150 <xsl:template name="makeClassHeader">
1151 <xsl:param name="className"/>
1152 <xsl:param name="uniqueId"/>
1154 <!--<xsl:if test="database">
1155 <xsl:call-template name="makePersistentPtrHeader">
1156 <xsl:with-param name="className" select="@name"/>
1157 </xsl:call-template>
1158 </xsl:if>
1160 <xsl:call-template name="makeMasterDoc"/>
1161 <xsl:text> /////////////////////////////////////////////////////////////////
1162 // WARNING : this is a generated file, don't change it !
1163 /////////////////////////////////////////////////////////////////
1164 class </xsl:text><xsl:value-of select="$className"/>
1166 <xsl:text> protected:
1167 </xsl:text> <xsl:for-each select="property">
1168 <xsl:call-template name="makeProperty">
1169 <xsl:with-param name="property" select="."/>
1170 </xsl:call-template>
1171 </xsl:for-each>
1172 <xsl:for-each select="child_class[@relation = 'one-to-many']">
1173 friend class <xsl:value-of select="@type"/>;
1174 <xsl:choose>
1175 <xsl:when test="@cont = 'map'">
1176 std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; *_<xsl:value-of select="@name"/>;
1177 </xsl:when>
1178 <xsl:when test="@cont = 'vector'">
1179 std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; *_<xsl:value-of select="@name"/>;
1180 </xsl:when>
1181 <xsl:otherwise>
1182 <xsl:message terminate="yes">
1183 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"/>'
1184 </xsl:message>
1185 </xsl:otherwise>
1186 </xsl:choose>
1187 </xsl:for-each>
1188 <xsl:for-each select="child_class[@relation = 'one-to-one']">
1189 <xsl:text> friend class </xsl:text><xsl:value-of select="@type"/>;
1190 bool _<xsl:value-of select="@name"/>Loaded;
1191 <xsl:value-of select="@type"/>Ptr _<xsl:value-of select="@name"/>;
1192 </xsl:for-each>
1194 <xsl:text> public:
1195 </xsl:text> <xsl:for-each select="property[@name != $uniqueId]">
1196 <xsl:call-template name="makePropertyAccessor">
1197 <xsl:with-param name="property" select="."/>
1198 </xsl:call-template>
1199 </xsl:for-each>
1201 <xsl:for-each select="child_class">
1202 <xsl:call-template name="makeChildAccessor">
1203 <xsl:with-param name="childClass" select="."/>
1204 </xsl:call-template>
1205 </xsl:for-each>
1206 bool operator == (const <xsl:value-of select="@name"/> &amp;other) const
1208 return <xsl:for-each select="property">_<xsl:value-of select="@name"/> == other._<xsl:value-of select="@name"/><xsl:if test="position() != last()">
1209 &amp;&amp; </xsl:if></xsl:for-each>;
1212 <xsl:if test="not(database)">
1213 <xsl:text>
1214 // constructor
1215 </xsl:text><xsl:value-of select="$className"/>()
1217 <xsl:if test="property[@default]"> // Default initialisation
1218 </xsl:if>
1219 <xsl:for-each select="property[@default]">
1220 <xsl:text> </xsl:text>_<xsl:value-of select="@name"/> = <xsl:value-of select="@default"/>;
1221 </xsl:for-each>
1223 </xsl:if>
1225 <xsl:if test="message">
1226 <!-- generate a serialisable and sendable nel message -->
1227 void send(const std::string &amp;serviceName)
1229 NLNET::CMessage msg("<xsl:value-of select="@name"/>");
1230 serial(msg);
1231 sendMessageViaMirror( serviceName, msg );
1234 void send(NLNET::TServiceId serviceId)
1236 NLNET::CMessage msg("<xsl:value-of select="@name"/>");
1237 serial(msg);
1238 sendMessageViaMirror( serviceId, msg );
1240 </xsl:if>
1242 <xsl:if test="database">
1243 <xsl:text>
1244 private:
1245 // private constructor, you must use 'createTransient' to get an instance
1246 </xsl:text><xsl:value-of select="$className"/>()
1247 : _PtrList(NULL),
1248 _ObjectState(NOPE::os_transient),
1249 _<xsl:value-of select="$uniqueId"/>(NOPE::INVALID_OBJECT_ID)
1251 <xsl:if test="property[@default]"> // Default initialisation
1252 </xsl:if>
1253 <xsl:for-each select="property[@default]">
1254 <xsl:text> </xsl:text>_<xsl:value-of select="@name"/> = <xsl:value-of select="@default"/>;
1255 </xsl:for-each>
1256 <xsl:for-each select="child_class[@relation = 'one-to-many']">
1257 <xsl:text> _</xsl:text><xsl:value-of select="@name"/> = NULL;
1258 </xsl:for-each>
1259 <xsl:for-each select="child_class[@relation = 'one-to-one']">
1260 <xsl:text> _</xsl:text><xsl:value-of select="@name"/>Loaded = false;
1261 </xsl:for-each>
1262 // register the cache for this class (if not already done)
1263 registerUpdatable();
1266 // Destructor, delete any children
1267 ~<xsl:value-of select="@name"/>();
1269 /// utility func to remove this object from the released object container
1270 void removeFromReleased();
1273 public:
1274 /// Create a new instance in the transient space
1275 static <xsl:value-of select="$className"/>Ptr createTransient(const char *filename, uint32 lineNum)
1277 return <xsl:value-of select="$className"/>Ptr(new <xsl:value-of select="$className"/>(), filename, lineNum);
1280 /** Create a new object in the database from the current object data.
1281 * The object MUST be in transient state (i.e, it must be a new
1282 * object created by user and not comming from the databse).
1283 * If identifier is autogenerated, the generated id can be read after
1284 * this call.
1286 bool create(MSW::CConnection &amp;connection);
1287 /** Update the database with the current object state.
1288 * The object MUST be either in clean or dirty state.
1289 * Return true if the object has been effectively stored
1290 * in the database.
1291 * After this call, the object is in 'clean' state.
1293 bool update(MSW::CConnection &amp;connection);
1294 /** Remove the current object from the persistent storage.
1295 * The object must be in clean or dirty state.
1296 * Return true if the object has been correctly
1297 * updated in the database.
1298 * After the call, the object is in 'clean' state.
1300 bool remove(MSW::CConnection &amp;connection);
1301 /** Remove an object from the persistent storage by specifying
1302 * the id to remove.
1303 * Return true if an entry as been effectively removed from
1304 * the database.
1305 * After the call, the object is in 'removed' state and should
1306 * no more be used. A good pratice should be to delete
1307 * the transient object just after the remove call.
1309 static bool removeById(MSW::CConnection &amp;connection, uint32 id);
1311 /** Load an instance from the database.
1312 * This call allocate a new object and load the property value
1313 * from the database.
1314 * Return NULL if the object id is not found.
1316 static <xsl:value-of select="$className"/>Ptr load(MSW::CConnection &amp;connection, uint32 id, const char *filename, uint32 lineNum);
1318 <xsl:for-each select="parent[@relation = 'one-to-many']">
1319 /** Load all objects children of <xsl:value-of select="@class"/> and
1320 * return them by using the specified output iterator.
1322 <xsl:choose>
1323 <xsl:when test="@cont = 'vector'">
1324 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);
1325 </xsl:when>
1326 <xsl:when test="@cont = 'map'">
1327 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);
1328 </xsl:when>
1329 <xsl:otherwise>
1330 <xsl:message terminate="yes">
1331 ERROR : parent/child relation support only 'map' or 'vector' cont specification in <xsl:value-of select="$className"/> definition
1332 </xsl:message>
1333 </xsl:otherwise>
1334 </xsl:choose>
1335 </xsl:for-each>
1336 <xsl:for-each select="parent[@relation = 'one-to-one']">
1337 /** Load the object child of <xsl:value-of select="@class"/> and
1338 * return true if no error, false in case of error (in SQL maybe).
1339 * If no such object is found, fill the child pointer with NULL.
1341 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);
1342 </xsl:for-each>
1345 <!-- <child_class type="CKnownUser" name="KnownUsers" relation="one-to-many" cont="vector"/>-->
1346 <xsl:for-each select="child_class">
1347 /// Load <xsl:value-of select="@name"/> child(ren) object(s).
1348 bool load<xsl:value-of select="@name"/>(MSW::CConnection &amp;connection, const char *filename, uint32 lineNum);
1349 </xsl:for-each>
1350 </xsl:if>
1352 <!-- generate serial -->
1353 <xsl:if test="serial or message">
1354 <xsl:text>
1355 void serial(NLMISC::IStream &amp;s)
1357 </xsl:text>
1358 <xsl:for-each select="property">
1359 <xsl:text> s.serial</xsl:text><xsl:value-of select="@serial"/>(_<xsl:value-of select="@name"/>)<xsl:text>;
1360 </xsl:text>
1361 </xsl:for-each>
1363 </xsl:if>
1365 private:
1366 <!-- generate private child container modifier -->
1367 <xsl:for-each select="child_class[relation = 'one-to-many' and cont='vector']">
1369 /// add a child in the container
1370 void insert<xsl:value-of select="@name"/>Child(<xsl:value-of select="@type"/> &amp;child)
1372 nlassert(std::find(_<xsl:value-of select="@name"/>.begin(), _<xsl:value-of select="@name"/>.end(), child) == _<xsl:value-of select="@name"/>.end());
1374 _<xsl:value-of select="@name"/>.push_back(child);
1377 // remove a child from the container
1378 void removeXXChild()
1382 </xsl:for-each>
1385 <xsl:if test="database">
1386 private:
1387 friend class CPersistentCache;
1388 friend class <xsl:value-of select="$className"/>Ptr;
1390 typedef std::map&lt;uint32, <xsl:value-of select="$className"/>*&gt; TObjectCache;
1391 typedef std::set&lt;<xsl:value-of select="$className"/>*&gt; TObjectSet;
1392 typedef std::map&lt;time_t, TObjectSet&gt; TReleasedObject;
1394 /// The complete set of object currently in memory (either active or released) excluding transient instance
1395 static TObjectCache _ObjectCache;
1396 /// The set of object in memory ut released (no pointer on them) and waiting for decommit
1397 static TReleasedObject _ReleasedObject;
1399 /// The current object state
1400 NOPE::TObjectState _ObjectState;
1402 /// For object in released state, this is the release date (used to trigger deletion of the object from memory)
1403 time_t _ReleaseDate;
1405 /// The linked list of pointer on this object
1406 <xsl:value-of select="$className"/>Ptr *_PtrList;
1408 // Try to load the specified object from the memory cache, return NULL if the object is not in the cache
1409 static <xsl:value-of select="$className"/> *loadFromCache(uint32 objectId, bool unrelease);
1411 // Receive and execute command from the cache manager.
1412 static uint32 cacheCmd(NOPE::TCacheCmd cmd);
1414 static void dump();
1416 static void updateCache();
1418 public:
1419 static void clearCache();
1420 private:
1421 void registerUpdatable();
1423 // set the pointer on the first pointer of the pointer list (set to null when there is no more pointer)
1424 void setFirstPtr(<xsl:value-of select="$className"/>Ptr *ptr);
1426 // return the first pointer of the pointer list (can be null)
1427 <xsl:value-of select="$className"/>Ptr *getFirstPtr()
1429 return _PtrList;
1432 public:
1434 /** Return the object identifier (witch is unique)
1435 * You can only call this method on a persistent instance.
1436 * (because transient instance can have invalid id)
1438 uint32 getObjectId() const
1440 <xsl:if test="property[@name = $uniqueId]/@autogen = 'true'">
1441 nlassert(getPersistentState() != NOPE::os_transient);</xsl:if>
1442 return _<xsl:value-of select="$uniqueId"/>;
1445 /** Set the object unique ID.
1446 * You can only set the object id on a transient object
1447 * having a non autogenerated unique id.
1448 * Furthermore, you MUST set the id before calling create()
1449 * if the id is not autogenerated.
1451 void setObjectId(uint32 objectId)
1453 // can only be set when in transient state
1454 nlassert(getPersistentState() == NOPE::os_transient);
1455 // can only be set once
1456 nlassert(_<xsl:value-of select="$uniqueId"/> == NOPE::INVALID_OBJECT_ID);
1457 _<xsl:value-of select="$uniqueId"/> = objectId;
1460 /** Return the current persistent state of the object.*/
1461 NOPE::TObjectState getPersistentState() const
1463 return _ObjectState;
1466 private:
1467 // Set the persistent state of the object and do some house keeping
1468 void setPersistentState(NOPE::TObjectState state);
1470 </xsl:if>
1475 </xsl:template>
1478 <!-- ######################################################### -->
1479 <!-- ##### Class generation (db mapping, serial and message)### -->
1480 <!-- ######################################################### -->
1481 <!-- ##### cpp file #### -->
1482 <xsl:template match="class" mode="cpp">
1483 <xsl:if test="count(property[@unique_id = 'true' and @db_col]) != 1 and database">
1484 <xsl:message terminate="yes">
1485 ERROR : You must have ONE and ONLY one unique_id property in class '_<xsl:value-of select="@name"/>'
1486 </xsl:message>
1487 </xsl:if>
1489 <xsl:choose>
1490 <xsl:when test="database">
1491 <xsl:call-template name="makeClassCpp">
1492 <xsl:with-param name="className" select="@name"/>
1493 <xsl:with-param name="uniqueId" select="property[@unique_id = 'true']/@name"/>
1494 </xsl:call-template>
1495 </xsl:when>
1496 <xsl:otherwise>
1497 <xsl:call-template name="makeClassCpp">
1498 <xsl:with-param name="className" select="@name"/>
1499 <xsl:with-param name="uniqueId" select="''"/>
1500 </xsl:call-template>
1501 </xsl:otherwise>
1502 </xsl:choose>
1503 </xsl:template>
1505 <xsl:template name="makeClassCpp">
1506 <xsl:param name="className"/>
1507 <xsl:param name="uniqueId"/>
1509 <xsl:if test="database">
1510 <xsl:call-template name="makePersistentPtrCpp">
1511 <xsl:with-param name="className" select="@name"/>
1512 </xsl:call-template>
1513 </xsl:if>
1516 <xsl:if test="database">
1517 <xsl:text>
1519 </xsl:text> <xsl:value-of select="$className"/>::TObjectCache <xsl:value-of select="$className"/>::_ObjectCache;
1520 <xsl:value-of select="$className"/>::TReleasedObject <xsl:value-of select="$className"/>::_ReleasedObject;
1521 <xsl:text>
1523 // Destructor, delete any children
1524 </xsl:text><xsl:value-of select="$className"/>::~<xsl:value-of select="@name"/>()
1526 // release childs reference
1527 <xsl:for-each select="child_class[@relation = 'one-to-many']">
1528 <xsl:text> if (_</xsl:text><xsl:value-of select="@name"/> != NULL)
1529 delete _<xsl:value-of select="@name"/>;
1530 </xsl:for-each>
1532 if (_PtrList != NULL)
1534 nlwarning("ERROR : someone try to delete this object, but there are still ptr on it !");
1535 <xsl:value-of select="$className"/>Ptr *ptr = _PtrList;
1538 nlwarning(" Pointer created from '%s', line %u", ptr->_FileName, ptr->_LineNum);
1539 ptr = _PtrList->getNextPtr();
1540 } while(ptr != _PtrList);
1541 nlstop;
1543 // remove object from cache map
1544 if (_<xsl:value-of select="$uniqueId"/> != NOPE::INVALID_OBJECT_ID
1545 &amp;&amp; _ObjectState != NOPE::os_removed
1546 &amp;&amp; _ObjectState != NOPE::os_transient)
1548 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"/>));
1549 nlverify(_ObjectCache.erase(_<xsl:value-of select="$uniqueId"/>) == 1);
1551 else if (_ObjectState != NOPE::os_transient)
1553 nlassert(_ObjectCache.find(_<xsl:value-of select="$uniqueId"/>) == _ObjectCache.end());
1555 if (_ObjectState == NOPE::os_released)
1557 removeFromReleased();
1559 else
1561 TReleasedObject::iterator it(_ReleasedObject.find(_ReleaseDate));
1562 if (it != _ReleasedObject.end())
1564 nlassert(it->second.find(this) == it->second.end());
1569 void <xsl:value-of select="$className"/>::removeFromReleased()
1571 TReleasedObject::iterator it(_ReleasedObject.find(_ReleaseDate));
1572 nlassert(it != _ReleasedObject.end());
1573 TObjectSet &amp;os = it->second;
1575 nlverify(os.erase(this) == 1);
1577 // nb : _ReleasedObject time entry are removed by the cache update
1580 bool <xsl:value-of select="$className"/>::create(MSW::CConnection &amp;connection)
1582 nlassert(getPersistentState() == NOPE::os_transient);
1583 <xsl:if test="not(property[@name = $uniqueId]/@autogen = 'true')">
1584 nlassert(_<xsl:value-of select="property[@name = $uniqueId]/@name"/> != 0);</xsl:if>
1585 std::string qs;
1586 qs = "INSERT INTO <xsl:value-of select="database/@table"/> (";
1587 <xsl:call-template name="makeColumList">
1588 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1589 </xsl:call-template>
1590 qs += ") VALUES (";
1591 <xsl:call-template name="makeValueList">
1592 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1593 </xsl:call-template>
1594 qs += ")";
1596 if (connection.query(qs))
1598 <xsl:if test="property[@name = $uniqueId]/@autogen = 'true'">
1599 <xsl:text> uint32 _id_ = connection.getLastGeneratedId();
1600 setObjectId(_id_);
1601 </xsl:text></xsl:if>
1603 setPersistentState(NOPE::os_clean);
1605 // update the parent class instance in cache if any
1606 <xsl:for-each select="parent[@relation = 'one-to-many']">
1607 <xsl:variable name="db_col" select="@db_col"/>
1608 <xsl:variable name="parentId" select="concat('_', ../property[@db_col = $db_col]/@name)"/>
1609 if (<xsl:value-of select="$parentId"/> != 0)
1611 // need to update the parent class child list if it is in the cache
1612 <xsl:value-of select="@class"/> *parent = <xsl:value-of select="@class"/>::loadFromCache(<xsl:value-of select="$parentId"/>, false);
1613 if (parent &amp;&amp; parent->_<xsl:value-of select="@child_name"/> != NULL)
1615 <xsl:choose>
1616 <xsl:when test="@cont = 'map'">
1617 nlverify(parent->_<xsl:value-of select="@child_name"/>->insert(std::make_pair(getObjectId(), <xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__))).second);
1618 </xsl:when>
1619 <xsl:when test="@cont = 'vector'">
1620 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());
1621 parent->_<xsl:value-of select="@child_name"/>->push_back(<xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__));
1622 </xsl:when>
1623 </xsl:choose>
1626 </xsl:for-each>
1628 <xsl:for-each select="parent[@relation = 'one-to-one']">
1629 <xsl:variable name="db_col" select="@db_col"/>
1630 <xsl:variable name="parentId" select="concat('_', ../property[@db_col = $db_col]/@name)"/>
1631 if (<xsl:value-of select="$parentId"/> != 0)
1633 // need to update the parent class child if it is in the cache
1634 <xsl:value-of select="@class"/> *parent = <xsl:value-of select="@class"/>::loadFromCache(<xsl:value-of select="$parentId"/>, false);
1635 if (parent &amp;&amp; parent->_<xsl:value-of select="@child_name"/>Loaded)
1637 nlassert(parent->_<xsl:value-of select="@child_name"/> == NULL);
1638 parent->_<xsl:value-of select="@child_name"/> = <xsl:value-of select="$className"/>Ptr(this, __FILE__, __LINE__);
1641 </xsl:for-each>
1642 return true;
1645 return false;
1648 bool <xsl:value-of select="$className"/>::update(MSW::CConnection &amp;connection)
1650 nlassert(getPersistentState() == NOPE::os_dirty || getPersistentState() == NOPE::os_clean);
1652 if (getPersistentState() == NOPE::os_clean)
1653 // the object is clean, just ignore the save
1654 return true;
1656 std::string qs;
1657 qs = "UPDATE <xsl:value-of select="database/@table"/> SET ";
1658 <xsl:call-template name="makeSetList">
1659 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1660 </xsl:call-template>
1661 <xsl:call-template name="makeWhereClause">
1662 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1663 </xsl:call-template>
1665 if (connection.query(qs))
1667 if (connection.getAffectedRows() == 1)
1669 setPersistentState(NOPE::os_clean);
1670 return true;
1674 return false;
1677 bool <xsl:value-of select="$className"/>::remove(MSW::CConnection &amp;connection)
1679 nlassert(getPersistentState() == NOPE::os_dirty || getPersistentState() == NOPE::os_clean);
1681 std::string qs;
1682 qs = "DELETE FROM <xsl:value-of select="database/@table"/> ";
1683 <xsl:call-template name="makeWhereClause">
1684 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1685 </xsl:call-template>
1687 if (connection.query(qs))
1689 if (connection.getAffectedRows() == 1)
1691 <xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='vector']">
1693 // cascading deletion for vector child <xsl:value-of select="@name"/>
1694 if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__))
1696 const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1698 while (!childs.empty())
1700 get<xsl:value-of select="@name"/>ByIndex((uint32)childs.size()-1)->remove(connection);
1705 </xsl:for-each>
1706 <xsl:for-each select="child_class[@on-delete = 'cascade' and @cont='map']">
1708 // cascading deletion for map child <xsl:value-of select="@name"/>
1709 if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__))
1711 const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1713 while (!childs.empty())
1715 get<xsl:value-of select="@name"/>ById(childs.begin()->first)->remove(connection);
1719 </xsl:for-each>
1720 <xsl:for-each select="child_class[@on-delete = 'cascade' and @relation='one-to-one']">
1722 // cascading deletion for single child <xsl:value-of select="@name"/>
1723 if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__))
1725 if (get<xsl:value-of select="@name"/>() != NULL)
1726 get<xsl:value-of select="@name"/>()->remove(connection);
1729 </xsl:for-each>
1730 <xsl:for-each select="child_class[@on-delete = 'update' and @cont='vector']">
1732 // unreference (and update) for vector child <xsl:value-of select="@name"/>
1733 if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__))
1735 const std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1737 for (uint i=0; i &lt; childs.size(); ++i)
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"/>ByIndex(i)->set<xsl:value-of select="$parent_prop"/>(0);
1743 get<xsl:value-of select="@name"/>ByIndex(i)->update(connection);
1747 </xsl:for-each>
1748 <xsl:for-each select="child_class[@on-delete = 'update' and @cont='map']">
1750 // unreference (and update) for map child <xsl:value-of select="@name"/>
1751 if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__)) {
1753 const std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt; &amp; childs = get<xsl:value-of select="@name"/>();
1754 std::map&lt; uint32, <xsl:value-of select="@type"/>Ptr &gt;::const_iterator first(childs.begin()), last(childs.end());
1756 for (; first != last; ++first)
1758 <xsl:variable name="type" select="@type"/>
1759 <xsl:variable name="child_name" select="@name"/>
1760 <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
1761 get<xsl:value-of select="@name"/>ById(it->first)->set<xsl:value-of select="$parent_prop"/>(0);
1762 get<xsl:value-of select="@name"/>ById(it->first)->update(connection);
1766 </xsl:for-each>
1767 <xsl:for-each select="child_class[@on-delete = 'update' and @relation='one-to-one']">
1769 // unreference (and update) for single child <xsl:value-of select="@name"/>
1770 if (load<xsl:value-of select="@name"/>(connection, __FILE__, __LINE__))
1772 <xsl:variable name="type" select="@type"/>
1773 <xsl:variable name="child_name" select="@name"/>
1774 <xsl:variable name="parent_prop" select="//class[@name = $type]/property[@db_col = //class[@name = $type]/parent[@class = $className]/@db_col]/@name"/>
1775 if (get<xsl:value-of select="@name"/>() != NULL)
1777 get<xsl:value-of select="@name"/>()->set<xsl:value-of select="parent_prop"/>(0);
1778 get<xsl:value-of select="@name"/>()->update(connection);
1782 </xsl:for-each>
1784 // change the persistant state to 'removed'.
1785 setPersistentState(NOPE::os_removed);
1787 // need to remove ref from parent class container (if any)
1788 <xsl:for-each select="parent[@relation = 'one-to-many']">
1790 <xsl:variable name="db_col" select="@db_col"/>
1791 <xsl:if test="count(../property[@db_col = $db_col]) = 0">
1792 <xsl:message terminate="yes">
1793 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
1794 </xsl:message>
1795 </xsl:if>
1796 <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__);
1797 if (parent != NULL &amp;&amp; parent->_<xsl:value-of select="@child_name"/> != NULL)
1799 <xsl:choose>
1800 <xsl:when test="@cont = 'map'">
1801 parent->_<xsl:value-of select="@child_name"/>->erase(getObjectId());
1802 </xsl:when>
1803 <xsl:when test="@cont = 'vector'">
1804 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);
1805 if (it != parent->_<xsl:value-of select="@child_name"/>->end())
1807 parent->_<xsl:value-of select="@child_name"/>->erase(it);
1809 </xsl:when>
1810 <xsl:otherwise>
1811 <xsl:message terminate="yes">
1812 ERROR : parent/child relation support only 'map' or 'vector' cont specification in <xsl:value-of select="$className"/> definition
1813 </xsl:message>
1814 </xsl:otherwise>
1815 </xsl:choose>
1818 </xsl:for-each>
1819 // need to remove ref from parent (if any)
1820 <xsl:for-each select="parent[@relation = 'one-to-one']">
1822 <xsl:variable name="db_col" select="@db_col"/>
1823 <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__);
1824 if (parent != NULL &amp;&amp; parent->_<xsl:value-of select="@child_name"/>Loaded)
1826 // assign a new NULL pointer
1827 parent->_<xsl:value-of select="@child_name"/>.assign(<xsl:value-of select="$className"/>Ptr(), __FILE__, __LINE__);
1830 </xsl:for-each>
1832 return true;
1835 return false;
1838 bool <xsl:value-of select="$className"/>::removeById(MSW::CConnection &amp;connection, uint32 id)
1840 <xsl:value-of select="$className"/> *object = loadFromCache(id, true);
1841 if (object != NULL)
1843 return object->remove(connection);
1845 // not in cache, run a SQL query
1846 std::string qs;
1847 qs = "DELETE FROM <xsl:value-of select="database/@table"/> ";
1848 <xsl:call-template name="makeWhereClauseWithId">
1849 <xsl:with-param name="uniqueId" select="$uniqueId"/>
1850 <xsl:with-param name="id" select="'id'"/>
1851 </xsl:call-template>
1853 if (connection.query(qs))
1855 if (connection.getAffectedRows() == 1)
1857 // ok, the row is removed
1858 return true;
1862 return false;
1866 // Try to load the specified object from the memory cache, return NULL if the object is not in the cache
1867 <xsl:value-of select="$className"/> *<xsl:value-of select="$className"/>::loadFromCache(uint32 objectId, bool unrelease)
1869 // look in the cache
1870 TObjectCache::iterator it(_ObjectCache.find(objectId));
1871 if (it == _ObjectCache.end())
1873 // not found, return null
1874 return NULL;
1876 else
1878 <xsl:value-of select="$className"/> *object = it->second;
1880 if (object->_ObjectState == NOPE::os_released)
1882 if (unrelease)
1884 // we need to remove this object from the released object set.
1885 object->removeFromReleased();
1886 object->_ObjectState = NOPE::os_clean;
1890 return it->second;
1893 // Receive and execute command from the cache manager.
1894 uint32 <xsl:value-of select="$className"/>::cacheCmd(NOPE::TCacheCmd cmd)
1896 if (cmd == NOPE::cc_update)
1898 updateCache();
1900 else if (cmd == NOPE::cc_clear)
1902 clearCache();
1904 else if (cmd == NOPE::cc_dump)
1906 dump();
1908 else if (cmd == NOPE::cc_instance_count)
1910 return (uint32)_ObjectCache.size();
1913 // default return value
1914 return 0;
1917 void <xsl:value-of select="$className"/>::dump()
1919 nlinfo(" Cache info for class <xsl:value-of select="$className"/> :");
1920 nlinfo(" There are %u object instances in cache", _ObjectCache.size());
1922 // count the number of object in the released object set
1923 uint32 nbReleased = 0;
1925 TReleasedObject::iterator first(_ReleasedObject.begin()), last(_ReleasedObject.end());
1926 for (; first != last; ++first)
1928 nbReleased += (uint32)first->second.size();
1931 nlinfo(" There are %u object instances in cache not referenced (waiting deletion or re-use))", nbReleased);
1934 void <xsl:value-of select="$className"/>::updateCache()
1936 if (_ReleasedObject.empty())
1937 return;
1939 // 30 s hold in cache
1940 const time_t MAX_CACHE_OLD_TIME = 30;
1942 time_t now = NLMISC::CTime::getSecondsSince1970();
1944 // look for object set older than MAX_CACHE_OLD_TIME and delete them
1945 while (!_ReleasedObject.empty() &amp;&amp; _ReleasedObject.begin()-&gt;first &lt; now-MAX_CACHE_OLD_TIME)
1947 TObjectSet &amp;delSet = _ReleasedObject.begin()->second;
1948 // unload this objects
1949 while (!delSet.empty())
1951 <xsl:value-of select="$className"/> *object = *delSet.begin();
1952 delete object;
1955 _ReleasedObject.erase(_ReleasedObject.begin());
1959 void <xsl:value-of select="$className"/>::clearCache()
1961 // remove any unreferenced object from the cache
1962 while (!_ReleasedObject.empty())
1964 TObjectSet &amp;delSet = _ReleasedObject.begin()->second;
1965 // unload this objects
1966 while (!delSet.empty())
1968 <xsl:value-of select="$className"/> *object = *delSet.begin();
1969 delete object;
1972 _ReleasedObject.erase(_ReleasedObject.begin());
1976 void <xsl:value-of select="$className"/>::registerUpdatable()
1978 static bool registered = false;
1979 if (!registered)
1981 NOPE::CPersistentCache::getInstance().registerCache(&amp;<xsl:value-of select="$className"/>::cacheCmd);
1983 registered = true;
1987 // set the pointer on the first pointer of the pointer list (set to null when there is no more pointer)
1988 void <xsl:value-of select="$className"/>::setFirstPtr(<xsl:value-of select="$className"/>Ptr *ptr)
1990 _PtrList = ptr;
1992 if (ptr == NULL)
1994 // this is the last pointer !
1995 if (_ObjectState == NOPE::os_transient
1996 || _ObjectState == NOPE::os_removed)
1998 // not a persistent object, or removed object, just delet it
1999 delete this;
2001 else if (_ObjectState != NOPE::os_removed)
2003 setPersistentState(NOPE::os_released);
2008 // Set the persistent state of the object and do some house keeping
2009 void <xsl:value-of select="$className"/>::setPersistentState(NOPE::TObjectState state)
2011 nlassert(NOPE::AllowedTransition[_ObjectState][state] == true);
2013 if(_ObjectState == NOPE::os_released &amp;&amp; state == NOPE::os_removed)
2015 // a release object gets removed (e.g. by remove by id)
2017 // delete the object
2018 delete this;
2020 // no more to do
2021 return;
2024 if (_ObjectState == NOPE::os_transient &amp;&amp; state != NOPE::os_transient)
2026 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"/>));
2027 nlverify(_ObjectCache.insert(std::make_pair(_<xsl:value-of select="$uniqueId"/>, this)).second);
2030 if (_ObjectState != NOPE::os_transient)
2031 nlassert(_ObjectCache.find(_<xsl:value-of select="$uniqueId"/>) != _ObjectCache.end());
2033 _ObjectState = state;
2035 if (state == NOPE::os_released)
2037 _ReleaseDate = NLMISC::CTime::getSecondsSince1970();
2038 nlverify(_ReleasedObject[_ReleaseDate].insert(this).second);
2040 else if (state == NOPE::os_removed)
2042 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"/>));
2043 nlverify(_ObjectCache.erase(_<xsl:value-of select="$uniqueId"/>) == 1);
2048 <xsl:value-of select="$className"/>Ptr <xsl:value-of select="$className"/>::load(MSW::CConnection &amp;connection, uint32 id, const char *filename, uint32 lineNum)
2050 <xsl:value-of select="$className"/> *inCache = loadFromCache(id, true);
2051 if (inCache != NULL)
2053 return <xsl:value-of select="$className"/>Ptr(inCache, filename, lineNum);
2056 std::string qs;
2057 qs = "SELECT ";
2058 <xsl:call-template name="makeColumListWithId"/>
2059 qs += " FROM <xsl:value-of select="database/@table"/>";
2060 <xsl:call-template name="makeWhereClauseWithId">
2061 <xsl:with-param name="uniqueId" select="$uniqueId"/>
2062 <xsl:with-param name="id" select="'id'"/>
2063 </xsl:call-template>
2065 <xsl:value-of select="$className"/>Ptr ret;
2066 if (!connection.query(qs))
2068 return ret;
2071 MSW::CStoreResult *result = connection.storeResult().release();
2073 nlassert(result->getNumRows() &lt;= 1);
2074 if (result->getNumRows() == 1)
2076 ret.assign(new <xsl:value-of select="$className"/>, filename, lineNum);
2077 // ok, we have an object
2078 result->fetchRow();<xsl:text>
2080 </xsl:text> <xsl:for-each select="property[@db_col]">
2081 <xsl:choose>
2082 <xsl:when test="@enum='true' or @enum='smart'">
2083 <xsl:text> {
2084 std::string s;
2085 result->getField(</xsl:text><xsl:value-of select="position()-1"/>, s);
2086 ret->_<xsl:value-of select="@name"/> = <xsl:value-of select="@type"/><xsl:text>(s);
2088 </xsl:text>
2089 </xsl:when>
2090 <xsl:when test="@date='true'">
2091 <xsl:text> result->getDateField(</xsl:text><xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>)<xsl:text>;
2092 </xsl:text>
2093 </xsl:when>
2094 <xsl:when test="@md5='true'">
2095 <xsl:text> result->getMD5Field(</xsl:text><xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>)<xsl:text>;
2096 </xsl:text>
2097 </xsl:when>
2098 <xsl:otherwise>
2099 <xsl:text> result->getField(</xsl:text><xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>)<xsl:text>;
2100 </xsl:text>
2101 </xsl:otherwise>
2102 </xsl:choose>
2103 </xsl:for-each>
2105 ret->setPersistentState(NOPE::os_clean);
2108 delete result;
2110 return ret;
2113 <xsl:for-each select="parent[@relation = 'one-to-many']">
2114 <xsl:choose>
2115 <xsl:when test="@cont='map'">
2116 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)
2117 </xsl:when>
2118 <xsl:when test="@cont='vector'">
2119 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)
2120 </xsl:when>
2121 <xsl:otherwise>
2122 <xsl:message terminate="yes">
2123 ERROR : parent/child relation support only 'map' or 'vector' cont specification in <xsl:value-of select="$className"/>, <xsl:value-of select="@class"/> parent definition
2124 </xsl:message>
2125 </xsl:otherwise>
2126 </xsl:choose>
2128 std::string qs;
2129 qs = "SELECT ";
2130 <xsl:for-each select="..">
2131 <xsl:call-template name="makeColumListWithId"/>
2132 </xsl:for-each>
2133 qs += " FROM <xsl:value-of select="../database/@table"/>";
2134 qs += " WHERE <xsl:value-of select="@db_col"/> = '"+NLMISC::toString(parentId)+"'";
2136 if (!connection.query(qs))
2138 return false;
2141 CUniquePtr&lt;MSW::CStoreResult&gt; result(connection.storeResult());
2143 for (uint i=0; i&lt;result->getNumRows(); ++i)
2145 <xsl:value-of select="$className"/> *ret = new <xsl:value-of select="$className"/>();
2146 // ok, we have an object
2147 result->fetchRow();
2148 <xsl:for-each select="../property[@db_col]">
2149 <xsl:choose>
2150 <xsl:when test="@enum='true' or @enum='smart'">
2152 std::string s;
2153 result->getField(<xsl:value-of select="position()-1"/>, s);
2154 ret->_<xsl:value-of select="@name"/> = <xsl:value-of select="@type"/>(s);
2156 </xsl:when>
2157 <xsl:when test="@date='true'">
2158 result->getDateField(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2159 </xsl:when>
2160 <xsl:when test="@md5='true'">
2161 result->getMD5Field(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2162 </xsl:when>
2163 <xsl:otherwise>
2164 result->getField(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2165 </xsl:otherwise>
2166 </xsl:choose>
2167 </xsl:for-each>
2169 <xsl:value-of select="$className"/> *inCache = loadFromCache(ret->_<xsl:value-of select="$uniqueId"/>, true);
2170 if (inCache != NULL)
2172 <xsl:choose>
2173 <xsl:when test="@cont='map'">
2174 container.insert(std::make_pair(inCache->getObjectId(), <xsl:value-of select="$className"/>Ptr(inCache, filename, lineNum)));
2175 </xsl:when>
2176 <xsl:when test="@cont='vector'">
2177 container.push_back(<xsl:value-of select="$className"/>Ptr(inCache, filename, lineNum));
2178 </xsl:when>
2179 </xsl:choose>
2180 // no more needed
2181 delete ret;
2183 else
2185 ret->setPersistentState(NOPE::os_clean);
2186 <xsl:choose>
2187 <xsl:when test="@cont='map'">
2188 container.insert(std::make_pair(ret->getObjectId(), <xsl:value-of select="$className"/>Ptr(ret, filename, lineNum)));
2189 </xsl:when>
2190 <xsl:when test="@cont='vector'">
2191 container.push_back(<xsl:value-of select="$className"/>Ptr(ret, filename, lineNum));
2192 </xsl:when>
2193 </xsl:choose>
2197 return true;
2199 </xsl:for-each>
2201 <xsl:for-each select="parent[@relation = 'one-to-one']">
2202 <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)
2204 std::string qs;
2205 qs = "SELECT ";
2206 <xsl:for-each select="..">
2207 <xsl:call-template name="makeColumListWithId"/>
2208 </xsl:for-each>
2209 qs += " FROM <xsl:value-of select="../database/@table"/>";
2210 qs += " WHERE <xsl:value-of select="@db_col"/> = '"+NLMISC::toString(parentId)+"'";
2212 <xsl:value-of select="$className"/>Ptr ret;
2213 if (!connection.query(qs))
2215 childPtr = <xsl:value-of select="../@name"/>Ptr();
2216 return false;
2219 CUniquePtr&lt;MSW::CStoreResult&gt; result(connection.storeResult());
2221 // check that the data description is consistent with database content
2222 nlassert(result->getNumRows() &lt;= 1);
2224 if (result->getNumRows() == 1)
2226 <xsl:value-of select="$className"/> *object = new <xsl:value-of select="$className"/>;
2227 // ok, we have an object
2228 result->fetchRow();
2229 <xsl:for-each select="../property[@db_col]">
2230 <xsl:choose>
2231 <xsl:when test="@enum='true' or @enum='smart'">
2233 std::string s;
2234 result->getField(<xsl:value-of select="position()-1"/>, s);
2235 object->_<xsl:value-of select="@name"/> = <xsl:value-of select="@type"/>(s);
2237 </xsl:when>
2238 <xsl:when test="@date='true'">
2239 result->getDateField(<xsl:value-of select="position()-1"/>, object->_<xsl:value-of select="@name"/>);
2240 </xsl:when>
2241 <xsl:when test="@md5='true'">
2242 result->getMD5Field(<xsl:value-of select="position()-1"/>, ret->_<xsl:value-of select="@name"/>);
2243 </xsl:when>
2244 <xsl:otherwise>
2245 result->getField(<xsl:value-of select="position()-1"/>, object->_<xsl:value-of select="@name"/>);
2246 </xsl:otherwise>
2247 </xsl:choose>
2248 </xsl:for-each>
2250 <xsl:value-of select="$className"/> *inCache = loadFromCache(object->_<xsl:value-of select="$uniqueId"/>, true);
2251 if (inCache != NULL)
2253 ret.assign(inCache, filename, lineNum);
2254 // no more needed
2255 delete object;
2257 else
2259 object->setPersistentState(NOPE::os_clean);
2260 ret.assign(object, filename, lineNum);
2263 childPtr = ret;
2264 return true;
2267 // no result, but no error
2268 childPtr = <xsl:value-of select="../@name"/>Ptr();
2269 return true;
2271 </xsl:for-each>
2274 <xsl:for-each select="child_class[@relation = 'one-to-many']">
2275 bool <xsl:value-of select="$className"/>::load<xsl:value-of select="@name"/>(MSW::CConnection &amp;connection, const char *filename, uint32 lineNum)
2277 bool ret = true;
2278 if (_<xsl:value-of select="@name"/> != NULL)
2280 // the children are already loaded, just return true
2281 return true;
2284 // allocate the container
2285 <xsl:choose>
2286 <xsl:when test="@cont = 'map'"> _<xsl:value-of select="@name"/> = new std::map &lt; uint32, <xsl:value-of select="@type"/>Ptr &gt;;</xsl:when>
2287 <xsl:when test="@cont = 'vector'"> _<xsl:value-of select="@name"/> = new std::vector &lt; <xsl:value-of select="@type"/>Ptr &gt;;</xsl:when>
2288 </xsl:choose>
2290 // load the childs
2291 ret &amp;= <xsl:value-of select="@type"/>::loadChildrenOf<xsl:value-of select="../@name"/>(connection, getObjectId(), *_<xsl:value-of select="@name"/>, filename, lineNum);
2292 return ret;
2295 <xsl:choose>
2296 <xsl:when test="@cont = 'vector'">
2297 const std::vector&lt;<xsl:value-of select="@type"/>Ptr&gt; &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>() const
2299 nlassert(_<xsl:value-of select="@name"/> != NULL);
2300 return *_<xsl:value-of select="@name"/>;
2303 <xsl:value-of select="@type"/>Ptr &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>ByIndex(uint32 index) const
2305 nlassert(_<xsl:value-of select="@name"/> != NULL);
2306 nlassert(index &lt; _<xsl:value-of select="@name"/>->size());
2307 return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(_<xsl:value-of select="@name"/>->operator[](index));
2310 <xsl:value-of select="@type"/>Ptr &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>ById(uint32 id) const
2312 nlassert(_<xsl:value-of select="@name"/> != NULL);
2313 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());
2314 for (; first != last; ++first)
2316 const <xsl:value-of select="@type"/>Ptr &amp;child = *first;
2317 if (child->getObjectId() == id)
2319 return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(child);
2323 // no object with this id, return a null pointer
2324 static <xsl:value-of select="@type"/>Ptr nilPtr;
2326 return nilPtr;
2329 </xsl:when>
2330 <xsl:when test="@cont = 'map'">
2331 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
2333 nlassert(_<xsl:value-of select="@name"/> != NULL);
2334 return *_<xsl:value-of select="@name"/>;
2337 <xsl:value-of select="@type"/>Ptr &amp;<xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>ById(uint32 id) const
2339 nlassert(_<xsl:value-of select="@name"/> != NULL);
2340 std::map&lt;uint32, <xsl:value-of select="@type"/>Ptr&gt;::const_iterator it(_<xsl:value-of select="@name"/>->find(id));
2342 if (it == _<xsl:value-of select="@name"/>->end())
2344 // no object with this id, return a null pointer
2345 static <xsl:value-of select="@type"/>Ptr nilPtr;
2346 return nilPtr;
2349 return const_cast&lt; <xsl:value-of select="@type"/>Ptr &amp; &gt;(it->second);
2352 </xsl:when>
2353 <xsl:otherwise>
2354 <xsl:message terminate="yes">
2355 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>
2356 </xsl:text>
2357 </xsl:message>
2358 </xsl:otherwise>
2359 </xsl:choose>
2362 </xsl:for-each>
2363 <xsl:for-each select="child_class[@relation = 'one-to-one']">
2364 bool <xsl:value-of select="$className"/>::load<xsl:value-of select="@name"/>(MSW::CConnection &amp;connection, const char *filename, uint32 lineNum)
2366 if (_<xsl:value-of select="@name"/>Loaded)
2368 // the child is already loaded, just return true
2369 return true;
2371 bool ret = <xsl:value-of select="@type"/>::loadChildOf<xsl:value-of select="../@name"/>(connection, getObjectId(), _<xsl:value-of select="@name"/>, filename, lineNum);
2372 _<xsl:value-of select="@name"/>Loaded = true;
2373 return ret;
2376 /** Return the one child object (or null if not) */
2377 <xsl:value-of select="@type"/>Ptr <xsl:value-of select="$className"/>::get<xsl:value-of select="@name"/>()
2379 nlassert(_<xsl:value-of select="@name"/>Loaded);
2380 return _<xsl:value-of select="@name"/>;
2383 </xsl:for-each>
2384 </xsl:if>
2385 </xsl:template>
2389 <!-- ################################################################# -->
2390 <!-- ##### C++ Layer 3 interface generation (server mode) ### -->
2391 <!-- ################################################################# -->
2392 <!-- ##### header file #### -->
2393 <xsl:template match="callback_interface" mode="header">
2394 <xsl:call-template name="makeMasterDoc"/>
2395 <xsl:choose>
2396 <xsl:when test="@extend">
2397 class <xsl:value-of select="@name"/>Itf : public <xsl:value-of select="@extend"/>Itf
2398 </xsl:when>
2399 <xsl:otherwise>
2400 class <xsl:value-of select="@name"/>Itf <!--: public NLNET::CCallbackServer-->
2401 </xsl:otherwise>
2402 </xsl:choose>
2404 protected:
2405 <xsl:if test="not(@extend)">
2406 /// the callback server adaptor
2407 std::auto_ptr&lt;ICallbackServerAdaptor&gt; _CallbackServer;
2408 </xsl:if>
2409 void getCallbakArray(NLNET::TCallbackItem *&amp;arrayPtr, uint32 &amp;arraySize)
2411 static NLNET::TCallbackItem callbackArray[] =
2413 <xsl:for-each select="invoke"> { "<xsl:value-of select="@msg"/>", <xsl:value-of select="../@name"/>Itf::cb_<xsl:value-of select="@name"/> },
2414 </xsl:for-each>
2417 arrayPtr = callbackArray;
2418 arraySize = sizeofarray(callbackArray);
2421 static void _cbConnection(NLNET::TSockId from, void *arg)
2423 H_AUTO(<xsl:value-of select="@name"/>__cbConnection);
2424 <xsl:value-of select="@name"/>Itf *_this = reinterpret_cast&lt;<xsl:value-of select="@name"/>Itf *&gt;(arg);
2426 _this->on_<xsl:value-of select="@name"/>_Connection(from);
2429 static void _cbDisconnection(NLNET::TSockId from, void *arg)
2431 H_AUTO(<xsl:value-of select="@name"/>__cbDisconnection);
2432 <xsl:value-of select="@name"/>Itf *_this = reinterpret_cast&lt;<xsl:value-of select="@name"/>Itf *&gt;(arg);
2434 _this->on_<xsl:value-of select="@name"/>_Disconnection(from);
2438 public:
2439 /** Constructor, if you specify a replacement adaptor, then the object
2440 * become owner of the adaptor (and it will be released with the
2441 * interface).
2443 <xsl:if test="@extend">
2444 <xsl:text> </xsl:text><xsl:value-of select="@name"/>Itf(ICallbackServerAdaptor *replacementAdaptor = NULL)
2445 : <xsl:value-of select="@extend"/>Itf(replacementAdaptor)
2447 </xsl:if>
2448 <xsl:if test="not(@extend)">
2449 <xsl:text> </xsl:text><xsl:value-of select="@name"/>Itf(ICallbackServerAdaptor *replacementAdaptor = NULL)
2451 if (replacementAdaptor == NULL)
2453 // use default callback server
2454 _CallbackServer = std::auto_ptr&lt;ICallbackServerAdaptor&gt;(new CNelCallbackServerAdaptor(this));
2456 else
2458 // use the replacement one
2459 _CallbackServer = std::auto_ptr&lt;ICallbackServerAdaptor&gt;(replacementAdaptor);
2462 </xsl:if>
2463 virtual ~<xsl:value-of select="@name"/>Itf()
2467 /// Open the interface socket in the specified port
2468 void openItf(uint16 port)
2470 NLNET::TCallbackItem *arrayPtr;
2471 uint32 arraySize;
2473 <xsl:if test="@extend">
2474 // add callback array of the base interface class
2475 <xsl:value-of select="@extend"/>Itf::getCallbakArray(arrayPtr, arraySize);
2476 _CallbackServer->addCallbackArray(arrayPtr, arraySize);
2477 </xsl:if>
2479 getCallbakArray(arrayPtr, arraySize);
2480 _CallbackServer->addCallbackArray(arrayPtr, arraySize);
2482 _CallbackServer->setConnectionCallback (_cbConnection, this);
2483 _CallbackServer->setDisconnectionCallback (_cbDisconnection, this);
2485 _CallbackServer->init(port);
2488 /** Must be called evenly, update the network subclass to receive message
2489 * and dispatch method invokation.
2491 void update()
2493 H_AUTO(<xsl:value-of select="@name"/>_update);
2497 _CallbackServer->update();
2499 catch (...)
2501 nlwarning("<xsl:value-of select="@name"/> : Exception launch in callback server update");
2505 <xsl:for-each select="return">
2506 <xsl:call-template name="makeMethodDoc"/>
2507 void <xsl:value-of select="@name"/>(NLNET::TSockId dest<xsl:call-template name="makeParamList"/>)
2509 H_AUTO(<xsl:value-of select="@name"/>_<xsl:value-of select="@name"/>);
2510 #ifdef NL_DEBUG
2511 nldebug("<xsl:value-of select="../@name"/>::<xsl:value-of select="@name"/> called");
2512 #endif
2513 NLNET::CMessage message("<xsl:value-of select="@msg"/>");
2514 <xsl:for-each select="param">
2515 <xsl:call-template name="serialWrite"/>
2516 </xsl:for-each>
2517 _CallbackServer->send(message, dest);
2519 </xsl:for-each>
2521 <xsl:for-each select="invoke">
2522 static void cb_<xsl:value-of select="@name"/> (NLNET::CMessage &amp;message, NLNET::TSockId from, NLNET::CCallbackNetBase &amp;netbase)
2524 H_AUTO(<xsl:value-of select="@name"/>_on_<xsl:value-of select="@name"/>);
2525 #ifdef NL_DEBUG
2526 nldebug("<xsl:value-of select="../@name"/>::cb_<xsl:value-of select="@name"/> received from class '%s'", typeid(netbase).name());
2527 #endif
2528 ICallbackServerAdaptor *adaptor = static_cast&lt; ICallbackServerAdaptor *&gt;(netbase.getUserData());
2530 <xsl:value-of select="../@name"/>Itf *callback = (<xsl:value-of select="../@name"/>Itf *)adaptor->getContainerClass();
2532 if (callback == NULL)
2533 return;
2534 <xsl:for-each select="param">
2535 <xsl:if test="not(@array)">
2536 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
2537 </xsl:text>
2538 </xsl:if>
2539 <xsl:if test="@array = 'true'">
2540 <xsl:text> </xsl:text>std::vector&lt;<xsl:value-of select="@type"/>&gt;<xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
2541 </xsl:text>
2542 </xsl:if>
2543 </xsl:for-each>
2544 <xsl:for-each select="param">
2545 <xsl:call-template name="serialRead"/>
2546 </xsl:for-each>
2548 #ifdef NL_DEBUG
2549 nldebug("<xsl:value-of select="../@name"/>::cb_<xsl:value-of select="@name"/> : calling on_<xsl:value-of select="@name"/>");
2550 #endif
2552 <xsl:if test="not(return)">
2553 callback->on_<xsl:value-of select="@name"/>(from<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
2554 </xsl:if>
2555 <xsl:if test="return">
2556 <xsl:if test="not(return/@array)">
2557 <xsl:text> </xsl:text><xsl:value-of select="return/@type"/> retValue;
2558 </xsl:if>
2559 <xsl:if test="return/@array">
2560 <xsl:text> std::vector&lt;</xsl:text><xsl:value-of select="return/@type"/>&gt; retValue;
2561 </xsl:if>
2562 retValue = callback->on_<xsl:value-of select="@name"/>(from<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
2564 NLNET::CMessage retMsg("R_<xsl:value-of select="@msg"/>");
2565 <xsl:if test="not(return/@array)">
2566 nlWrite(retMsg, serial<xsl:value-of select="return/@serial"/>, retValue);
2567 </xsl:if>
2568 <xsl:if test="return/@array">
2569 nlWrite(retMsg, serialCont, retValue);
2570 </xsl:if>
2572 callback->_CallbackServer->send(retMsg, from);
2573 </xsl:if>
2575 </xsl:for-each>
2577 /// Connection callback : a new interface client connect
2578 virtual void on_<xsl:value-of select="@name"/>_Connection(NLNET::TSockId from) =0;
2579 /// Disconnection callback : one of the interface client disconnect
2580 virtual void on_<xsl:value-of select="@name"/>_Disconnection(NLNET::TSockId from) =0;
2582 <xsl:for-each select="invoke"><xsl:text>
2583 </xsl:text><xsl:call-template name="makeMethodDoc"/>
2584 <xsl:if test="not(return)">
2585 <xsl:text> virtual void on_</xsl:text><xsl:value-of select="@name"/>(NLNET::TSockId from<xsl:call-template name="makeParamList"/>) =0;
2586 </xsl:if>
2587 <xsl:if test="return">
2588 <xsl:if test="not(return/@array)">
2589 <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;
2590 </xsl:if>
2591 <xsl:if test="return/@array">
2592 <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;
2593 </xsl:if>
2594 </xsl:if>
2595 </xsl:for-each>
2598 <!-- Callback interface client class -->
2599 <xsl:call-template name="makeMasterDoc"/>
2600 /** This is the client side of the interface
2601 * Derive from this class to invoke method on the callback server
2603 <xsl:choose>
2604 <xsl:when test="@extend">
2605 class <xsl:value-of select="@name"/>ClientItf : public <xsl:value-of select="@extend"/>ClientItf
2606 </xsl:when>
2607 <xsl:otherwise>
2608 class <xsl:value-of select="@name"/>ClientItf <!--: public NLNET::CCallbackClient-->
2609 </xsl:otherwise>
2610 </xsl:choose>
2612 protected:
2613 <xsl:if test="not(@extend)">
2614 /// the callback client adaptor
2615 std::auto_ptr &lt; ICallbackClientAdaptor &gt; _CallbackClient;
2616 </xsl:if>
2618 void getCallbakArray(NLNET::TCallbackItem *&amp;arrayPtr, uint32 &amp;arraySize)
2620 <xsl:if test="not(return)">
2621 arrayPtr = NULL;
2622 arraySize = 0;
2623 </xsl:if>
2625 <xsl:if test="return">
2626 static NLNET::TCallbackItem callbackArray[] =
2628 <xsl:for-each select="return"> { "<xsl:value-of select="@msg"/>", <xsl:value-of select="../@name"/>ClientItf::cb_<xsl:value-of select="@name"/> },
2629 </xsl:for-each>
2632 arrayPtr = callbackArray;
2633 arraySize = sizeofarray(callbackArray);
2634 </xsl:if>
2637 static void _cbDisconnection(NLNET::TSockId from, void *arg)
2639 <xsl:value-of select="@name"/>ClientItf *_this = reinterpret_cast&lt;<xsl:value-of select="@name"/>ClientItf *&gt;(arg);
2641 _this->on_<xsl:value-of select="@name"/>Client_Disconnection(from);
2645 public:
2646 /// Retreive the message name for a given callback name
2647 static const std::string &amp;getMessageName(const std::string &amp;methodName)
2649 static std::map&lt;std::string, std::string&gt; messageNames;
2650 static bool initialized = false;
2651 if (!initialized)
2653 <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"/>")));
2654 </xsl:for-each>
2655 initialized = true;
2658 std::map &lt; std::string, std::string&gt;::const_iterator it(messageNames.find(methodName));
2659 if (it != messageNames.end())
2660 return it->second;
2662 <xsl:if test="@extend">
2663 // try with the base class
2664 return <xsl:value-of select="@extend"/>ClientItf::getMessageName(methodName);
2665 </xsl:if>
2666 <xsl:if test="not(@extend)">
2667 static std::string emptyString;
2669 return emptyString;
2670 </xsl:if>
2673 <xsl:if test="@extend">
2674 <xsl:text> </xsl:text><xsl:value-of select="@name"/>ClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL)
2675 : <xsl:value-of select="@extend"/>ClientItf(adaptorReplacement)
2677 </xsl:if>
2678 <xsl:if test="not(@extend)">
2679 <xsl:text> </xsl:text><xsl:value-of select="@name"/>ClientItf(ICallbackClientAdaptor *adaptorReplacement = NULL)
2681 if (adaptorReplacement == NULL)
2683 // use the default Nel adaptor
2684 _CallbackClient = std::auto_ptr &lt; ICallbackClientAdaptor &gt;(new CNelCallbackClientAdaptor(this));
2686 else
2688 // use the replacement one
2689 _CallbackClient = std::auto_ptr &lt; ICallbackClientAdaptor &gt;(adaptorReplacement);
2692 </xsl:if>
2693 /// Connect the interface client to the callback server at the specified address and port
2694 virtual void connectItf(NLNET::CInetAddress address)
2696 NLNET::TCallbackItem *arrayPtr;
2697 uint32 arraySize;
2699 static bool callbackAdded = false;
2700 if (!callbackAdded)
2702 <xsl:if test="@extend">
2703 // add callback array of the base interface class
2704 <xsl:value-of select="@extend"/>ClientItf::getCallbakArray(arrayPtr, arraySize);
2705 _CallbackClient->addCallbackArray(arrayPtr, arraySize);
2706 callbackAdded = true;
2707 // add callback array of this interface
2708 </xsl:if>
2709 getCallbakArray(arrayPtr, arraySize);
2710 _CallbackClient->addCallbackArray(arrayPtr, arraySize);
2713 _CallbackClient->setDisconnectionCallback (_cbDisconnection, this);
2715 _CallbackClient->connect(address);
2718 /** Must be called evenly, update the network subclass to receive message
2719 * and dispatch invokation returns.
2721 virtual void update()
2723 H_AUTO(<xsl:value-of select="@name"/>_update);
2727 _CallbackClient->update();
2729 catch (...)
2731 nlwarning("<xsl:value-of select="@name"/> : Exception launch in callback client update");
2735 <xsl:for-each select="invoke">
2736 <xsl:call-template name="makeMethodDoc"/>
2737 void <xsl:value-of select="@name"/>(<xsl:call-template name="makeParamListNoStartingComma"/>)
2739 #ifdef NL_DEBUG
2740 nldebug("<xsl:value-of select="../@name"/>Client::<xsl:value-of select="@name"/> called");
2741 #endif
2742 NLNET::CMessage message("<xsl:value-of select="@msg"/>");
2743 <xsl:for-each select="param">
2744 <xsl:call-template name="serialWrite"/>
2745 </xsl:for-each>
2746 _CallbackClient->send(message);
2748 </xsl:for-each>
2750 <xsl:for-each select="return">
2751 static void cb_<xsl:value-of select="@name"/> (NLNET::CMessage &amp;message, NLNET::TSockId from, NLNET::CCallbackNetBase &amp;netbase)
2753 #ifdef NL_DEBUG
2754 nldebug("<xsl:value-of select="../@name"/>Client::cb_<xsl:value-of select="@name"/> received from class '%s'", typeid(netbase).name());
2755 #endif
2756 ICallbackClientAdaptor *adaptor = static_cast&lt; ICallbackClientAdaptor *&gt;(netbase.getUserData());
2758 <xsl:value-of select="../@name"/>ClientItf *callback = (<xsl:value-of select="../@name"/>ClientItf *)adaptor->getContainerClass();
2760 if (callback == NULL)
2761 return;
2762 <xsl:for-each select="param">
2764 <xsl:if test="not(@array)">
2765 <xsl:text> </xsl:text><xsl:value-of select="@type"/><xsl:text> </xsl:text><xsl:value-of select="@name"/>;<xsl:text>
2766 </xsl:text>
2767 </xsl:if>
2769 <xsl:if test="@array = 'true'">
2770 <xsl:text> </xsl:text>std::vector&lt;<xsl:value-of select="@type"/>&gt; <xsl:value-of select="@name"/>;<xsl:text>
2771 </xsl:text>
2772 </xsl:if>
2774 </xsl:for-each>
2775 <xsl:for-each select="param">
2776 <xsl:call-template name="serialRead"/>
2777 </xsl:for-each>
2779 #ifdef NL_DEBUG
2780 nldebug("<xsl:value-of select="../@name"/>Client::cb_<xsl:value-of select="@name"/> : calling on_<xsl:value-of select="@name"/>");
2781 #endif
2783 callback->on_<xsl:value-of select="@name"/>(from<xsl:for-each select="param">, <xsl:value-of select="@name"/></xsl:for-each>);
2785 </xsl:for-each>
2787 /// Disconnection callback : the connection to the server is lost
2788 virtual void on_<xsl:value-of select="@name"/>Client_Disconnection(NLNET::TSockId from) =0;
2790 <xsl:for-each select="return"><xsl:text>
2791 </xsl:text><xsl:call-template name="makeMethodDoc"/>
2792 <xsl:text> virtual void on_</xsl:text><xsl:value-of select="@name"/>(NLNET::TSockId from<xsl:call-template name="makeParamList"/>) =0;
2793 </xsl:for-each>
2795 </xsl:template>
2798 <!-- ######################################################### -->
2799 <!-- ##### PHP Layer 3 interface generation ### -->
2800 <!-- ######################################################### -->
2801 <!-- ##### php file #### -->
2802 <xsl:template match="callback_interface[@caller = 'php']" mode="php">
2803 <xsl:if test=".//param[@type != 'uint32'
2804 and @type != 'uint8'
2805 and @type != 'std::string'
2806 and @enum != 'smart']">
2807 <xsl:message terminate="yes">
2808 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"/>'
2809 </xsl:message>
2810 </xsl:if>
2811 <xsl:text>&lt;?php
2812 /////////////////////////////////////////////////////////////////
2813 // WARNING : this is a generated file, don't change it !
2814 /////////////////////////////////////////////////////////////////
2816 require_once('../tools/nel_message.php');
2818 class </xsl:text><xsl:value-of select="@name"/> extends CCallbackClient
2820 <xsl:for-each select="invoke">
2821 function <xsl:value-of select="@name"/>(<xsl:call-template name="makePhpArgListNoFollow"/>)
2823 $msg = new CMessage;
2824 $msg->setName("<xsl:value-of select="@msg"/>");
2827 <xsl:for-each select="param">
2829 <xsl:choose>
2830 <xsl:when test="@php_serial">
2831 <xsl:call-template name="makeWriteSerial">
2832 <xsl:with-param name="msgName" select="'$msg'"/>
2833 <xsl:with-param name="varName" select="@name"/>
2834 <xsl:with-param name="serialName" select="concat('serial', @php_serial)"/>
2835 </xsl:call-template>
2836 </xsl:when>
2837 <xsl:when test="@enum">
2838 <xsl:call-template name="makeWriteSerial">
2839 <xsl:with-param name="msgName" select="'$msg'"/>
2840 <xsl:with-param name="varName" select="@name"/>
2841 <xsl:with-param name="serialName" select="'serialEnum'"/>
2842 </xsl:call-template>
2843 </xsl:when>
2844 <xsl:otherwise>
2845 <xsl:call-template name="makeWriteSerial">
2846 <xsl:with-param name="msgName" select="'$msg'"/>
2847 <xsl:with-param name="varName" select="@name"/>
2848 <xsl:with-param name="serialName" select="'serialUint32'"/>
2849 </xsl:call-template>
2850 </xsl:otherwise>
2851 </xsl:choose>
2852 </xsl:for-each>
2854 <xsl:if test="not(return)">
2855 return parent::sendMessage($msg);
2856 </xsl:if>
2857 <xsl:if test="return">
2858 <!-- this is a two way call -->
2859 $ret = "";
2860 $ret = parent::sendMessage($msg);
2861 if ($ret == false)
2863 // error during send
2864 $this->invokeError("<xsl:value-of select="@name"/>", "Error in 'sendMessage'");
2865 return false;
2868 $retMsg = parent::waitMessage();
2869 if ($ret == false)
2871 // error during send
2872 $this->invokeError("<xsl:value-of select="@name"/>", "Error in 'waitMessage'");
2873 return false;
2875 if (!($retMsg->MsgName === "R_<xsl:value-of select="@msg"/>"))
2877 // error during send
2878 $this->invokeError("<xsl:value-of select="@name"/>", "Invalid response, awaited 'R_<xsl:value-of select="@msg"/>', received '".$retMsg->MsgName."'");
2879 return false;
2882 // serial the return value
2883 <xsl:choose>
2884 <xsl:when test="return/@php_serial">
2885 <xsl:call-template name="makeReadSerial">
2886 <xsl:with-param name="paramNode" select="return"/>
2887 <xsl:with-param name="msgName" select="'$retMsg'"/>
2888 <xsl:with-param name="varName" select="'retValue'"/>
2889 <xsl:with-param name="serialName" select="concat('serial', return/@php_serial)"/>
2890 </xsl:call-template>
2891 </xsl:when>
2892 <xsl:when test="return/@enum">
2893 $<xsl:value-of select="@varName"/> = new <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@type"/>;
2894 <xsl:call-template name="makeReadSerial">
2895 <xsl:with-param name="paramNode" select="return"/>
2896 <xsl:with-param name="return"/>
2897 <xsl:with-param name="msgName" select="'$retMsg'"/>
2898 <xsl:with-param name="varName" select="'retValue'"/>
2899 <xsl:with-param name="serialName" select="'serialEnum'"/>
2900 </xsl:call-template>
2901 </xsl:when>
2902 <xsl:otherwise>
2903 <xsl:call-template name="makeReadSerial">
2904 <xsl:with-param name="paramNode" select="return"/>
2905 <xsl:with-param name="return"/>
2906 <xsl:with-param name="msgName" select="'$retMsg'"/>
2907 <xsl:with-param name="varName" select="'retValue'"/>
2908 <xsl:with-param name="serialName" select="'serialUint32'"/>
2909 </xsl:call-template>
2910 </xsl:otherwise>
2911 </xsl:choose>
2913 // return the return value
2914 return $retValue;
2915 </xsl:if>
2918 </xsl:for-each>
2920 function waitCallback()
2922 $message = parent::waitMessage();
2924 if ($message == false)
2925 return false;
2927 switch($message->MsgName)
2929 <xsl:for-each select="return"> case "<xsl:value-of select="@msg"/>":
2930 $this-><xsl:value-of select="@name"/>_skel($message);
2931 break;
2932 </xsl:for-each> default:
2933 return false;
2936 return true;
2939 <xsl:for-each select="return">
2940 function <xsl:value-of select="@name"/>_skel(&amp;$message)
2942 <xsl:for-each select="param">
2943 <xsl:text> </xsl:text>
2944 <xsl:choose>
2945 <xsl:when test="@php_serial">
2946 <xsl:call-template name="makeReadSerial">
2947 <xsl:with-param name="paramNode" select="."/>
2948 <xsl:with-param name="msgName" select=" '$message'"/>
2949 <xsl:with-param name="varName" select="@name"/>
2950 <xsl:with-param name="serialName" select="concat('serial', @php_serial)"/>
2951 </xsl:call-template>
2952 </xsl:when>
2953 <xsl:when test="@enum">
2954 $<xsl:value-of select="@name"/> = new <xsl:value-of select="//namespace/@name"/>_<xsl:value-of select="@type"/>;
2955 <xsl:call-template name="makeReadSerial">
2956 <xsl:with-param name="paramNode" select="."/>
2957 <xsl:with-param name="msgName" select=" '$message'"/>
2958 <xsl:with-param name="varName" select="@name"/>
2959 <xsl:with-param name="serialName" select="'serialEnum'"/>
2960 </xsl:call-template>
2961 </xsl:when>
2962 <xsl:otherwise>
2963 <xsl:call-template name="makeReadSerial">
2964 <xsl:with-param name="paramNode" select="."/>
2965 <xsl:with-param name="msgName" select=" '$message'"/>
2966 <xsl:with-param name="varName" select="@name"/>
2967 <xsl:with-param name="serialName" select="'serialUint32'"/>
2968 </xsl:call-template>
2969 </xsl:otherwise>
2970 </xsl:choose>
2971 </xsl:for-each>
2972 <xsl:text>
2973 $this-&gt;</xsl:text><xsl:value-of select="@name"/>(<xsl:call-template name="makePhpArgListNoFollow"/>);
2975 </xsl:for-each>
2977 /////////////////////////////////////////////////////////////////
2978 // Copy paste this part of code in your derived class
2979 // and implement code to ract to incoming message
2980 /////////////////////////////////////////////////////////////////
2981 <xsl:for-each select="return">
2982 <xsl:call-template name="makeMethodDoc"/>
2983 function <xsl:value-of select="@name"/>(<xsl:call-template name="makePhpArgListNoFollow"/>)
2987 </xsl:for-each> }
2988 <xsl:text>?&gt;
2989 </xsl:text>
2990 </xsl:template>
2993 <!-- ######################################### -->
2994 <!-- ##### PHP Read serialisation code ###### -->
2995 <!-- ######################################### -->
2997 <xsl:template name="makeReadSerial">
2998 <xsl:param name="paramNode"/>
2999 <xsl:param name="msgName"/>
3000 <xsl:param name="varName"/>
3001 <xsl:param name="serialName"/>
3004 <xsl:choose>
3005 <xsl:when test="$paramNode/@array"> $nbElem = 0;
3006 <xsl:value-of select="$msgName"/>->serialUInt32($nbElem);
3007 $<xsl:value-of select="$varName"/> = array();
3008 for ($i=0; $i&lt;$nbElem;$i++)
3010 <xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($item);
3011 $<xsl:value-of select="$varName"/>[] = $item;
3013 </xsl:when>
3014 <xsl:otherwise> <xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($<xsl:value-of select="$varName"/>);
3015 </xsl:otherwise>
3016 </xsl:choose>
3018 </xsl:template>
3020 <!-- ######################################### -->
3021 <!-- ##### PHP Write serialisation code ###### -->
3022 <!-- ######################################### -->
3024 <xsl:template name="makeWriteSerial">
3025 <xsl:param name="msgName"/>
3026 <xsl:param name="varName"/>
3027 <xsl:param name="serialName"/>
3029 <xsl:choose>
3030 <xsl:when test="@array"><xsl:text> </xsl:text><xsl:value-of select="$msgName"/>->serialUint32(count($<xsl:value-of select="@name"/>));
3031 foreach($<xsl:value-of select="$varName"/> as $key=>$value)
3032 <xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($value);
3033 </xsl:when>
3034 <xsl:otherwise><xsl:text> </xsl:text><xsl:value-of select="$msgName"/>-><xsl:value-of select="$serialName"/>($<xsl:value-of select="$varName"/>);
3035 </xsl:otherwise>
3036 </xsl:choose>
3037 </xsl:template>
3040 <!-- ######################################### -->
3041 <!-- ##### Make a php parameter list ###### -->
3042 <!-- ######################################### -->
3043 <xsl:template name="makePhpArgList">
3044 <xsl:for-each select="param">$<xsl:value-of select="@name"/>, </xsl:for-each>
3045 </xsl:template>
3047 <xsl:template name="makePhpArgListNoFollow">
3048 <xsl:for-each select="param">$<xsl:value-of select="@name"/><xsl:if test="position() != last()">, </xsl:if></xsl:for-each>
3049 </xsl:template>
3051 <!-- ################################################### -->
3052 <!-- ##### Generate a cpp non template smart ptr ###### -->
3053 <!-- ################################################### -->
3055 <xsl:template name="makePersistentPtrHeader">
3056 <xsl:param name="className"/>
3058 <xsl:variable name="ptrName" select="concat($className, 'Ptr')"/>
3061 class <xsl:value-of select="$ptrName"/>
3063 friend class <xsl:value-of select="$className"/>;
3065 const char *_FileName;
3066 uint32 _LineNum;
3068 // linked list of smart ptr
3069 <xsl:value-of select="$ptrName"/> *_NextPtr;
3070 <xsl:value-of select="$ptrName"/> *_PrevPtr;
3072 <xsl:value-of select="$className"/> *_Ptr;
3074 void linkPtr();
3076 void unlinkPtr();
3078 public:
3079 <xsl:value-of select="$ptrName"/>()
3080 : _FileName(NULL),
3081 _LineNum(0),
3082 _Ptr(NULL),
3083 _NextPtr(NULL),
3084 _PrevPtr(NULL)
3088 <xsl:value-of select="$ptrName"/>(const <xsl:value-of select="$ptrName"/> &amp;other, const char *filename, uint32 lineNum)
3089 : _FileName(filename),
3090 _LineNum(lineNum),
3091 _NextPtr(NULL),
3092 _PrevPtr(NULL)
3094 // point the same object
3095 _Ptr = other._Ptr;
3096 // insert the pointer in the list
3097 linkPtr();
3100 <xsl:value-of select="$ptrName"/>(const <xsl:value-of select="$ptrName"/> &amp;other)
3101 : _FileName(other._FileName),
3102 _LineNum(other._LineNum),
3103 _NextPtr(NULL),
3104 _PrevPtr(NULL)
3106 // point the same object
3107 _Ptr = other._Ptr;
3108 // insert the pointer in the list
3109 linkPtr();
3112 <xsl:value-of select="$ptrName"/>(<xsl:value-of select="$className"/> *objectPtr, const char *filename, uint32 lineNum)
3113 : _FileName(filename),
3114 _LineNum(lineNum),
3115 _NextPtr(NULL),
3116 _PrevPtr(NULL)
3118 _Ptr = objectPtr;
3120 linkPtr();
3123 <xsl:value-of select="$ptrName"/> &amp;assign(const <xsl:value-of select="$ptrName"/> &amp;other, const char *filename, uint32 lineNum)
3125 _FileName = filename;
3126 _LineNum = lineNum;
3128 unlinkPtr();
3129 _Ptr = other._Ptr;
3130 linkPtr();
3132 return *this;
3135 ~<xsl:value-of select="$ptrName"/>()
3137 unlinkPtr();
3140 <xsl:value-of select="$ptrName"/> &amp;assign(<xsl:value-of select="$className"/> *objectPtr, const char *filename, uint32 lineNum)
3142 _FileName = filename;
3143 _LineNum = lineNum;
3145 unlinkPtr();
3146 _Ptr = objectPtr;
3147 linkPtr();
3149 return *this;
3152 <xsl:value-of select="$ptrName"/> &amp;operator =(const <xsl:value-of select="$ptrName"/> &amp;other)
3154 return assign(other, __FILE__, __LINE__);
3157 <xsl:value-of select="$className"/> *operator ->()
3159 return _Ptr;
3161 const <xsl:value-of select="$className"/> *operator ->() const
3163 return _Ptr;
3166 bool operator == (const <xsl:value-of select="$ptrName"/> &amp;other) const
3168 return _Ptr == other._Ptr;
3170 bool operator != (const <xsl:value-of select="$ptrName"/> &amp;other) const
3172 return !operator ==(other);
3175 bool operator == (const <xsl:value-of select="$className"/> *object) const
3177 return _Ptr == object;
3179 bool operator != (const <xsl:value-of select="$className"/> *object) const
3181 return !operator ==(object);
3184 /// Less then comparator : comparison on pointer object address
3185 bool operator &lt; (const <xsl:value-of select="$ptrName"/> &amp;other) const
3187 return _Ptr &lt; other._Ptr;
3190 /// Used to walk thrue the linked list of pointer
3191 <xsl:value-of select="$ptrName"/> *getNextPtr()
3193 return _NextPtr;
3197 </xsl:template>
3199 <xsl:template name="makePersistentPtrCpp">
3200 <xsl:param name="className"/>
3201 <xsl:variable name="ptrName" select="concat($className, 'Ptr')"/>
3202 void <xsl:value-of select="$ptrName"/>::linkPtr()
3204 nlassert(_NextPtr == NULL);
3205 nlassert(_PrevPtr == NULL);
3206 if (_Ptr != NULL)
3208 _NextPtr = _Ptr->getFirstPtr();
3209 if (_NextPtr != NULL)
3211 _PrevPtr = _NextPtr->_PrevPtr;
3212 _PrevPtr->_NextPtr = this;
3213 _NextPtr->_PrevPtr = this;
3215 else
3217 _NextPtr = this;
3218 _PrevPtr = this;
3219 _Ptr->setFirstPtr(this);
3224 void <xsl:value-of select="$ptrName"/>::unlinkPtr()
3226 if (_NextPtr == NULL)
3228 nlassert(_PrevPtr == NULL);
3229 return;
3232 if (_Ptr != NULL)
3234 if (_NextPtr == this)
3236 nlassert(_PrevPtr == this);
3237 // last pointer !
3238 _Ptr->setFirstPtr(NULL);
3240 else
3242 if (_Ptr->getFirstPtr() == this)
3244 // the first ptr is the current one, we need to switch to next one
3245 _Ptr->setFirstPtr(_NextPtr);
3250 if (_NextPtr != this)
3252 nlassert(_PrevPtr != this);
3254 _NextPtr->_PrevPtr = _PrevPtr;
3255 _PrevPtr->_NextPtr = _NextPtr;
3257 _NextPtr = NULL;
3258 _PrevPtr = NULL;
3260 </xsl:template>
3261 </xsl:stylesheet>