Update lua versions
[ryzomcore.git] / nel / samples / georges / main.cpp
blobcccd5a7fa25f6eb31acdf5d14b5036dcb51990a6
1 /**
2 * \file main.cpp
3 * \date October 2004
4 * \author Matt Raykowski
6 * This sample shows how to load a Georges form and read parts from it.
7 */
9 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
10 // Copyright (C) 2010 Winch Gate Property Limited
12 // This source file has been modified by the following contributors:
13 // Copyright (C) 2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
15 // This program is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU Affero General Public License as
17 // published by the Free Software Foundation, either version 3 of the
18 // License, or (at your option) any later version.
20 // This program is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU Affero General Public License for more details.
25 // You should have received a copy of the GNU Affero General Public License
26 // along with this program. If not, see <http://www.gnu.org/licenses/>.
29 // System Includes
31 #include <stdio.h>
34 // NeL Includes
36 #include "nel/misc/debug.h"
38 #include "nel/georges/u_form_loader.h"
39 #include "nel/georges/u_form.h"
40 #include "nel/georges/u_form_elm.h"
41 #include "nel/georges/load_form.h"
43 #ifndef GF_DIR
44 # define GF_DIR "."
45 #endif
47 struct TPositionData
49 uint X, Y, Z;
51 /// This class must be serializable for the form to be packed.
52 void serial(NLMISC::IStream &f)
54 f.serial(X);
55 f.serial(Y);
56 f.serial(Z);
60 struct TSampleConfig
62 /// Load a form, if necessary, and store its data in the members of this class.
63 void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const NLMISC::CSheetId &sheetId)
65 readForm(form);
68 void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const std::string &sheetId)
70 readForm(form);
73 void readForm(const NLMISC::CSmartPtr<NLGEORGES::UForm> &form)
75 nlinfo("Loading a sample config object.");
76 // The system has already loaded the form and parsed it using a loader. So get the root node:
77 NLGEORGES::UFormElm &root = form->getRootNode();
79 // And start loading the form values into the object.
80 root.getValueByName(TestVal1, ".TestVal1");
81 root.getValueByName(TestVal2, ".TestVal2");
83 root.getValueByName(PosData.X,"PositionData.x");
84 root.getValueByName(PosData.Y,"PositionData.y");
85 root.getValueByName(PosData.Z,"PositionData.z");
87 // Get the array called "TestArray"
88 NLGEORGES::UFormElm *testArray;
89 root.getNodeByName(&testArray, ".TestArray");
90 if(testArray != NULL) {
91 // Get the size of the array.
92 uint size;
93 testArray->getArraySize(size);
95 // Cycle through the atoms in the array
96 for(uint idx=0 ; idx<size ; idx++) {
97 std::string arrayValue;
99 // Get the value of the array.
100 testArray->getArrayValue(arrayValue, idx);
101 // And insert it into our container.
102 TestArray.push_back(arrayValue);
106 // And so on. We'll skip the rest of the sheet, you get the idea.
107 // ...
110 /// This class must be serializable for the form to be packed.
111 void serial(NLMISC::IStream &f)
113 f.serial(TestVal1);
114 f.serial(TestVal2);
115 f.serial(PosData);
116 f.serialCont(TestArray);
119 /// This is called whenever the loader needs to remove an old sheet.
120 void removed()
125 /// This is used to make sure that changes in form/loader versions are correctly handled. This must be > 0.
126 static uint getVersion() { return 1; }
128 uint32 TestVal1;
129 uint32 TestVal2;
131 TPositionData PosData;
133 std::vector<std::string> TestArray;
136 /// This contains the TSampleConfig sheets.
137 std::map<NLMISC::CSheetId, TSampleConfig> MySampleConfigsSheets;
138 std::map<std::string, TSampleConfig> MySampleConfigs;
140 int main(void)
142 new NLMISC::CApplicationContext;
144 // get a pointer ready for the form loader.
145 NLGEORGES::UFormLoader *formLoader = NULL;
147 NLMISC::CPath::addSearchPath(GF_DIR, false, false);
149 try {
150 // set the name of the form you're going to load.
151 std::string sampleConfigFile = NLMISC::CPath::lookup("default.sample_config", false);
153 // check to see if CPath found the config.
154 if (!sampleConfigFile.empty()) {
155 // we'll use this to test retrieving vars.
156 bool res;
158 // get a form loader.
159 formLoader = NLGEORGES::UFormLoader::createLoader();
161 // this will hold the form we load - it must be contained in a smart pointer.
162 NLMISC::CSmartPtr<NLGEORGES::UForm> form;
164 // load the form.
165 form = formLoader->loadForm(sampleConfigFile.c_str());
167 // get the root of the form.
168 NLGEORGES::UFormElm &root = form->getRootNode();
170 // retrieve the two test values
171 uint32 testVal1, testVal2, badVar1;
172 root.getValueByName(testVal1, ".TestVal1");
173 root.getValueByName(testVal2, ".TestVal2");
175 // try and get a var that doesn't exist.
176 res=root.getValueByName(badVar1, ".Foobar");
177 if(res) {
178 nlinfo("This should never have matched.");
179 exit(1);
182 // and output them
183 nlinfo("Test Value 1: %d",testVal1);
184 nlinfo("Test Value 2: %d",testVal2);
185 nlinfo("Foo Retrieval was: %s", res ? "true" : "false");
187 // Retrieve data from a root-level named struct
188 uint xTest, yTest, zTest;
189 root.getValueByName(xTest,"PositionData.x");
190 root.getValueByName(yTest,"PositionData.y");
191 root.getValueByName(zTest,"PositionData.z");
192 nlinfo("Retrieved Position Data (x,y,z): %d, %d, %d",xTest,yTest,zTest);
194 // get a reference to the TestArray array...
195 NLGEORGES::UFormElm *testArray;
196 res=root.getNodeByName(&testArray, ".TestArray");
198 nlinfo("TestArray retrieval returned: %s", res ? "true" : "false");
199 // make sure it was there.
200 if(testArray != NULL) {
201 // get the size of the array.
202 uint size;
203 testArray->getArraySize(size);
205 // cycle through the atoms in the array
206 for(uint idx=0 ; idx<size ; idx++) {
207 // string to store our array values in.
208 std::string arrayValue;
210 // and get the value of the array, we know it's a string.
211 testArray->getArrayValue(arrayValue, idx);
213 nlinfo("Found TestArray atom: %s",arrayValue.c_str());
215 } else {
216 if(res==true)
217 nlinfo("TestArray wasn't configured properly but was found, double check the form.");
218 else
219 nlinfo("Something's wrong, the TestArray is missing from the form.");
222 // Next grab a set of structures from an array.
223 NLGEORGES::UFormElm *coolFiles;
224 res=root.getNodeByName(&coolFiles, ".CoolFilesInfo");
226 nlinfo("Retrieving CoolFilesInfo returned: %s", res ? "true" : "false");
227 if(coolFiles != NULL) {
228 uint size;
229 coolFiles->getArraySize(size);
231 // cycle through the structs in the array.
232 for(uint idx=0 ; idx<size ; idx++) {
233 // storage for our vars in the structs
234 std::string name, shortname;
235 uint rank, toptenrank;
237 // since we know the structure of the file, we know the array contains structs
238 // retrieve the struct for use.
239 NLGEORGES::UFormElm *files;
240 coolFiles->getArrayNode(&files, idx);
242 // we can now access this struct in the array as a root.
243 files->getValueByName(rank, ".Ranking");
244 files->getValueByName(toptenrank, ".TopTenRanking");
245 files->getValueByName(name, ".Name");
246 files->getValueByName(shortname, ".ShortName");
247 nlinfo("Retrieved struct %d: |%s| - %s at %d (%d)", idx, name.c_str(), shortname.c_str(), rank, toptenrank);
250 } else {
251 if(res==true)
252 nlinfo("CoolFilesInfo was found, but might have been entered incorrectly, double check the form.");
253 else
254 nlinfo("CoolFilesInfo wasn't found or there was a syntax error loading your form.");
257 // we can also access elements of an array by their backet identifier.
258 std::string bbool1, bbool2;
259 root.getValueByName(bbool1, ".TestByBracket[0]");
260 root.getValueByName(bbool2, ".TestByBracket[1]");
261 nlinfo("Bool Backet 1: %s, Bool Bracket 2: %s",bbool1.c_str(), bbool2.c_str());
263 // likewise you can access structures by index and dot notation. take the CoolFilesInfo.
264 // the following should return 1, the ranking for the Nevrax Presents element.
265 // and the 2nd one should return 'Crazy Car Jump' from that element.
266 uint rankTest;
267 std::string nameTest;
268 root.getValueByName(rankTest, ".CoolFilesInfo[2].Ranking");
269 root.getValueByName(nameTest, ".CoolFilesInfo[1].ShortName");
270 nlinfo("Retrieved .CoolFilesInfo[2].Ranking using bracket and dot notation: %d", rankTest);
271 nlinfo("Retrieved .CoolFilesInfo[1].ShortName using bracket and dot notation: %s", nameTest.c_str());
273 // if you set a value to a node name that doesn't exist, it's created. after running this you will see it listed in the form:
274 uint writeValue;
276 // first lets see if we can find it:
277 res=root.getValueByName(writeValue,".WriteVal");
278 if(res) // if it existed, save the value and increment it.
279 writeValue++;
280 else
281 writeValue=3;
283 // now set the value. created tells us if the value was creaed or just updated.
284 bool created;
285 root.setValueByName(writeValue,".WriteVal",&created);
286 if(created) {
287 nlinfo("WriteVal wasn't found and was created.");
288 } else {
289 nlinfo("Updated WriteVal, it already existed in the form.");
292 // and finally save the form out in case we made changes.
293 // if you're accessing a form read-only (not using set*) you can skip this.
294 NLMISC::COFile saveSample(sampleConfigFile);
295 form->write(saveSample);
296 nlinfo("Saved sample config file.");
297 } else {
298 // CPath didn't find the file, just print an error and exit.
299 nlinfo("Couldn't find the config file.");
300 exit(1);
303 // finished, unload the form loader.
304 NLGEORGES::UFormLoader::releaseLoader(formLoader);
306 } catch(...) {
307 // something went wrong, unload the form loader.
308 nlinfo("Caught an exception, quitting.");
309 NLGEORGES::UFormLoader::releaseLoader(formLoader);
312 // Now demonstrate the packed sheet system.
313 nlinfo("Begin loading packed sheets.");
314 ::loadForm( "sample_config", "sample_configs.packed_sheets", MySampleConfigs, true, false);
315 nlinfo("Number of sheets loaded: %d", MySampleConfigs.size());
317 // Now demonstrate the packed sheet system using CSheetId's and the sheet_id.bin file.
318 nlinfo("Load packed sheets using CSheetId and the sheet_id.bin");
319 ::loadForm( "sample_config", "sample_configs_sheets.packed_sheets", MySampleConfigsSheets, true, false);
320 nlinfo("Number of sheets loaded with CSheetId's: %d", MySampleConfigsSheets.size());