PageRenderTime 25ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/Project/SceneObject/KELuaBehavior.cpp

https://github.com/Langkamp/KabalaEngine
C++ | 319 lines | 189 code | 49 blank | 81 comment | 25 complexity | 16f05722d90f141d13d3f369cb4ab679 MD5 | raw file
  1. /*---------------------------------------------------------------------------*\
  2. * Kabala Engine *
  3. * *
  4. * Copyright (C) 2009-2010 by David Kabala *
  5. * *
  6. * authors: David Kabala (djkabala@gmail.com), Eric Langkamp, Robert Goetz *
  7. * *
  8. \*---------------------------------------------------------------------------*/
  9. /*---------------------------------------------------------------------------*\
  10. * License *
  11. * *
  12. * This library is free software; you can redistribute it and/or modify it *
  13. * under the terms of the GNU General Public License as published *
  14. * by the Free Software Foundation, version 3. *
  15. * *
  16. * This library is distributed in the hope that it will be useful, but *
  17. * WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
  19. * Library General Public License for more details. *
  20. * *
  21. * You should have received a copy of the GNU General Public *
  22. * License along with this library; if not, write to the Free Software *
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
  24. * *
  25. \*---------------------------------------------------------------------------*/
  26. /*---------------------------------------------------------------------------*\
  27. * Changes *
  28. * *
  29. * *
  30. * *
  31. * *
  32. * *
  33. * *
  34. \*---------------------------------------------------------------------------*/
  35. //---------------------------------------------------------------------------
  36. // Includes
  37. //---------------------------------------------------------------------------
  38. #include <cstdlib>
  39. #include <cstdio>
  40. #define KE_COMPILEKABALAENGINELIB
  41. #include <OpenSG/OSGConfig.h>
  42. #include "KELuaBehavior.h"
  43. #include "KELuaBehaviorType.h"
  44. #include <OpenSG/OSGLuaManager.h>
  45. #include <OpenSG/OSG_wrap.h>
  46. #include <OpenSG/OSGFilePathAttachment.h>
  47. #include <OpenSG/OSGContainerUtils.h>
  48. #include <fstream>
  49. #include <sstream>
  50. #include "LuaBindings/KELuaBindings.h"
  51. #include <boost/algorithm/string.hpp>
  52. OSG_BEGIN_NAMESPACE
  53. // Documentation for this class is emitted in the
  54. // OSGLuaBehaviorBase.cpp file.
  55. // To modify it, please change the .fcd file (OSGLuaBehavior.fcd) and
  56. // regenerate the base file.
  57. /***************************************************************************\
  58. * Class variables *
  59. \***************************************************************************/
  60. /***************************************************************************\
  61. * Class methods *
  62. \***************************************************************************/
  63. void LuaBehavior::initMethod(InitPhase ePhase)
  64. {
  65. Inherited::initMethod(ePhase);
  66. if(ePhase == TypeObject::SystemPost)
  67. {
  68. }
  69. }
  70. LuaBehaviorType* const LuaBehavior::getLuaBehaviorType(void) const
  71. {
  72. return dynamic_cast<LuaBehaviorType* const>(theBehaviorType);
  73. }
  74. void LuaBehavior::initEvents(SceneObject* const rootSceneObject)
  75. {
  76. getLuaBehaviorType()->registerWithScene(rootSceneObject->getParentScene());
  77. eventsInitted = true;
  78. }
  79. void LuaBehavior::initLinks(SceneObject* const rootSceneObject)
  80. {
  81. for(UInt32 i(0); i < getLuaBehaviorType()->getSourceContainers().size(); ++i)
  82. {
  83. if(getLuaBehaviorType()->getSourceContainers()[i].compare("*")==0)
  84. {
  85. UInt64 uId(0);//rootSceneObject->getParentScene()->getId();
  86. //uId <<= 32;
  87. const EventDescription* desc = rootSceneObject->getParentScene()->getProducerType().findEventDescription(getLuaBehaviorType()->getEventLinks()[i]);
  88. if(desc != NULL)
  89. {
  90. uId |= desc->getEventId();
  91. _FunctionsMap[uId] = std::vector<std::string>();
  92. std::string NestedTableFunction(getLuaBehaviorType()->getLuaFunctionNames()[i]);
  93. if(NestedTableFunction.empty())
  94. {
  95. SWARNING << "The lua function bound to the " << desc->getName() << " produced event of " << getLuaBehaviorType()->getName() << " is empty." << getLuaBehaviorType()->getEventLinks()[i] << endLog;
  96. }
  97. else
  98. {
  99. std::string::size_type subStrStart(0),
  100. subStrEnd(0);
  101. //Loop through all nested tables
  102. while(subStrEnd != std::string::npos)
  103. {
  104. subStrEnd = NestedTableFunction.find_first_of('.',subStrStart);
  105. _FunctionsMap[uId].push_back(NestedTableFunction.substr(subStrStart,subStrEnd-subStrStart));
  106. if(subStrEnd != std::string::npos) ++subStrEnd;
  107. subStrStart = subStrEnd;
  108. }
  109. //BUG: For some reason using the split algorithm is causing a
  110. //misaligned stack error on OS X builds of the engine. This
  111. //does not occur for the use of split in dependent libraries.
  112. //So for now the split is done by hand.
  113. //boost::algorithm::split( , NestedTableFunction, boost::algorithm::is_any_of(std::string(".")) );
  114. }
  115. attachHandlers(rootSceneObject->getParentScene());
  116. }
  117. else
  118. {
  119. SWARNING << "LuaBehavior could not find event " << getLuaBehaviorType()->getEventLinks()[i] << endLog;
  120. }
  121. }
  122. else
  123. {
  124. FieldContainerRefPtr fc = getFieldContainer(getLuaBehaviorType()->getSourceContainers()[i]);
  125. UInt64 uId = fc->getId();
  126. uId <<= 32;
  127. const EventDescription* desc = fc->getProducerType().findEventDescription(getLuaBehaviorType()->getEventLinks()[i]);
  128. if(desc != NULL)
  129. {
  130. std::string NestedTableFunction(getLuaBehaviorType()->getLuaFunctionNames()[i]);
  131. if(NestedTableFunction.empty())
  132. {
  133. SWARNING << "The lua function bound to the " << desc->getName() << " produced event of " << fc->getProducerType().getName() << " is empty." << getLuaBehaviorType()->getEventLinks()[i] << endLog;
  134. }
  135. else
  136. {
  137. uId |= desc->getEventId();
  138. _FunctionsMap[uId] = std::vector<std::string>();
  139. std::string::size_type subStrStart(0),
  140. subStrEnd(0);
  141. //Loop through all nested tables
  142. while(subStrEnd != std::string::npos)
  143. {
  144. subStrEnd = NestedTableFunction.find_first_of('.',subStrStart);
  145. _FunctionsMap[uId].push_back(NestedTableFunction.substr(subStrStart,subStrEnd-subStrStart));
  146. if(subStrEnd != std::string::npos) ++subStrEnd;
  147. subStrStart = subStrEnd;
  148. }
  149. //BUG: For some reason using the split algorithm is causing a
  150. //misaligned stack error on OS X builds of the engine. This
  151. //does not occur for the use of split in dependent libraries.
  152. //So for now the split is done by hand.
  153. //boost::algorithm::split( _FunctionsMap[uId], NestedTableFunction, boost::algorithm::is_any_of(std::string(".")) );
  154. }
  155. UInt32 EventID(fc->getProducerType().getProducedEventId(getLuaBehaviorType()->getEventLinks()[i]));
  156. fc->connectEvent(EventID, boost::bind(&LuaBehavior::handleDepFieldContainerEvent, this, _1, EventID));
  157. linksMade++;
  158. }
  159. else
  160. {
  161. SWARNING << "LuaBehavior could not find event " << getLuaBehaviorType()->getEventLinks()[i] << endLog;
  162. }
  163. }
  164. }
  165. }
  166. void LuaBehavior::depBehaviorProducedEvent(EventDetails* const e, UInt32 producedEventID)
  167. {
  168. UInt64 uId(producedEventID);
  169. callLuaFunctionForEvent(uId,e,producedEventID);
  170. }
  171. void LuaBehavior::depFieldContainerProducedEvent(EventDetails* const details, UInt32 producedEventID)
  172. {
  173. UInt64 uId(details->getSource()->getId());
  174. uId <<= 32;
  175. uId |= producedEventID;
  176. callLuaFunctionForEvent(uId,details,producedEventID);
  177. }
  178. void LuaBehavior::callLuaFunctionForEvent(UInt64 MapId,
  179. EventDetails* const details,
  180. UInt32 ProducedEventID)
  181. {
  182. //Get the Lua state
  183. lua_State *LuaState(LuaManager::the()->getLuaState());
  184. const std::vector<std::string>& funcPath = _FunctionsMap[MapId];
  185. //Get the Lua function to be called
  186. for(UInt32 i(0) ; i<funcPath.size() ; ++i)
  187. {
  188. if(i == 0)
  189. {
  190. lua_pushstring(LuaState,funcPath[i].c_str()); //push the name of the table on the stack
  191. lua_gettable(LuaState, LUA_GLOBALSINDEX); //Push The table onto the stack
  192. }
  193. else
  194. {
  195. //Check if the the value given is a table
  196. if(!lua_istable(LuaState, -1))
  197. {
  198. lua_pop(LuaState, 1); //Pop the value off the stack
  199. std::string TablePath("");
  200. for(UInt32 j(0) ; j<i ; ++j)
  201. {
  202. if(j!=0) TablePath += ".";
  203. TablePath += funcPath[j];
  204. }
  205. SWARNING << TablePath << " cannot be referenced in lua because it is not a table" << std::endl;
  206. return;
  207. }
  208. lua_pushstring(LuaState,funcPath[i].c_str()); //push the name of the table on the stack
  209. lua_gettable(LuaState, -2); //Push The table onto the stack
  210. //Remove the original table from the stack
  211. lua_remove(LuaState, -2);
  212. }
  213. }
  214. //Check if the the value given is a function
  215. if(!lua_isfunction(LuaState, -1))
  216. {
  217. lua_pop(LuaState, 1); //Pop the value off the stack
  218. std::string TablePath("");
  219. for(UInt32 i(0) ; i<funcPath.size() ; ++i)
  220. {
  221. if(i!=0) TablePath += ".";
  222. TablePath += funcPath[i];
  223. }
  224. SWARNING << TablePath << " cannot be referenced in lua because it is not a function" << std::endl;
  225. return;
  226. }
  227. //Push on the arguments
  228. push_FieldContainer_on_lua(LuaState, details); //Argument 1: the Event
  229. push_Behavior_on_lua(LuaState, this); //Argument 2: the The Behavior it came from
  230. lua_pushnumber(LuaState,ProducedEventID); //Argument 3: the ProducedEvent ID
  231. //Execute the Function
  232. //
  233. // |------3 arguments to function
  234. // |
  235. // | |---0 arguments returned
  236. // | |
  237. // V V
  238. LuaManager::the()->checkError(lua_pcall(LuaState, 3, 0, 0));
  239. }
  240. /***************************************************************************\
  241. * Instance methods *
  242. \***************************************************************************/
  243. /*-------------------------------------------------------------------------*\
  244. - private -
  245. \*-------------------------------------------------------------------------*/
  246. /*----------------------- constructors & destructors ----------------------*/
  247. LuaBehavior::LuaBehavior(void) :
  248. Inherited()
  249. {
  250. }
  251. LuaBehavior::LuaBehavior(const LuaBehavior &source) :
  252. Inherited(source)
  253. {
  254. }
  255. LuaBehavior::~LuaBehavior(void)
  256. {
  257. }
  258. /*----------------------------- class specific ----------------------------*/
  259. void LuaBehavior::changed(ConstFieldMaskArg whichField,
  260. UInt32 origin,
  261. BitVector details)
  262. {
  263. Inherited::changed(whichField, origin, details);
  264. }
  265. void LuaBehavior::dump( UInt32 ,
  266. const BitVector ) const
  267. {
  268. SLOG << "Dump LuaBehavior NI" << std::endl;
  269. }
  270. OSG_END_NAMESPACE