Browse Source

Script+System: Allow native scripts from projects, decoupled from engine

master
Riyyi 12 months ago
parent
commit
649d196577
  1. 40
      example/src/cameracontroller.cpp
  2. 18
      example/src/cameracontroller.h
  3. 20
      src/inferno/component/nativescriptcomponent.h
  4. 4
      src/inferno/scene/scene.cpp
  5. 46
      src/inferno/script/nativescript.h
  6. 2
      src/inferno/system/scriptsystem.cpp

40
src/inferno/script/cameracontroller.cpp → example/src/cameracontroller.cpp

@ -10,9 +10,10 @@
#include "inferno/component/transformcomponent.h" #include "inferno/component/transformcomponent.h"
#include "inferno/io/input.h" #include "inferno/io/input.h"
#include "inferno/keycodes.h" #include "inferno/keycodes.h"
#include "inferno/script/cameracontroller.h"
namespace Inferno { #include "cameracontroller.h"
namespace example {
void CameraController::updateOrthographic(float deltaTime) void CameraController::updateOrthographic(float deltaTime)
{ {
@ -20,10 +21,10 @@ void CameraController::updateOrthographic(float deltaTime)
float cameraRotateSpeed = ROTATE_SPEED * deltaTime; float cameraRotateSpeed = ROTATE_SPEED * deltaTime;
if (Input::isKeyPressed(keyCode("GLFW_KEY_Q"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_Q"))) {
transform->rotate.z -= cameraRotateSpeed; transform->rotate.z -= cameraRotateSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_E"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_E"))) {
transform->rotate.z += cameraRotateSpeed; transform->rotate.z += cameraRotateSpeed;
} }
@ -39,19 +40,19 @@ void CameraController::updateOrthographic(float deltaTime)
float cameraTranslateSpeed = TRANSLATE_SPEED * deltaTime; float cameraTranslateSpeed = TRANSLATE_SPEED * deltaTime;
// WASD movement // WASD movement
if (Input::isKeyPressed(keyCode("GLFW_KEY_W"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_W"))) {
transform->translate.x += -sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.x += -sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y += cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.y += cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_S"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_S"))) {
transform->translate.x -= -sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.x -= -sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y -= cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.y -= cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_A"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_A"))) {
transform->translate.x -= cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.x -= cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y -= sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.y -= sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_D"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_D"))) {
transform->translate.x += cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.x += cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y += sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed; transform->translate.y += sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
} }
@ -60,10 +61,10 @@ void CameraController::updateOrthographic(float deltaTime)
float zoomSpeed = ZOOM_SENSITIVITY * deltaTime; float zoomSpeed = ZOOM_SENSITIVITY * deltaTime;
if (Input::isKeyPressed(keyCode("GLFW_KEY_EQUAL"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_EQUAL"))) {
m_camera->zoomLevel -= zoomSpeed; m_camera->zoomLevel -= zoomSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_MINUS"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_MINUS"))) {
m_camera->zoomLevel += zoomSpeed; m_camera->zoomLevel += zoomSpeed;
} }
m_camera->zoomLevel = std::max(m_camera->zoomLevel, 0.25f); m_camera->zoomLevel = std::max(m_camera->zoomLevel, 0.25f);
@ -73,8 +74,8 @@ void CameraController::updateOrthographic(float deltaTime)
void CameraController::updatePerspective(float deltaTime) void CameraController::updatePerspective(float deltaTime)
{ {
// Get mouse movement offset compared to last frame // Get mouse movement offset compared to last frame
float xOffset = Input::getXOffset() * MOUSE_SENSITIVITY; float xOffset = Inferno::Input::getXOffset() * MOUSE_SENSITIVITY;
float yOffset = Input::getYOffset() * MOUSE_SENSITIVITY; float yOffset = Inferno::Input::getYOffset() * MOUSE_SENSITIVITY;
m_camera->yaw += xOffset; m_camera->yaw += xOffset;
m_camera->pitch += yOffset; m_camera->pitch += yOffset;
@ -107,24 +108,25 @@ void CameraController::updatePerspective(float deltaTime)
float cameraSpeed = TRANSLATE_SPEED * deltaTime; float cameraSpeed = TRANSLATE_SPEED * deltaTime;
// WASD movement // WASD movement
if (Input::isKeyPressed(keyCode("GLFW_KEY_W"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_W"))) {
transform->translate += transform->rotate * cameraSpeed; transform->translate += transform->rotate * cameraSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_S"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_S"))) {
transform->translate -= transform->rotate * cameraSpeed; transform->translate -= transform->rotate * cameraSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_A"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_A"))) {
transform->translate -= glm::normalize(glm::cross(transform->rotate, m_camera->up)) * cameraSpeed; transform->translate -= glm::normalize(glm::cross(transform->rotate, m_camera->up)) * cameraSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_D"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_D"))) {
transform->translate += glm::normalize(glm::cross(transform->rotate, m_camera->up)) * cameraSpeed; transform->translate += glm::normalize(glm::cross(transform->rotate, m_camera->up)) * cameraSpeed;
} }
// Up / down movement // Up / down movement
if (Input::isKeyPressed(keyCode("GLFW_KEY_SPACE"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_SPACE"))) {
transform->translate.y += cameraSpeed; transform->translate.y += cameraSpeed;
} }
if (Input::isKeyPressed(keyCode("GLFW_KEY_LEFT_SHIFT"))) { if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_LEFT_SHIFT"))) {
transform->translate.y -= cameraSpeed; transform->translate.y -= cameraSpeed;
} }
} }
} // namespace Inferno
} // namespace example

18
src/inferno/script/cameracontroller.h → example/src/cameracontroller.h

@ -14,20 +14,18 @@
#define ZOOM_SENSITIVITY 2.5f #define ZOOM_SENSITIVITY 2.5f
#define MOUSE_SENSITIVITY 0.25f #define MOUSE_SENSITIVITY 0.25f
namespace Inferno { namespace example {
struct CameraComponent; class CameraController final : public Inferno::NativeScript {
class CameraController final : public NativeScript {
public: public:
virtual void update(float deltaTime) override virtual void update(float deltaTime) override
{ {
m_camera = &getComponent<CameraComponent>(); m_camera = &getComponent<Inferno::CameraComponent>();
if (m_camera->type == CameraType::Orthographic) { if (m_camera->type == Inferno::CameraType::Orthographic) {
updateOrthographic(deltaTime); updateOrthographic(deltaTime);
} }
else if (m_camera->type == CameraType::Perspective) { else if (m_camera->type == Inferno::CameraType::Perspective) {
updatePerspective(deltaTime); updatePerspective(deltaTime);
} }
} }
@ -36,7 +34,9 @@ public:
void updatePerspective(float deltaTime); void updatePerspective(float deltaTime);
private: private:
CameraComponent* m_camera { nullptr }; Inferno::CameraComponent* m_camera { nullptr };
}; };
} // namespace Inferno BIND_NATIVE(CameraController);
} // namespace example

20
src/inferno/component/nativescriptcomponent.h

@ -6,7 +6,7 @@
#pragma once #pragma once
#include "ruc/meta/assert.h" #include <string>
#include "inferno/script/nativescript.h" #include "inferno/script/nativescript.h"
@ -15,23 +15,15 @@ namespace Inferno {
struct NativeScriptComponent { struct NativeScriptComponent {
NativeScript* instance { nullptr }; NativeScript* instance { nullptr };
NativeScript* (*initialize)() { nullptr }; NativeScript::InitializeFunction initialize { nullptr };
NativeScript::DestroyFunction destroy { nullptr };
// Dont allow manually setting instance during construction // Dont allow manually setting instance during construction
NativeScriptComponent() {} NativeScriptComponent() {}
NativeScriptComponent(const std::string& binding)
template<typename T>
void bind()
{
VERIFY(instance == nullptr, "NativeScript already bound");
initialize = []() { return static_cast<NativeScript*>(new T()); };
}
void destroy()
{ {
VERIFY(instance, "Attempting to destroy an uninitialized NativeScript"); initialize = NativeScriptBinding::the().initializeBinding(binding);
delete instance; destroy = NativeScriptBinding::the().destroyBinding(binding);
instance = nullptr;
} }
}; };

4
src/inferno/scene/scene.cpp

@ -20,7 +20,6 @@
#include "inferno/component/textareacomponent.h" #include "inferno/component/textareacomponent.h"
#include "inferno/component/transformcomponent.h" #include "inferno/component/transformcomponent.h"
#include "inferno/scene/scene.h" #include "inferno/scene/scene.h"
#include "inferno/script/cameracontroller.h"
#include "inferno/script/nativescript.h" #include "inferno/script/nativescript.h"
#include "inferno/system/camerasystem.h" #include "inferno/system/camerasystem.h"
#include "inferno/system/rendersystem.h" #include "inferno/system/rendersystem.h"
@ -69,8 +68,7 @@ void Scene::initialize()
addComponent<LuaScriptComponent>(camera, cameraScript.at("name").get<std::string>()); addComponent<LuaScriptComponent>(camera, cameraScript.at("name").get<std::string>());
} }
else { else {
// TODO: Allow usage of custom camera classes addComponent<NativeScriptComponent>(camera, name);
addComponent<NativeScriptComponent>(camera).bind<CameraController>();
} }
} }
} }

46
src/inferno/script/nativescript.h

@ -6,6 +6,9 @@
#pragma once #pragma once
#include "ruc/meta/core.h"
#include "ruc/singleton.h"
#include "inferno/scene/scene.h" #include "inferno/scene/scene.h"
namespace Inferno { namespace Inferno {
@ -14,6 +17,9 @@ struct TransformComponent;
class NativeScript { class NativeScript {
public: public:
typedef NativeScript* (*InitializeFunction)();
typedef void (*DestroyFunction)(NativeScript*);
virtual ~NativeScript() {} virtual ~NativeScript() {}
protected: protected:
@ -36,4 +42,44 @@ private:
friend class ScriptSystem; friend class ScriptSystem;
}; };
class NativeScriptBinding final : public ruc::Singleton<NativeScriptBinding> {
public:
NativeScriptBinding(s) {}
virtual ~NativeScriptBinding() {}
void registerBinding(const std::string& binding,
NativeScript::InitializeFunction initialize,
NativeScript::DestroyFunction destroy)
{
m_initializeBindings.emplace(binding, initialize);
m_detroyBindings.emplace(binding, destroy);
}
NativeScript::InitializeFunction initializeBinding(const std::string& binding) { return m_initializeBindings[binding]; }
NativeScript::DestroyFunction destroyBinding(const std::string& binding) { return m_detroyBindings[binding]; }
private:
std::unordered_map<std::string, NativeScript::InitializeFunction> m_initializeBindings;
std::unordered_map<std::string, NativeScript::DestroyFunction> m_detroyBindings;
};
} // namespace Inferno } // namespace Inferno
#define BIND_NATIVE_IMPL(name, struct_name) \
struct struct_name { \
struct_name() \
{ \
Inferno::NativeScriptBinding::the().registerBinding( \
#name, \
[]() -> Inferno::NativeScript* { return static_cast<Inferno::NativeScript*>(new name()); }, \
[](Inferno::NativeScript* nativeScript) -> void { \
VERIFY(nativeScript, "Attempting to destroy an uninitialized NativeScript"); \
delete static_cast<name*>(nativeScript); \
nativeScript = nullptr; \
}); \
} \
}; \
static struct struct_name struct_name; // NOLINT(clang-diagnostic-unused-function)
#define BIND_NATIVE(name) \
BIND_NATIVE_IMPL(name, CONCAT(__BIND_NATIVE_FUNCTION_, __COUNTER__))

2
src/inferno/system/scriptsystem.cpp

@ -92,7 +92,7 @@ void ScriptSystem::cleanup(NativeScriptComponent& nativeScript)
{ {
if (nativeScript.instance) { if (nativeScript.instance) {
nativeScript.instance->destroy(); nativeScript.instance->destroy();
nativeScript.destroy(); nativeScript.destroy(nativeScript.instance);
} }
} }

Loading…
Cancel
Save