| | @@ -44,23 +44,14 @@ |
| 44 | 44 | , m_Program(prog) |
| 45 | 45 | , m_Console(cmd) |
| 46 | 46 | { |
| 47 | | - m_Lua.open_libraries( |
| 48 | | - sol::lib::base, |
| 49 | | - sol::lib::math, |
| 50 | | - sol::lib::table, |
| 51 | | - sol::lib::string |
| 52 | | - ); |
| 53 | | - |
| 54 | | - BindGraphics(); |
| 55 | | - Execute(); |
| 47 | + m_Lua = MakeAPI(); |
| 56 | 48 | } |
| 57 | 49 | |
| 58 | | - LuaEngine::~LuaEngine() { |
| 59 | | - } |
| 50 | + LuaEngine::~LuaEngine() {} |
| 60 | 51 | |
| 61 | 52 | void LuaEngine::Reload(const string &code) { |
| 62 | 53 | m_Code = code; |
| 63 | | - Execute(); |
| 54 | + Execute(m_Lua); |
| 64 | 55 | } |
| 65 | 56 | |
| 66 | 57 | void LuaEngine::Update() { |
| | @@ -70,19 +61,93 @@ |
| 70 | 61 | |
| 71 | 62 | if (!res.valid()) { |
| 72 | 63 | sol::error err = res; |
| 73 | | - gui::LogEntry entry = {}; |
| 74 | | - entry.type = gui::LogType::Error; |
| 75 | | - entry.text = err.what(); |
| 76 | | - if (m_Console) m_Console->Add(entry); |
| 77 | | - else std::cerr << err.what() << std::endl; |
| 64 | + LogError(err); |
| 78 | 65 | } |
| 79 | 66 | } |
| 80 | 67 | } |
| 81 | 68 | |
| 82 | | - void LuaEngine::BindGraphics() { |
| 83 | | - m_Lua["graphics"] = m_Lua.create_table(); |
| 69 | + bool LuaEngine::Validate(const string &code) { |
| 70 | + try { |
| 71 | + sol::load_result resSyntax = m_Lua.load(code); |
| 72 | + if (!resSyntax.valid()) { |
| 73 | + sol::error err = resSyntax; |
| 74 | + LogError(err); |
| 75 | + return false; |
| 76 | + } |
| 84 | 77 | |
| 85 | | - m_Lua["graphics"]["set_mesh"] = [&](sol::table t) { |
| 78 | + sol::state testApi = MakeAPI(); |
| 79 | + sol::protected_function_result resApi = testApi.safe_script(code); |
| 80 | + if (!resApi.valid()) { |
| 81 | + sol::error err = resApi; |
| 82 | + LogError(err); |
| 83 | + return false; |
| 84 | + } |
| 85 | + |
| 86 | + return true; |
| 87 | + } catch (const sol::error &err) { |
| 88 | + LogError(err); |
| 89 | + return false; |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + //////////////////// |
| 94 | + |
| 95 | + void LuaEngine::LogError(sol::error err) { |
| 96 | + gui::LogEntry entry = {}; |
| 97 | + entry.type = gui::LogType::Error; |
| 98 | + entry.text = err.what(); |
| 99 | + if (m_Console) m_Console->Add(entry); |
| 100 | + else std::cerr << err.what() << std::endl; |
| 101 | + } |
| 102 | + |
| 103 | + void LuaEngine::LogError(const std::exception &err) { |
| 104 | + gui::LogEntry entry = {}; |
| 105 | + entry.type = gui::LogType::Error; |
| 106 | + entry.text = err.what(); |
| 107 | + if (m_Console) m_Console->Add(entry); |
| 108 | + else std::cerr << err.what() << std::endl; |
| 109 | + } |
| 110 | + |
| 111 | + sol::state LuaEngine::MakeAPI() { |
| 112 | + sol::state out; |
| 113 | + |
| 114 | + out.open_libraries( |
| 115 | + sol::lib::base, |
| 116 | + sol::lib::math, |
| 117 | + sol::lib::table, |
| 118 | + sol::lib::string |
| 119 | + ); |
| 120 | + |
| 121 | + try { |
| 122 | + BindEngine(out); |
| 123 | + BindSystem(out); |
| 124 | + BindGraphics(out); |
| 125 | + Execute(out); |
| 126 | + } catch (const std::exception &e) { |
| 127 | + LogError(e); |
| 128 | + return {}; |
| 129 | + } |
| 130 | + |
| 131 | + return out; |
| 132 | + } |
| 133 | + |
| 134 | + void LuaEngine::BindEngine(sol::state &lua) { |
| 135 | + lua["le"] = lua.create_table(); |
| 136 | + lua["le"]["api_version"] = m_ApiVersion; |
| 137 | + } |
| 138 | + |
| 139 | + void LuaEngine::BindSystem(sol::state &lua) { |
| 140 | + lua["le"]["sys"] = lua.create_table(); |
| 141 | + |
| 142 | + lua["le"]["sys"]["get_time"] = [&]() -> f32 { |
| 143 | + return (f32)glfwGetTime(); |
| 144 | + }; |
| 145 | + } |
| 146 | + |
| 147 | + void LuaEngine::BindGraphics(sol::state &lua) { |
| 148 | + lua["le"]["gfx"] = lua.create_table(); |
| 149 | + |
| 150 | + lua["le"]["gfx"]["set_mesh"] = [&](sol::table t) { |
| 86 | 151 | m_Mesh.vertices.clear(); |
| 87 | 152 | m_Mesh.indices.clear(); |
| 88 | 153 | m_Mesh.attr.clear(); |
| | @@ -97,6 +162,15 @@ |
| 97 | 162 | for (auto &k : attrs) { |
| 98 | 163 | sol::table a = k.second; |
| 99 | 164 | |
| 165 | + sol::optional<int> location = a["location"]; |
| 166 | + sol::optional<int> size = a["size"]; |
| 167 | + sol::optional<int> stride = a["stride"]; |
| 168 | + sol::optional<int> offset = a["offset"]; |
| 169 | + |
| 170 | + if (!location || !size || !stride || !offset) { |
| 171 | + throw std::runtime_error("メッシュアトリビュートが不正です。"); |
| 172 | + } |
| 173 | + |
| 100 | 174 | m_Mesh.attr.push_back({ |
| 101 | 175 | a["location"], |
| 102 | 176 | a["size"], |
| | @@ -106,26 +180,18 @@ |
| 106 | 180 | } |
| 107 | 181 | }; |
| 108 | 182 | |
| 109 | | - m_Lua["graphics"]["get_time"] = [&]() -> f32 { |
| 110 | | - return (f32)glfwGetTime(); |
| 111 | | - }; |
| 112 | | - |
| 113 | | - m_Lua["graphics"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) { |
| 183 | + lua["le"]["gfx"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) { |
| 114 | 184 | if (!m_Program) return; |
| 115 | 185 | glUniform3f(m_Program->GetUniformLocation(name), x, y, z); |
| 116 | 186 | }; |
| 117 | 187 | } |
| 118 | 188 | |
| 119 | | - void LuaEngine::Execute() { |
| 120 | | - sol::protected_function_result res = m_Lua.safe_script(m_Code); |
| 189 | + void LuaEngine::Execute(sol::state &lua) { |
| 190 | + sol::protected_function_result res = lua.safe_script(m_Code); |
| 121 | 191 | |
| 122 | 192 | if (!res.valid()) { |
| 123 | 193 | sol::error err = res; |
| 124 | | - gui::LogEntry entry = {}; |
| 125 | | - entry.type = gui::LogType::Error; |
| 126 | | - entry.text = err.what(); |
| 127 | | - if (m_Console) m_Console->Add(entry); |
| 128 | | - else std::cerr << err.what() << std::endl; |
| 194 | + LogError(err); |
| 129 | 195 | } |
| 130 | 196 | } |
| 131 | 197 | } // namespace lua |