ScriptComponent.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Scene/Components/ScriptComponent.h>
  6. #include <AnKi/Scene/SceneGraph.h>
  7. #include <AnKi/Resource/ResourceManager.h>
  8. #include <AnKi/Resource/ScriptResource.h>
  9. #include <AnKi/Script/ScriptManager.h>
  10. #include <AnKi/Script/ScriptEnvironment.h>
  11. namespace anki
  12. {
  13. ANKI_SCENE_COMPONENT_STATICS(ScriptComponent)
  14. ScriptComponent::ScriptComponent(SceneNode* node)
  15. : SceneComponent(node, getStaticClassId())
  16. , m_node(node)
  17. {
  18. ANKI_ASSERT(node);
  19. }
  20. ScriptComponent::~ScriptComponent()
  21. {
  22. m_node->getAllocator().deleteInstance(m_env);
  23. }
  24. Error ScriptComponent::loadScriptResource(CString fname)
  25. {
  26. // Load
  27. ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(fname, m_script));
  28. // Create the env
  29. if(m_env)
  30. {
  31. m_node->getAllocator().deleteInstance(m_env);
  32. }
  33. m_env = m_node->getAllocator().newInstance<ScriptEnvironment>();
  34. ANKI_CHECK(m_env->init(&m_node->getSceneGraph().getScriptManager()));
  35. // Exec the script
  36. ANKI_CHECK(m_env->evalString(m_script->getSource()));
  37. return Error::NONE;
  38. }
  39. Error ScriptComponent::update(SceneNode& node, Second prevTime, Second crntTime, Bool& updated)
  40. {
  41. ANKI_ASSERT(&node == m_node);
  42. updated = false;
  43. if(m_env == nullptr)
  44. {
  45. return Error::NONE;
  46. }
  47. lua_State* lua = &m_env->getLuaState();
  48. // Push function name
  49. lua_getglobal(lua, "update");
  50. // Push args
  51. LuaBinder::pushVariableToTheStack(lua, &node);
  52. lua_pushnumber(lua, prevTime);
  53. lua_pushnumber(lua, crntTime);
  54. // Do the call (3 arguments, 1 result)
  55. if(lua_pcall(lua, 3, 1, 0) != 0)
  56. {
  57. ANKI_SCENE_LOGE("Error running ScriptComponent's \"update\": %s", lua_tostring(lua, -1));
  58. return Error::USER_DATA;
  59. }
  60. if(!lua_isnumber(lua, -1))
  61. {
  62. ANKI_SCENE_LOGE("ScriptComponent's \"update\" should return a number");
  63. lua_pop(lua, 1);
  64. return Error::USER_DATA;
  65. }
  66. // Get the result
  67. lua_Number result = lua_tonumber(lua, -1);
  68. lua_pop(lua, 1);
  69. if(result < 0)
  70. {
  71. ANKI_SCENE_LOGE("ScriptComponent's \"update\" return an error code");
  72. return Error::USER_DATA;
  73. }
  74. updated = (result != 0);
  75. return Error::NONE;
  76. }
  77. } // end namespace anki