Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / georges / form_loader.cpp
blob7a56f7bf91f2bfe98f8e7a19094bf34ebb47d04e
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdgeorges.h"
22 #include "nel/misc/file.h"
23 #include "nel/misc/path.h"
24 #include "nel/misc/i_xml.h"
26 #include "nel/georges/u_form.h"
28 #include "nel/georges/form_loader.h"
29 #include "nel/georges/type.h"
30 #include "nel/georges/form.h"
31 #include "nel/georges/form_dfn.h"
33 #ifdef DEBUG_NEW
34 #define new DEBUG_NEW
35 #endif
37 using namespace NLMISC;
38 using namespace std;
40 namespace NLGEORGES
43 // ***************************************************************************
45 void warning (bool exception, const char *format, ... );
47 // ***************************************************************************
48 // UFormLoader
49 // ***************************************************************************
51 UFormLoader *UFormLoader::createLoader ()
53 return new CFormLoader;
56 // ***************************************************************************
58 void UFormLoader::releaseLoader (UFormLoader *loader)
60 delete ((CFormLoader*)loader);
63 // ***************************************************************************
64 // CFormLoader
65 // ***************************************************************************
66 CFormLoader::~CFormLoader()
70 CType *CFormLoader::loadType (const std::string &filename)
72 // Lower string filename
73 string lowerStr = toLowerAscii(filename);
74 lowerStr = CFile::getFilename (lowerStr);
76 // Already in the map ?
77 TTypeMap::iterator ite = _MapType.find (lowerStr);
78 if (ite != _MapType.end() && (ite->second != NULL) )
80 // Return the pointer
81 return ite->second;
83 else
85 // Create the type
86 CType *type = new CType;
88 // Load the type
89 try
91 // Open the file
92 string name = CPath::lookup (filename, false, false);
93 if (name.empty())
94 name = filename;
95 CIFile file;
96 if (file.open (name))
98 // Init an xml stream
99 CIXml read;
100 read.init (file);
102 // Read the type
103 type->read (read.getRootNode ());
105 else
107 // Output error
108 warning (false, "loadType", "Can't open the form file (%s).", filename.c_str());
110 // Delete the type
111 delete type;
112 type = NULL;
115 catch (const Exception &e)
117 // Output error
118 warning (false, "loadType", "Error while loading the form (%s): %s", filename.c_str(), e.what());
120 // Delete the type
121 delete type;
122 type = NULL;
125 // Loaded ?
126 if (type)
128 // Insert a new entry
129 _MapType[lowerStr]= type;
130 ite = _MapType.find (lowerStr);
131 //CType *typeType = ite->second;
132 // int toto = 0;
134 return type;
138 // ***************************************************************************
140 CFormDfn *CFormLoader::loadFormDfn (const std::string &filename, bool forceLoad)
142 // Lower string filename
143 string lowerStr = toLowerAscii(filename);
144 lowerStr = CFile::getFilename (lowerStr);
146 // Already in the map ?
147 TFormDfnMap::iterator ite = _MapFormDfn.find (lowerStr);
148 if (ite != _MapFormDfn.end() && ite->second)
150 // Return the pointer
151 return ite->second;
153 else
155 // Create the formDfn
156 CFormDfn *formDfn = new CFormDfn;
158 // Insert the form first
159 _MapFormDfn[lowerStr] = formDfn;
161 // Load the type
164 // Open the file
165 string name = CPath::lookup (filename, false, false);
166 if (name.empty())
167 name = filename;
168 CIFile file;
169 if (file.open (name))
171 // Init an xml stream
172 CIXml read;
173 read.init (file);
175 // Read the type
176 formDfn->read (read.getRootNode (), *this, forceLoad, filename);
178 else
180 // Output error
181 warning (false, "loadFormDfn", "Can't open the form file (%s).", filename.c_str());
183 // Delete the formDfn
184 delete formDfn;
185 formDfn = NULL;
186 _MapFormDfn.erase (lowerStr);
189 catch (const Exception &e)
191 // Output error
192 warning (false, "loadFormDfn", "Error while loading the form (%s): %s", filename.c_str(), e.what());
194 // Delete the formDfn
195 delete formDfn;
196 formDfn = NULL;
197 _MapFormDfn.erase (lowerStr);
200 return formDfn;
204 // ***************************************************************************
206 UForm *CFormLoader::loadForm (const std::string &filename)
208 // Lower string filename
209 string lowerStr = toLowerAscii((string)filename);
210 lowerStr = CFile::getFilename (lowerStr);
212 // Already in the map ?
213 TFormMap::iterator ite = _MapForm.find (lowerStr);
214 if (ite != _MapForm.end() && ite->second)
216 // Return the pointer
217 return (CForm*)ite->second;
219 else
221 // Create the form
222 CForm *form = new CForm;
224 // Insert the form first
225 _MapForm[lowerStr] = form;
227 // Load the type
230 // Get the form DFN filename
231 string name = CFile::getFilename (filename);
232 string::size_type index = name.rfind ('.');
233 if (index == string::npos)
235 // Output error
236 warning (false, "loadForm", "Form name is invalid (%s). It should have the extension of its DFN type.", name.c_str ());
238 // Delete the form
239 delete form;
240 form = NULL;
241 _MapForm.erase (lowerStr);
243 name = name.substr (index+1);
244 name += ".dfn";
246 // Load the dfn
247 CSmartPtr<CFormDfn> dfn = loadFormDfn (name, false);
248 if (dfn)
250 // Open the file
251 name = CPath::lookup (filename, false, false);
252 if (name.empty())
253 name = filename;
254 CIFile file;
255 if (file.open (name))
257 // Init an xml stream
258 CIXml read;
259 read.init (file);
261 // Read the form
262 form->read (read.getRootNode (), *this, dfn, filename);
264 else
266 // Output error
267 warning (false, "loadForm", "Can't open the form file (%s).", filename.c_str());
269 // Delete the form
270 delete form;
271 form = NULL;
272 _MapForm.erase (lowerStr);
275 else
277 // Output error
278 warning (false, "loadForm", "Can't open the dfn file (%s).", name.c_str ());
280 // Delete the form
281 delete form;
282 form = NULL;
283 _MapForm.erase (lowerStr);
286 catch (const Exception &e)
288 // Output error
289 warning (false, "loadForm", "Error while loading the form (%s): %s", filename.c_str(), e.what());
291 // Delete the form
292 delete form;
293 form = NULL;
294 _MapForm.erase (lowerStr);
297 return form;
301 // ***************************************************************************
303 UFormDfn *CFormLoader::loadFormDfn (const std::string &filename)
305 return loadFormDfn (filename, false);
308 // ***************************************************************************
310 UType *CFormLoader::loadFormType (const std::string &filename)
312 return loadType (filename);
315 // ***************************************************************************
317 void CFormLoader::warning (bool exception, const std::string &function, const char *format, ... ) const
319 // Make a buffer string
320 va_list args;
321 va_start( args, format );
322 char buffer[1024];
323 vsnprintf( buffer, 1024, format, args );
324 va_end( args );
326 // Set the warning
327 NLGEORGES::warning (exception, "(CFormLoader::%s) : %s", function.c_str(), buffer);
330 // ***************************************************************************
332 } // NLGEORGES