ScriptComponent.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (C) 2009-2023, 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. void ScriptComponent::loadScriptResource(CString fname)
  23. {
  24. // Load
  25. ScriptResourcePtr rsrc;
  26. Error err = ResourceManager::getSingleton().loadResource(fname, rsrc);
  27. // Create the env
  28. ScriptEnvironment* newEnv = nullptr;
  29. if(!err)
  30. {
  31. newEnv = newInstance<ScriptEnvironment>(m_node->getMemoryPool());
  32. err = newEnv->init(getExternalSubsystems(*m_node).m_scriptManager);
  33. }
  34. // Exec the script
  35. if(!err)
  36. {
  37. err = newEnv->evalString(m_script->getSource());
  38. }
  39. // Error
  40. if(err)
  41. {
  42. ANKI_SCENE_LOGE("Failed to load the script");
  43. deleteInstance(m_node->getMemoryPool(), newEnv);
  44. }
  45. else
  46. {
  47. m_script = std::move(rsrc);
  48. deleteInstance(m_node->getMemoryPool(), m_env);
  49. m_env = newEnv;
  50. }
  51. }
  52. Error ScriptComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  53. {
  54. ANKI_ASSERT(info.m_node == m_node);
  55. updated = false;
  56. if(m_env == nullptr)
  57. {
  58. return Error::kNone;
  59. }
  60. lua_State* lua = &m_env->getLuaState();
  61. // Push function name
  62. lua_getglobal(lua, "update");
  63. // Push args
  64. LuaBinder::pushVariableToTheStack(lua, info.m_node);
  65. lua_pushnumber(lua, info.m_previousTime);
  66. lua_pushnumber(lua, info.m_currentTime);
  67. // Do the call (3 arguments, 1 result)
  68. if(lua_pcall(lua, 3, 1, 0) != 0)
  69. {
  70. ANKI_SCENE_LOGE("Error running ScriptComponent's \"update\": %s", lua_tostring(lua, -1));
  71. return Error::kUserData;
  72. }
  73. if(!lua_isnumber(lua, -1))
  74. {
  75. ANKI_SCENE_LOGE("ScriptComponent's \"update\" should return a number");
  76. lua_pop(lua, 1);
  77. return Error::kUserData;
  78. }
  79. // Get the result
  80. lua_Number result = lua_tonumber(lua, -1);
  81. lua_pop(lua, 1);
  82. if(result < 0)
  83. {
  84. ANKI_SCENE_LOGE("ScriptComponent's \"update\" return an error code");
  85. return Error::kUserData;
  86. }
  87. updated = (result != 0);
  88. return Error::kNone;
  89. }
  90. } // end namespace anki