Skip to content

Commit

Permalink
feat: lua scripting
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMcAvoy committed Oct 11, 2024
1 parent 59f6987 commit 722e71e
Show file tree
Hide file tree
Showing 19 changed files with 689 additions and 91 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.5)
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)

# C++
set (CMAKE_CXX_STANDARD 20)
set (CMAKE_CXX_STANDARD 23)
set (CMAKE_CXX_STANDARD_REQUIRED ON)

# Project declaration
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ Come back later, sorry! Jenjin is not ready for real usage.
- [x] Editor
- [x] Serialization/Deserialization of scenes
- [x] Texture loading
- [x] Scripting (Lua)
- [ ] Transparency on sprites
- [ ] Scripting (Lua)
- [ ] Icons everywhere
- [ ] Code editor in the editor
- [ ] Dynamic data attached to game objects at runtime
- [ ] Hierarchy and `.Parent` in Lua along with `workspace` (e.g. `Workspace.MyGameObject.Parent` == `Workspace`)
Expand Down
2 changes: 2 additions & 0 deletions engine/include/jenjin/editor/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class Manager {
bool selectedCamera = false;

char renameGameObjectBuffer[256] = {0};

bool running = false;
};
} // namespace Editor
} // namespace Jenjin
1 change: 1 addition & 0 deletions engine/include/jenjin/editor/utils.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/glad.h>

Expand Down
3 changes: 2 additions & 1 deletion engine/include/jenjin/editor/widgets.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once

#include "jenjin/gameobject.h"

namespace Jenjin::Editor::Widgets {
bool transformWidget(
Jenjin::GameObject::Transform
*transform); // Returns true if the transform was changed
*transform);
};
3 changes: 3 additions & 0 deletions engine/include/jenjin/engine.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "jenjin/luamanager.h"
#include "jenjin/scene.h"
#include "jenjin/target.h"

Expand All @@ -23,6 +24,8 @@ class Engine {
private:
std::vector<std::shared_ptr<Scene>> scenes = {};
Scene *currentScene = nullptr;

LuaManager luaManager;
};

extern Engine *EngineRef;
Expand Down
38 changes: 38 additions & 0 deletions engine/include/jenjin/luamanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <sol/forward.hpp>
#include <sol/sol.hpp>
#include <unordered_map>

namespace Jenjin {
class LuaManager {
public:
LuaManager();

// Used to manage loading and executing Lua scripts
// from files and directories
void LoadDirectory(const std::string &directory);
void LoadFile(const std::string &file);
void ReloadScripts(const std::string &directory);

// One-shot Lua script execution
void Execute(const std::string &script);
void ExecuteFile(const std::string &file);

// Utilities for calling Lua functions collected from files
// NOTE: This is not related to one-shot `Execute`/`ExecuteFile`
// calls. This is for `LoadFile`, `LoadDirectory`, etc.
void Ready();
void Update();

// Getters
sol::state *GetLuaState() { return &lua; }

private:
sol::state lua;

std::unordered_map<std::string,
std::pair<sol::safe_function, sol::safe_function>>
functions = {};
};
} // namespace Jenjin
6 changes: 6 additions & 0 deletions engine/include/jenjin/scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "jenjin/camera.h"
#include "jenjin/gameobject.h"
#include "jenjin/luamanager.h"
#include "jenjin/shader.h"
#include "jenjin/target.h"
#include "jenjin/texture.h"
Expand Down Expand Up @@ -36,11 +37,14 @@ class Scene {
void Update();
void Render();

std::shared_ptr<GameObject> GetGameObject(const std::string &name);

Camera *GetCamera() { return &camera; }
std::vector<std::shared_ptr<GameObject>> *GetGameObjects() {
return &gameObjects;
}
Target *GetTarget() { return target; }
LuaManager *GetLuaManager() { return &luaManager; }

void Save(const std::string &path);
void Save(std::ofstream &file);
Expand All @@ -60,5 +64,7 @@ class Scene {
Target *target = nullptr;

Camera camera = Camera(&shader, glm::vec2(800, 600));

LuaManager luaManager;
};
} // namespace Jenjin
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Jenjin {
namespace Targets {
class DefaultTarget : public Jenjin::Target {
class RuntimeTarget : public Jenjin::Target {
public:
DefaultTarget() = default;
RuntimeTarget() = default;

virtual void PreRender() override;

Expand Down
2 changes: 1 addition & 1 deletion engine/src/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include <spdlog/spdlog.h>

#include <glm/glm.hpp>
#include <glm/trigonometric.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/trigonometric.hpp>

using namespace Jenjin;

Expand Down
112 changes: 46 additions & 66 deletions engine/src/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,34 @@ void Manager::menu() {
if (!this->paths.openScenePath.empty()) {
if (ImGui::BeginMenu("Scripts")) {
if (ImGui::MenuItem("Reload")) {
spdlog::warn("Unimplemented: Reload Scripts");
auto luaManager =
Jenjin::EngineRef->GetCurrentScene()->GetLuaManager();

luaManager->ReloadScripts(this->paths.projectPath + "/scripts/");
luaManager->Ready();
}

ImGui::EndMenu();
}

if (ImGui::BeginMenu("Game")) {
if (ImGui::MenuItem("Play")) {
spdlog::warn("Unimplemented: Play");
if (ImGui::MenuItem(this->running ? "Stop" : "Play")) {
this->running = !this->running;

auto scene = Jenjin::EngineRef->GetCurrentScene();

if (this->running) {
scene->Save(this->paths.liveScenePath);

Jenjin::EngineRef->GetCurrentScene()
->GetLuaManager()
->LoadDirectory(
(this->paths.projectPath + "/scripts/").c_str());

scene->GetLuaManager()->Ready();
} else {
scene->Load(this->paths.liveScenePath);
}
}

ImGui::EndMenu();
Expand Down Expand Up @@ -305,7 +324,12 @@ void Manager::inspector(Jenjin::Scene *scene) {
selectedObject->texturePath == texture.path().string();
if (ImGui::Selectable(texture.path().filename().string().c_str(),
isSelected)) {
scene->SetGameObjectTexture(selectedObject, texture.path().string());
if (isSelected) {
scene->SetGameObjectTexture(selectedObject, "");
} else {
scene->SetGameObjectTexture(selectedObject,
texture.path().string());
}
}
}
}
Expand Down Expand Up @@ -337,64 +361,6 @@ void Manager::inspector(Jenjin::Scene *scene) {
ImGui::Unindent();
}

/* ImGui::Text("Colours"); */
/* ImGui::Separator(); */
/* ImGui::Indent(); */
/* ImGui::Spacing(); */
/* ImGui::ColorEdit3("Color", glm::value_ptr(selectedObject->color)); */
/* ImGui::Unindent(); */

/* ImGui::Text("Textures"); */
/* ImGui::Separator(); */
/* ImGui::Indent(); */
/* ImGui::Spacing(); */
/* auto diriter = std::filesystem::directory_iterator(this->paths.projectPath
* + "/textures/"); */

/* if (diriter == std::filesystem::directory_iterator()) { */
/* ImGui::Text("No textures found"); */
/* } */

/* for (auto& texture : diriter) { */
/* if (texture.is_regular_file() && texture.path().extension() == ".png" ||
* texture.path().extension() == ".jpg") { */
/* bool isSelected = selectedObject->texturePath ==
* texture.path().string(); */
/* if
* (ImGui::Selectable(texture.path().filename().string().c_str(), isSelected))
* { */
/* scene->SetGameObjectTexture(selectedObject,
* texture.path().string()); */
/* } */
/* } */
/* } */

/* if (!selectedObject->texturePath.empty()) { */
/* ImGui::Spacing(); */
/* ImGui::Checkbox("Mix Color", &selectedObject->mixColor); */
/* } */

/* ImGui::Unindent(); */

/* ImGui::Spacing(); */

/* ImGui::Text("Manage"); */
/* ImGui::Separator(); */
/* ImGui::Indent(); */
/* ImGui::Spacing(); */

/* ImGui::InputText("##RenameInput", renameGameObjectBuffer,
* sizeof(renameGameObjectBuffer)); */
/* ImGui::SameLine(); */
/* if (ImGui::Button("Rename")) { */
/* selectedObject->SetName(renameGameObjectBuffer); */
/* } */

/* if (ImGui::Button("Delete")) { */
/* scene->RemoveGameObject(selectedObject); */
/* selectedObject = nullptr; */
/* } */

ImGui::Unindent();

ImGui::End();
Expand Down Expand Up @@ -465,6 +431,19 @@ void Manager::backup_prompts(Jenjin::Scene *scene) {
void Manager::code(Jenjin::Scene *scene) {}

void Manager::show_all(Jenjin::Scene *scene) {
bool isRunning = this->running;
if (isRunning) {
scene->Update();

auto bg = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
auto red_bg = ImVec4((bg.x + 0.01) * 1.5f, bg.y, bg.z, bg.w);
auto red_bg_dark =
ImVec4((bg.x + 0.01) * 1.5, bg.y * 0.9, bg.z * 0.9, bg.w);
ImGui::PushStyleColor(ImGuiCol_WindowBg, red_bg);
ImGui::PushStyleColor(ImGuiCol_TitleBg, red_bg_dark);
ImGui::PushStyleColor(ImGuiCol_TitleBgActive, red_bg);
}

if (this->paths.projectPath.empty()) {
menu();
dockspace();
Expand All @@ -475,6 +454,8 @@ void Manager::show_all(Jenjin::Scene *scene) {

menu();
dockspace();
if (isRunning)
ImGui::PopStyleColor(3);

hierarchy(scene);
inspector(scene);
Expand All @@ -493,6 +474,7 @@ void Manager::welcome() {
ImGui::GetFrameHeightWithSpacing();
int spad = ImGui::GetStyle().WindowPadding.y * 2 +
ImGui::GetStyle().ItemSpacing.y * 2;

ImGui::BeginChild(
"WelcomeChild",
ImVec2(ImGui::GetWindowWidth() - ImGui::GetStyle().WindowPadding.x * 2,
Expand All @@ -509,13 +491,11 @@ void Manager::welcome() {

Jenjin::EngineRef->GetCurrentScene()->GetGameObjects()->clear();
std::ifstream ifile(this->paths.openScenePath);
/* Jenjin::EngineRef->GetCurrentScene()->load(ifile); */
Jenjin::EngineRef->GetCurrentScene()->Load(this->paths.openScenePath);

// Load all the lua files
spdlog::warn("Unimplemented: Load Lua files");
/* Jenjin::EngineRef->GetCurrentScene()->reload_lua((this->paths.projectPath
* + "/scripts/").c_str()); */
Jenjin::EngineRef->GetCurrentScene()->GetLuaManager()->LoadDirectory(
(this->paths.projectPath + "/scripts/").c_str());
};

for (auto file : std::filesystem::directory_iterator(
Expand Down
2 changes: 1 addition & 1 deletion engine/src/editor/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

#include <spdlog/spdlog.h>

#include <filesystem>
#include <cstdlib>
#include <filesystem>

void Jenjin::Editor::ensure_dir(std::string path) {
if (!std::filesystem::exists(path)) {
Expand Down
3 changes: 3 additions & 0 deletions engine/src/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ Engine::Engine(GLFWwindow *window) {
spdlog::debug("Initializing Jenjin {}", VERSION);

glfwSetErrorCallback([](int code, const char *error) {
if (code == 65540 || code == 65539)
return;

spdlog::error("GLFW Error: {} ({})", error, code);
});

Expand Down
Loading

0 comments on commit 722e71e

Please sign in to comment.