Caelum
CaelumScriptTranslator.cpp
1 /*
2 This file is part of Caelum.
3 See http://www.ogre3d.org/wiki/index.php/Caelum
4 
5 Copyright (c) 2006-2008 Caelum team. See Contributors.txt for details.
6 
7 Caelum is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Caelum 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 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with Caelum. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "CaelumPrecompiled.h"
22 #include "CaelumPrerequisites.h"
23 
24 #if CAELUM_SCRIPT_SUPPORT
25 
26 #include "CaelumScriptTranslator.h"
27 #include "CaelumSystem.h"
28 #include "CaelumExceptions.h"
29 
30 using namespace Ogre;
31 
32 namespace Caelum
33 {
34  PropScriptResource::PropScriptResource
35  (
36  Ogre::ResourceManager* creator, const Ogre::String& name, Ogre::ResourceHandle handle,
37  const Ogre::String& group, bool isManual, Ogre::ManualResourceLoader* loader
38  ):
39  Ogre::Resource (creator, name, handle, group, isManual, loader)
40  {
41  //Ogre::LogManager::getSingleton().logMessage(
42  // "PropScriptResource::PropScriptResource");
43  }
44 
45  PropScriptResource::~PropScriptResource() {
46  //Ogre::LogManager::getSingleton().logMessage(
47  // "PropScriptResource::~PropScriptResource");
48  }
49 
50  PropScriptResourceManager::PropScriptResourceManager() {
51  mLoadOrder = 1000;
52  mResourceType = "PropertyScript";
53  }
54 
55  PropScriptResource* PropScriptResourceManager::createImpl(
56  const String& name, ResourceHandle handle, const String& group,
57  bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams)
58  {
59  //Ogre::LogManager::getSingleton().logMessage(
60  // "PropScriptResourceManager::createImpl");
61  return new PropScriptResource (this, name, handle, group, isManual, loader);
62  }
63 
64  TypeDescriptorScriptTranslator::TypeDescriptorScriptTranslator (TypeDescriptor* typeDescriptor):
65  mTypeDescriptor(typeDescriptor)
66  {
67  }
68 
69  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
70  ScriptCompiler* compiler,
71  PropertyAbstractNode* prop,
72  bool& value)
73  {
74  if (prop->values.empty ()) {
75  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
76  return false;
77  }
78  if (prop->values.size () > 1) {
79  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
80  prop->name + " must have at most 1 argument");
81  return false;
82  }
83  if (!Ogre::ScriptTranslator::getBoolean(prop->values.front(), &value)) {
84  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
85  prop->values.front()->getValue() + " is not a valid number");
86  return false;
87  }
88  return true;
89  }
90 
91  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
92  ScriptCompiler* compiler,
93  PropertyAbstractNode* prop,
94  ColourValue& value)
95  {
96  if (prop->values.empty ()) {
97  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
98  return false;
99  }
100  if (prop->values.size () > 4) {
101  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
102  prop->name + " must have at most 4 arguments");
103  return false;
104  }
105  if (prop->values.size () < 3) {
106  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
107  prop->name + " must have at least 3 arguments");
108  }
109  if (!getColour(prop->values.begin(), prop->values.end(), &value)) {
110  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
111  prop->name + " requires a colour argument");
112  }
113  return true;
114  }
115 
116  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
117  ScriptCompiler* compiler,
118  PropertyAbstractNode* prop,
119  float& value)
120  {
121  if (prop->values.empty ()) {
122  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
123  return false;
124  }
125  if (prop->values.size () > 1) {
126  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
127  prop->name + " must have at most 1 argument");
128  return false;
129  }
130  if (!Ogre::ScriptTranslator::getFloat(prop->values.front(), &value)) {
131  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
132  prop->values.front()->getValue() + " is not a valid number");
133  return false;
134  }
135  return true;
136  }
137 
138  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
139  ScriptCompiler* compiler,
140  PropertyAbstractNode* prop,
141  int& value)
142  {
143  if (prop->values.empty ()) {
144  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
145  return false;
146  }
147  if (prop->values.size () > 1) {
148  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
149  prop->name + " must have at most 1 argument");
150  return false;
151  }
152  if (!Ogre::ScriptTranslator::getInt(prop->values.front(), &value)) {
153  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
154  prop->values.front()->getValue() + " is not a valid integer");
155  return false;
156  }
157  return true;
158  }
159 
160  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
161  ScriptCompiler* compiler,
162  PropertyAbstractNode* prop,
163  double& value)
164  {
165  if (prop->values.empty ()) {
166  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
167  return false;
168  }
169  if (prop->values.size () > 1) {
170  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
171  prop->name + " must have at most 1 argument");
172  return false;
173  }
174  // We do need a string stream here for the extra precision.
175  std::stringstream strStream (std::string(prop->values.front()->getValue()));
176  strStream >> value;
177  if (strStream.fail()) {
178  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
179  prop->values.front()->getValue() + " is not a valid number");
180  return false;
181  }
182  return true;
183  }
184 
185  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
186  ScriptCompiler* compiler,
187  PropertyAbstractNode* prop,
188  Ogre::Degree& value)
189  {
190  if (prop->values.size () == 0) {
191  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
192  return false;
193  }
194  if (prop->values.size () > 3) {
195  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
196  prop->name + " must have at most 3 arguments");
197  return false;
198  }
199  // Allow 3 components.
200  float degMinSec[3] = { 0, 0, 0 };
201  int k = 0;
202  for (AbstractNodeList::const_iterator it = prop->values.begin(), endIt = prop->values.end(); it != endIt; ++it, ++k) {
203  if (!Ogre::ScriptTranslator::getFloat(*it, &degMinSec[k])) {
204  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
205  (*it)->getValue () + " is not a valid number");
206  return false;
207  }
208  }
209  value = Ogre::Degree(degMinSec[0] + degMinSec[1] / 60.0 + degMinSec[2] / 3600);
210  return true;
211  }
212 
213  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
214  ScriptCompiler* compiler,
215  PropertyAbstractNode* prop,
216  Ogre::String& value)
217  {
218  if (prop->values.size () == 0) {
219  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
220  return false;
221  }
222  if (prop->values.size () > 1) {
223  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
224  prop->name + " must have at most 1 arguments");
225  return false;
226  }
227  if (!Ogre::ScriptTranslator::getString(prop->values.front(), &value)) {
228  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
229  prop->values.front()->getValue() + " is not a valid string");
230  return false;
231  }
232  return true;
233  }
234 
235  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
236  ScriptCompiler* compiler,
237  PropertyAbstractNode* prop,
238  Ogre::Vector3& value)
239  {
240  if (prop->values.size () == 0) {
241  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
242  return false;
243  }
244  if (prop->values.size () > 3) {
245  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
246  prop->name + " must have at most 3 arguments");
247  return false;
248  }
249  float floats[3];
250  if (!Ogre::ScriptTranslator::getFloats(prop->values.begin(), prop->values.end(), floats, 3)) {
251  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
252  "incorrect vector parameters.");
253  return false;
254  }
255  value.x = floats[0];
256  value.y = floats[1];
257  value.z = floats[2];
258  return true;
259  }
260 
261  bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
262  ScriptCompiler* compiler,
263  PropertyAbstractNode* prop,
264  Ogre::Vector2& value)
265  {
266  if (prop->values.size () == 0) {
267  compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
268  return false;
269  }
270  if (prop->values.size () > 2) {
271  compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
272  prop->name + " must have at most 3 arguments");
273  return false;
274  }
275  float floats[2];
276  if (!Ogre::ScriptTranslator::getFloats(prop->values.begin(), prop->values.end(), floats, 2)) {
277  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
278  "incorrect vector parameters.");
279  return false;
280  }
281  value.x = floats[0];
282  value.y = floats[1];
283  return true;
284  }
285 
286  template<class T>
287  static bool tryHandlePropertyType (
288  ScriptCompiler* compiler, PropertyAbstractNode* propNode,
289  void* targetObject, const ValuePropertyDescriptor* propDesc)
290  {
291  if (propDesc->getValueTypeId () == typeid(T)) {
292  T val;
293  if (TypeDescriptorScriptTranslator::getPropValueOrAddError (compiler, propNode, val)) {
294  propDesc->setValue (targetObject, Ogre::Any(val));
295  }
296  return true;
297  }
298  return false;
299  }
300 
301  void TypeDescriptorScriptTranslator::translateProperty (
302  ScriptCompiler* compiler,
303  PropertyAbstractNode* prop,
304  void* targetObject,
305  const TypeDescriptor* typeDescriptor)
306  {
307  const ValuePropertyDescriptor* propDesc = typeDescriptor->getPropertyDescriptor (prop->name);
308  if (!propDesc) {
309  compiler->addError (ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line,
310  "property \"" + prop->name + "\" not recognized; missing from type descriptor.");
311  return;
312  }
313  if (!propDesc->canSetValue ()) {
314  compiler->addError (ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line,
315  "property \"" + prop->name + "\" is read-only and can't be set from a script.");
316  return;
317  }
318 
319  //LogManager::getSingleton ().logMessage ("TypeDescriptorScriptTranslator::translateProperty"
320  // " name '" + prop->name + "'");
321 
322  bool handled = false
323  || tryHandlePropertyType<int> (compiler, prop, targetObject, propDesc)
324  || tryHandlePropertyType<float> (compiler, prop, targetObject, propDesc)
325  || tryHandlePropertyType<double> (compiler, prop, targetObject, propDesc)
326  || tryHandlePropertyType<bool> (compiler, prop, targetObject, propDesc)
327  || tryHandlePropertyType<Ogre::Degree> (compiler, prop, targetObject, propDesc)
328  || tryHandlePropertyType<Ogre::String> (compiler, prop, targetObject, propDesc)
329  || tryHandlePropertyType<Ogre::Vector3> (compiler, prop, targetObject, propDesc)
330  || tryHandlePropertyType<Ogre::Vector2> (compiler, prop, targetObject, propDesc)
331  || tryHandlePropertyType<Ogre::ColourValue> (compiler, prop, targetObject, propDesc);
332 
333  if (!handled) {
334  compiler->addError (ScriptCompiler::CE_UNEXPECTEDTOKEN, prop->file, prop->line,
335  "property \"" + prop->name + "\" is found in type descriptor but has "
336  "unsupported type. Mangled typeid is '" + propDesc->getValueTypeId().name() + "'");
337  }
338  }
339 
340  void TypeDescriptorScriptTranslator::translate (ScriptCompiler* compiler, const AbstractNodePtr& node)
341  {
342  //LogManager::getSingleton ().logMessage ("TypeDescriptorScriptTranslator::translate begin");
343 
344  // Check type descriptor was set.
345  assert (getTypeDescriptor () && "Type descriptor must be set before we can translate.");
346 
347  // Fetch target object.
348  ObjectAbstractNode *objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
349  assert (!objNode->context.isEmpty ());
350  void* targetObject = any_cast<void*> (objNode->context);
351  assert (targetObject);
352 
353  for (AbstractNodeList::iterator i = objNode->children.begin(); i != objNode->children.end(); ++i)
354  {
355  if ((*i)->type == ANT_PROPERTY)
356  {
357  PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
358 
359  translateProperty (compiler, prop, targetObject, getTypeDescriptor());
360  }
361  else if((*i)->type == ANT_OBJECT)
362  {
363  compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, (*i)->file, (*i)->line);
364  }
365  }
366 
367  //LogManager::getSingleton ().logMessage ("TypeDescriptorScriptTranslator::translate end");
368  }
369 
370  CaelumSystemScriptTranslator::CaelumSystemScriptTranslator ():
371  mResourceManager(),
372  mTranslationTarget(0),
373  mTranslationTargetFound(false),
374  mTypeDescriptor(0)
375  {
376  }
377 
378  void CaelumSystemScriptTranslator::setTranslationTarget (CaelumSystem* target, const Ogre::String& name)
379  {
380  assert (target != 0);
381  this->mTranslationTarget = target;
382  this->mTranslationTargetName = name;
383  this->mTranslationTargetFound = false;
384  }
385 
386  void CaelumSystemScriptTranslator::clearTranslationTarget () {
387  this->mTranslationTarget = 0;
388  this->mTranslationTargetName.clear();
389  this->mTranslationTargetFound = false;
390  }
391 
392  void CaelumSystemScriptTranslator::translate (ScriptCompiler* compiler, const AbstractNodePtr& node)
393  {
394  //LogManager::getSingleton ().logMessage ("CaelumSystemScriptTranslator::translate begin");
395 
396  ObjectAbstractNode *objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
397 
398  CaelumSystem* sys = 0;
399 
400  // Check for a translation target.
401  if (this->getTranslationTarget ()) {
402  sys = this->getTranslationTarget ();
403 
404  // Check for a name match.
405  if (this->getTranslationTargetName () != objNode->name) {
406  //LogManager::getSingleton ().logMessage (
407  // "Caelum: Skipped " + objNode->cls + " name " + objNode->name + " while loading");
408  return;
409  }
410 
411  // Clear the target; this ensure that properties which are not
412  // mentioned are set to their default values.
413  // We only do this after we found a target; this ensure that if
414  // the target is not found it's not modified either.
415  sys->clear();
416 
417  //LogManager::getSingleton ().logMessage (
418  // "Caelum: Found " + objNode->cls + " name " + objNode->name + "; filling properties.");
419  mTranslationTargetFound = true;
420  } else if (this->getResourceManager ()) {
421  // If we don't have a target but have a resource manager then create a resource.
422  //LogManager::getSingleton ().logMessage (
423  // "Caelum: Saved " + objNode->cls + " name " + objNode->name + " as a resource");
424  PropScriptResourceManager* mgr = this->getResourceManager ();
425 #if OGRE_VERSION >= 0x00010900
426  ResourcePtr resource = mgr->createResource (objNode->name, compiler->getResourceGroup());
427 #else
428  ResourcePtr resource = mgr->create (objNode->name, compiler->getResourceGroup());
429 #endif
430  resource->_notifyOrigin (objNode->file);
431  return;
432  }
433 
434  objNode->context = sys;
435 
436  for (AbstractNodeList::iterator i = objNode->children.begin(); i != objNode->children.end(); ++i)
437  {
438  if ((*i)->type == ANT_PROPERTY)
439  {
440  PropertyAbstractNode *prop = reinterpret_cast<PropertyAbstractNode*>((*i).get());
441 
442  // Properties implemented through type descriptor.
443  TypeDescriptorScriptTranslator::translateProperty(
444  compiler, prop,
445  static_cast<void*>(sys),
446  getTypeDescriptor ());
447  }
448  else if((*i)->type == ANT_OBJECT)
449  {
450  ObjectAbstractNode *childObjNode = reinterpret_cast<ObjectAbstractNode*>((*i).get());
451 
452  //LogManager::getSingleton ().logMessage ("CaelumSystemScriptTranslator::translate child object"
453  // " value '" + childObjNode->getValue () + "'"
454  // " name '" + childObjNode->name + "'"
455  // " cls '" + childObjNode->cls + "'"
456  // " base '" + childObjNode->base + "'");
457 
458  // Only allow declarations with one class token; like "moon { }"
459 #if OGRE_VERSION < 0x010700
460  if (childObjNode->name.empty () == false || childObjNode->base.empty () == false) {
461 #else
462  if (childObjNode->name.empty () == false || childObjNode->bases.size () != 0) {
463 #endif
464  compiler->addError (
465  ScriptCompiler::CE_FEWERPARAMETERSEXPECTED,
466  childObjNode->file, childObjNode->line,
467  "caelum_sky_system components can't have names or bases");
468  continue;
469  }
470  const String& className = childObjNode->cls;
471 
472  try {
473  if (className == "sun") {
474  sys->setSun (new Sun (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
475  childObjNode->context = static_cast<void*> (sys->getSun ());
476  } else if (className == "sky_dome") {
477  sys->setSkyDome (new SkyDome (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
478  childObjNode->context = static_cast<void*>(sys->getSkyDome ());
479  } else if (className == "moon") {
480  sys->setMoon (new Moon (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
481  childObjNode->context = static_cast<void*>(sys->getMoon ());
482  } else if (className == "ground_fog") {
483  sys->setGroundFog (new GroundFog (sys->getSceneMgr (), sys->getCaelumCameraNode ()));
484  childObjNode->context = static_cast<void*>(sys->getGroundFog ());
485  } else if (className == "depth_composer") {
486  sys->setDepthComposer (new DepthComposer (sys->getSceneMgr ()));
487  childObjNode->context = static_cast<void*>(sys->getDepthComposer ());
488  } else if (className == "point_starfield") {
489  sys->setPointStarfield (new PointStarfield (sys->getSceneMgr (), sys->getCaelumCameraNode()));
490  childObjNode->context = static_cast<void*>(sys->getPointStarfield ());
491  } else if (className == "precipitation") {
492  sys->setPrecipitationController (new PrecipitationController (sys->getSceneMgr ()));
493  childObjNode->context = static_cast<void*>(sys->getPrecipitationController ());
494  } else if (className == "cloud_system") {
495  sys->setCloudSystem (new CloudSystem (sys->getSceneMgr (), sys->getCaelumGroundNode ()));
496  childObjNode->context = static_cast<void*>(sys->getCloudSystem ());
497  } else {
498  LogManager::getSingleton ().logMessage ("CaelumSystemScriptTranslator::translate "
499  "unknown child object class '" + className + "'");
500  }
501  } catch (Caelum::UnsupportedException& ex) {
502  // Catch all unsupported exceptions and report them.
503  // This should usually happen because the proper shaders are not supported by hardware.
504  //
505  // Script parsing should still succeed.
506  compiler->addError (
507  ScriptCompiler::CE_UNSUPPORTEDBYRENDERSYSTEM,
508  childObjNode->file, childObjNode->line,
509  "Failed to create component \"" + className + "\": " + ex.getFullDescription ());
510  continue;
511  }
512  processNode (compiler, *i);
513  }
514  }
515 
516  //LogManager::getSingleton ().logMessage ("SkySystemScriptTranslator::translate END");
517  }
518 
519  void CloudSystemScriptTranslator::translate (ScriptCompiler* compiler, const AbstractNodePtr& node)
520  {
521  //LogManager::getSingleton ().logMessage ("SkySystemScriptTranslator::translate begin");
522 
523  ObjectAbstractNode *objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
524  assert (!objNode->context.isEmpty ());
525  void* rawTargetObject = any_cast<void*> (objNode->context);
526  assert (rawTargetObject);
527 
528  CloudSystem* target = static_cast<CloudSystem*>(rawTargetObject);
529 
530  for (AbstractNodeList::iterator i = objNode->children.begin(); i != objNode->children.end(); ++i)
531  {
532  if ((*i)->type == ANT_PROPERTY)
533  {
534  compiler->addError (
535  ScriptCompiler::CE_INVALIDPARAMETERS,
536  objNode->file, objNode->line,
537  "cloud_system doesn't have any properties");
538  }
539  else if((*i)->type == ANT_OBJECT)
540  {
541  ObjectAbstractNode *childObjNode = reinterpret_cast<ObjectAbstractNode*>((*i).get());
542 
543  /*
544  LogManager::getSingleton ().logMessage ("CloudSystemScriptTranslator::translate child object"
545  " value '" + childObjNode->getValue () + "'"
546  " name '" + childObjNode->name + "'"
547  " cls '" + childObjNode->cls + "'"
548  " base '" + childObjNode->base + "'");
549  */
550 
551  const Ogre::String& className = childObjNode->cls;
552 
553  if (className == "cloud_layer") {
554  // Don't allow names.
555 #if OGRE_VERSION < 0x010700
556  if (childObjNode->base.empty () == false) {
557 #else
558  if (childObjNode->bases.size () != 0) {
559 #endif
560  compiler->addError (
561  ScriptCompiler::CE_FEWERPARAMETERSEXPECTED,
562  childObjNode->file, childObjNode->line,
563  "cloud_layer can't have a base");
564  continue;
565  }
566  // Height here is irrelevant. It's silly to have it as a FlatCloudLayer ctor parameter.
567  target->createLayerAtHeight (0);
568  FlatCloudLayer* layer = target->getLayer (target->getLayerCount () - 1);
569 
570  // Add the new layer as a context for the object node.
571  // This will eventually pass to the TypeDescriptorScriptTranslator for a cloud layer.
572  childObjNode->context = static_cast<void*>(layer);
573  } else {
574  LogManager::getSingleton ().logMessage ("CloudSystemScriptTranslator::translate "
575  "unknown child object class '" + className + "'");
576  }
577  processNode (compiler, *i);
578  }
579  }
580 
581  //LogManager::getSingleton ().logMessage ("CloudSystemScriptTranslator::translate END");
582  }
583 
584  CaelumScriptTranslatorManager::CaelumScriptTranslatorManager
585  (
586  CaelumDefaultTypeDescriptorData* typeData
587  ):
588  mCaelumSystemTranslator(),
589  mCloudSystemTranslator(),
590  mFlatCloudLayerTranslator(typeData->FlatCloudLayerTypeDescriptor),
591  mSunTranslator(typeData->BaseSkyLightTypeDescriptor),
592  mMoonTranslator(typeData->BaseSkyLightTypeDescriptor),
593  mPointStarfieldTranslator(typeData->PointStarfieldTypeDescriptor),
594  mGroundFogTranslator(typeData->GroundFogTypeDescriptor),
595  mDepthComposerTranslator(typeData->DepthComposerTypeDescriptor),
596  mPrecipitationTranslator(typeData->PrecipitationTypeDescriptor),
597  mSkyDomeTranslator(typeData->SkyDomeTypeDescriptor)
598  {
599  mCaelumSystemTranslator.setTypeDescriptor(typeData->CaelumSystemTypeDescriptor);
600 
601  // Build translator map to member translators.
602  mTranslatorMap.insert (std::make_pair ("caelum_sky_system", &mCaelumSystemTranslator));
603  mTranslatorMap.insert (std::make_pair ("cloud_system", &mCloudSystemTranslator));
604  mTranslatorMap.insert (std::make_pair ("cloud_layer", &mFlatCloudLayerTranslator));
605  mTranslatorMap.insert (std::make_pair ("sun", &mSunTranslator));
606  mTranslatorMap.insert (std::make_pair ("moon", &mMoonTranslator));
607  mTranslatorMap.insert (std::make_pair ("point_starfield", &mPointStarfieldTranslator));
608  mTranslatorMap.insert (std::make_pair ("ground_fog", &mGroundFogTranslator));
609  mTranslatorMap.insert (std::make_pair ("depth_composer", &mDepthComposerTranslator));
610  mTranslatorMap.insert (std::make_pair ("precipitation", &mPrecipitationTranslator));
611  mTranslatorMap.insert (std::make_pair ("sky_dome", &mSkyDomeTranslator));
612  }
613 
614  size_t CaelumScriptTranslatorManager::getNumTranslators () const {
615  // Turns out this is never called.
616  assert(0 && "This method should be removed from Ogre::ScriptTranslatorManager");
617  return mTranslatorMap.size ();
618  }
619 
620  void CaelumScriptTranslatorManager::_setPropScriptResourceManager (PropScriptResourceManager* mgr)
621  {
622  mCaelumSystemTranslator.setResourceManager (mgr);
623  }
624 
625  ScriptTranslator* CaelumScriptTranslatorManager::getTranslator (const AbstractNodePtr& node)
626  {
627  //LogManager::getSingleton ().logMessage ("CaelumScriptTranslatorManager::getTranslator");
628  if (node->type == ANT_ATOM) {
629  //ObjectAbstractNode* atomNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
630  //LogManager::getSingleton ().logMessage ("CaelumScriptTranslatorManager::getTranslator atom node " + atomNode->getValue ());
631  } else if (node->type == ANT_OBJECT) {
632  ObjectAbstractNode* objNode = reinterpret_cast<ObjectAbstractNode*>(node.get());
633  //LogManager::getSingleton ().logMessage ("CaelumScriptTranslatorManager::getTranslator object node " + objNode->getValue ());
634 
635  // Pass down the context.
636  ScriptTranslatorMap::const_iterator it = mTranslatorMap.find(objNode->cls);
637  if (it != mTranslatorMap.end()) {
638  return it->second;
639  }
640  }
641 
642  // Not found in this manager.
643  return 0;
644  }
645 }
646 
647 #endif // CAELUM_SCRIPT_SUPPORT
Exception class for unsupported features.
Caelum namespace.
Definition: Astronomy.cpp:24