ScriptComponent.cpp 2.2 KB

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