ScriptComponent.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright (C) 2009-2022, 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. ScriptComponent::ScriptComponent(SceneNode* node)
  13. : SceneComponent(node, getStaticClassId())
  14. , m_node(node)
  15. {
  16. ANKI_ASSERT(node);
  17. }
  18. ScriptComponent::~ScriptComponent()
  19. {
  20. deleteInstance(m_node->getMemoryPool(), m_env);
  21. }
  22. Error ScriptComponent::loadScriptResource(CString fname)
  23. {
  24. // Load
  25. ANKI_CHECK(getExternalSubsystems(*m_node).m_resourceManager->loadResource(fname, m_script));
  26. // Create the env
  27. if(m_env)
  28. {
  29. deleteInstance(m_node->getMemoryPool(), m_env);
  30. }
  31. m_env = newInstance<ScriptEnvironment>(m_node->getMemoryPool());
  32. ANKI_CHECK(m_env->init(getExternalSubsystems(*m_node).m_scriptManager));
  33. // Exec the script
  34. ANKI_CHECK(m_env->evalString(m_script->getSource()));
  35. return Error::kNone;
  36. }
  37. Error ScriptComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  38. {
  39. ANKI_ASSERT(info.m_node == m_node);
  40. updated = false;
  41. if(m_env == nullptr)
  42. {
  43. return Error::kNone;
  44. }
  45. lua_State* lua = &m_env->getLuaState();
  46. // Push function name
  47. lua_getglobal(lua, "update");
  48. // Push args
  49. LuaBinder::pushVariableToTheStack(lua, info.m_node);
  50. lua_pushnumber(lua, info.m_previousTime);
  51. lua_pushnumber(lua, info.m_currentTime);
  52. // Do the call (3 arguments, 1 result)
  53. if(lua_pcall(lua, 3, 1, 0) != 0)
  54. {
  55. ANKI_SCENE_LOGE("Error running ScriptComponent's \"update\": %s", lua_tostring(lua, -1));
  56. return Error::kUserData;
  57. }
  58. if(!lua_isnumber(lua, -1))
  59. {
  60. ANKI_SCENE_LOGE("ScriptComponent's \"update\" should return a number");
  61. lua_pop(lua, 1);
  62. return Error::kUserData;
  63. }
  64. // Get the result
  65. lua_Number result = lua_tonumber(lua, -1);
  66. lua_pop(lua, 1);
  67. if(result < 0)
  68. {
  69. ANKI_SCENE_LOGE("ScriptComponent's \"update\" return an error code");
  70. return Error::kUserData;
  71. }
  72. updated = (result != 0);
  73. return Error::kNone;
  74. }
  75. } // end namespace anki