Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial prototyped Lua scripting support #96

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 30 additions & 27 deletions applications/testbed/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,50 @@
#include <cerlib/Main.hpp>
#include <imgui.h>

class Testbed : public cer::Game
{
public:
Testbed()
{
window = cer::Window{"Testbed"};
}
using namespace cer;

static constexpr auto game_code = R"(
local anim = 0.0
local img = Image('logo.png')

function update()
anim = anim + time.elapsed_time * 20
end

function draw()
draw_sprite_simple(img, Vector2(100 + anim, 200), white)
end
)"_lua;

struct Testbed : Game
{
void load_content() override
{
lua_state = LuaState{LuaLibraries::All,
{
LuaScript{"SomeGameCode", game_code},
}};
}

bool update(const cer::GameTime& time) override
auto update(const GameTime& time) -> bool override
{
return true;
}
lua_state.set_variable("time", time);
lua_state.run_code("update()");

void draw(const cer::Window& window) override
{
return !lua_state.variable_as<bool>("should_exit").value_or(false);
}

void draw_imgui(const cer::Window& window) override
void draw(const Window& window) override
{
// Enable as you wish:
#if false
ImGui::Begin("My ImGui Window");
ImGui::Text("Hello World!");

if (ImGui::Button("Click here"))
{
cer::log_info("Button was clicked!");
}

ImGui::End();
#endif
lua_state.set_variable("window", window);
lua_state.run_code("draw()");
}

cer::Window window;
Window window{"Testbed"};
LuaState lua_state;
};

int main(int argc, char* argv[])
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
{
return cer::run_game<Testbed>();
}
2 changes: 2 additions & 0 deletions include/cerlib.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <cerlib/KeyModifier.hpp>
#include <cerlib/List.hpp>
#include <cerlib/Logging.hpp>
#include <cerlib/LuaScript.hpp>
#include <cerlib/LuaState.hpp>
#include <cerlib/Math.hpp>
#include <cerlib/Matrix.hpp>
#include <cerlib/MouseButton.hpp>
Expand Down
45 changes: 45 additions & 0 deletions include/cerlib/LuaScript.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2023-2024 Cemalettin Dervis
// This file is part of cerlib.
// For conditions of distribution and use, see copyright notice in LICENSE.

#pragma once

#include <cerlib/StringView.hpp>
#include <cerlib/details/ObjectMacros.hpp>

namespace cer
{
namespace details
{
class LuaScriptImpl;
}

struct LuaCode
{
constexpr explicit LuaCode(StringView code)
: code(code)
{
}

StringView code;
};

class LuaScript final
{
CERLIB_DECLARE_OBJECT(LuaScript);

public:
explicit LuaScript(StringView asset_name);

explicit LuaScript(StringView name, LuaCode code);

auto name() const -> StringView;

auto code() const -> StringView;
};
} // namespace cer

constexpr auto operator""_lua(const char* code, size_t length) -> cer::LuaCode
{
return cer::LuaCode{cer::StringView{code, length}};
}
63 changes: 63 additions & 0 deletions include/cerlib/LuaState.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (C) 2023-2024 Cemalettin Dervis
// This file is part of cerlib.
// For conditions of distribution and use, see copyright notice in LICENSE.

#pragma once

#include <cerlib/Game.hpp>
#include <cerlib/List.hpp>
#include <cerlib/LuaScript.hpp>
#include <cerlib/Window.hpp>
#include <cerlib/details/ObjectMacros.hpp>
#include <optional>
#include <string>
#include <variant>

namespace cer
{
class LuaScript;

namespace details
{
class LuaStateImpl;
}

enum class LuaLibraries
{
All,
};

using LuaValue = std::variant<double, bool, std::string, GameTime, Window>;

class LuaState final
{
CERLIB_DECLARE_OBJECT(LuaState);

public:
explicit LuaState(LuaLibraries libraries_to_include, const List<LuaScript>& scripts = {});

auto variable(std::string_view name) const -> std::optional<LuaValue>;

template <typename T>
auto variable_as(std::string_view name) const -> std::optional<T>;

void set_variable(std::string_view name, const std::optional<LuaValue>& value);

void run_code(std::string_view code);

void run_script(const LuaScript& script);
};

template <typename T>
auto LuaState::variable_as(std::string_view name) const -> std::optional<T>
{
auto val = variable(name);

if (!val.has_value())
{
return std::nullopt;
}

return std::make_optional(std::get<T>(std::move(*val)));
}
} // namespace cer
40 changes: 37 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ set(cerlib_public_files
cerlib/Defer.hpp
cerlib/Tuple.hpp
cerlib/Camera.hpp
cerlib/LuaState.hpp
cerlib/LuaScript.hpp
cerlib.hpp
)

Expand Down Expand Up @@ -106,6 +108,7 @@ target_precompile_headers(cerlib PRIVATE
<utility>
<variant>
<vector>
<cerlib/lua/sol.hpp>
<cerlib/Span.hpp>
<cerlib/Array.hpp>
<cerlib/String.hpp>
Expand All @@ -129,9 +132,39 @@ target_precompile_headers(cerlib PRIVATE
<cerlib/util/narrow_cast.hpp>
)

set_source_files_properties(
cerlib/graphics/stb_image.cpp
PROPERTIES
set_property(SOURCE
lua/ldebug.cpp
graphics/stb_image.cpp
lua/lapi.cpp
lua/lauxlib.cpp
lua/lcode.cpp
lua/lcorolib.cpp
lua/ldblib.cpp
lua/lctype.cpp
lua/ldump.cpp
lua/ldo.cpp
lua/lfunc.cpp
lua/linit.cpp
lua/lgc.cpp
lua/liolib.cpp
lua/llex.cpp
lua/lmathlib.cpp
lua/lmem.cpp
lua/loadlib.cpp
lua/lobject.cpp
lua/lopcodes.cpp
lua/loslib.cpp
lua/lparser.cpp
lua/lstate.cpp
lua/lstring.cpp
lua/ltable.cpp
lua/ltablib.cpp
lua/ltm.cpp
lua/lundump.cpp
lua/lvm.cpp
lua/lutf8lib.cpp
lua/lzio.cpp
PROPERTY
SKIP_PRECOMPILE_HEADERS ON
)

Expand All @@ -147,6 +180,7 @@ set(src_sub_dirs
game
graphics
input
lua
math
shadercompiler
util
Expand Down
10 changes: 10 additions & 0 deletions src/cerlib/contentmanagement/ContentManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ auto ContentManager::load_sound(StringView name) -> Sound
});
}

auto ContentManager::load_lua_script(StringView name) -> LuaScript
{
const auto key = String{name};

return lazy_load<LuaScript, LuaScriptImpl>(key.view(), name, [](StringView full_name) {
const auto data = filesystem::load_asset_data(full_name);
return LuaScript{full_name, LuaCode{data.as_string_view()}};
});
}

auto ContentManager::load_custom_asset(StringView type_id,
StringView name,
const std::any& extra_info) -> SharedPtr<Asset>
Expand Down
6 changes: 5 additions & 1 deletion src/cerlib/contentmanagement/ContentManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
#include <cerlib/CopyMoveMacros.hpp>
#include <cerlib/Error.hpp>
#include <cerlib/Logging.hpp>
#include <cerlib/LuaScript.hpp>
#include <cerlib/Shader.hpp>
#include <cerlib/Span.hpp>
#include <cerlib/String.hpp>
#include <cerlib/Variant.hpp>
#include <cerlib/graphics/ShaderImpl.hpp>
#include <cerlib/lua/LuaScriptImpl.hpp>
#include <cerlib/util/StringUnorderedMap.hpp>

namespace cer::details
Expand Down Expand Up @@ -43,6 +45,8 @@ class ContentManager final

auto load_sound(StringView name) -> Sound;

auto load_lua_script(StringView name) -> LuaScript;

auto load_custom_asset(StringView type_id, StringView name, const std::any& extra_info)
-> SharedPtr<Asset>;

Expand All @@ -62,7 +66,7 @@ class ContentManager final
// vanished), they notify the content manager. The content manager then removes those
// assets from its list.
using ReferenceToLoadedAsset =
Variant<ImageImpl*, SoundImpl*, ShaderImpl*, FontImpl*, CustomAsset>;
std::variant<ImageImpl*, SoundImpl*, ShaderImpl*, FontImpl*, LuaScriptImpl*, CustomAsset>;

using MapOfLoadedAssets = StringUnorderedMap<ReferenceToLoadedAsset>;

Expand Down
64 changes: 64 additions & 0 deletions src/cerlib/lua/Files.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
set(lua_files
lapi.cpp
lapi.h
lauxlib.cpp
lauxlib.h
lbaselib.cpp
lcode.cpp
lcode.h
lcorolib.cpp
lctype.cpp
ldblib.cpp
ldebug.cpp
ldebug.h
ldo.cpp
ldo.h
ldump.cpp
lfunc.cpp
lfunc.h
lgc.cpp
lgc.h
linit.cpp
liolib.cpp
ljumptab.h
llex.cpp
llex.h
llimits.h
lmathlib.cpp
lmem.cpp
lmem.h
loadlib.cpp
lobject.cpp
lobject.h
lopcodes.cpp
lopcodes.h
lopnames.h
lparser.cpp
lparser.h
lprefix.h
lstate.cpp
lstring.cpp
lstring.h
lstrlib.cpp
ltable.cpp
ltable.h
ltablib.cpp
ltm.cpp
ltm.h
lua.h
luaconf.h
lualib.h
lundump.cpp
lundump.h
lutf8lib.cpp
lvm.cpp
lvm.h
lzio.cpp
lzio.h
LuaState.cpp
LuaStateImpl.hpp
LuaStateImpl.cpp
LuaScript.cpp
LuaScriptImpl.hpp
LuaScriptImpl.cpp
)
Loading