Skip to content
This repository was archived by the owner on Aug 13, 2024. It is now read-only.
Draft
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
10 changes: 10 additions & 0 deletions libpivot/sources/engine.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ namespace pivot
Engine::Engine()
: m_scripting_engine(m_system_index, m_component_index,
pivot::ecs::script::interpreter::builtins::BuiltinContext{
.loadScene =
[this](const std::string &scene) {
// Check that the scene is loaded
if (!this->m_scene_manager.getSceneId(scene).has_value()) {
logger.warn("loadScene") << "The scene " << scene << " doesn't exist.";
return;
}
// Set the scene as the active one
this->changeCurrentScene(this->m_scene_manager.getSceneId(scene).value());
},
.isKeyPressed = std::bind_front(&Engine::isKeyPressed, this),
.selectCamera = std::bind_front(&Engine::setCurrentCamera, this),
}),
Expand Down
1 change: 1 addition & 0 deletions libscript/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ build_tests(
tests/test_interpreter.cxx
tests/test_builtins.cxx
tests/test_escaped.cxx
tests/test_loadScene.cxx
tests/test_decimals.cxx
tests/test_multibyte.cxx
tests/test_negative_numbers.cxx
Expand Down
10 changes: 9 additions & 1 deletion libscript/include/pivot/script/Builtins.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ struct BuiltinContext {
/// Functor returning true if a specific key is pressed
std::function<bool(const std::string &)> isKeyPressed;

/// Functor calling the setScene from ecs::ScenemManager
std::function<void(const std::string &)> loadScene;

/// Select an entity as the new current camera
std::function<void(std::optional<Entity>)> selectCamera;

/// Mock builtin context for unit testing
static BuiltinContext mock()
{
return BuiltinContext{.isKeyPressed = [](auto) { return false; }, .selectCamera = [](auto) {}};
return BuiltinContext{
.isKeyPressed = [](auto) { return false; }, .loadScene = [](auto) {}, .selectCamera = [](auto) {}};
}
};

Expand All @@ -40,6 +44,10 @@ data::Value builtin_print(const std::vector<data::Value> &params, const BuiltinC
/// Same as above but take a ostream to write to
data::Value builtin_print_stream(const std::vector<data::Value> &params, std::ostream &stream);

/// void loadScene(String scene)
/// Loads the scene string passed as parameter into the editor
data::Value builtin_loadScene(const std::vector<data::Value> &params, const BuiltinContext &context);

// Math built-ins
/// Number cos(Number radAngle)
/// Returns the cosine of the parameter (in radian)
Expand Down
6 changes: 6 additions & 0 deletions libscript/sources/Builtins.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ data::Value builtin_print_stream(const std::vector<data::Value> &params, std::os
return data::Value();
}

data::Value builtin_loadScene(const std::vector<data::Value> &params, const BuiltinContext &context)
{
context.loadScene(std::get<std::string>(params.at(0)));
return data::Value();
}

data::Value builtin_cos(const std::vector<data::Value> &params, const BuiltinContext &)
{
return std::cos(std::get<double>(params.at(0)));
Expand Down
1 change: 1 addition & 0 deletions libscript/sources/Interpreter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ using ParameterPair = std::pair<size_t, std::vector<std::vector<data::Type>>>;
/// This map will map the name of a builtin, to its callback paired with its signature
const std::unordered_map<std::string, std::pair<BuiltinFunctionCallback, ParameterPair>> gBuiltinsCallbacks = {
{"isPressed", {interpreter::builtins::builtin_isPressed, {1, {{data::BasicType::String}}}}},
{"loadScene", {interpreter::builtins::builtin_loadScene, {1, {{data::BasicType::String}}}}},
{"selectCamera", {interpreter::builtins::builtin_selectCamera, {1, {{data::BasicType::EntityRef}}}}},
{"cos", {interpreter::builtins::builtin_cos, {1, {{data::BasicType::Number}}}}},
{"sin", {interpreter::builtins::builtin_sin, {1, {{data::BasicType::Number}}}}},
Expand Down
58 changes: 58 additions & 0 deletions libscript/tests/test_loadScene.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "pivot/ecs/Core/SceneManager.hxx"
#include "pivot/script/Engine.hxx"
#include <catch2/catch_test_macros.hpp>
#include <string>
#include <vector>

using namespace pivot::ecs;

TEST_CASE("Scripting-Interpreter-LoadScene")
{
std::cout << "------Interpreter LoadScene------start (lambda must be the same as in engine.cxx)" << std::endl;

component::Index cind;
systems::Index sind;
pivot::ecs::SceneManager scenemgr;
// Register 2 scenes, and set Scene2 as current active scene
scenemgr.registerScene("Scene1");
scenemgr.registerScene("Scene2");
scenemgr.setCurrentSceneId(scenemgr.getSceneId("Scene2").value());
script::Engine engine(sind, cind,
pivot::ecs::script::interpreter::builtins::BuiltinContext{
[](auto) { return false; },
[&scenemgr](const std::string &scene) {
// Check that the scene is loaded
if (!scenemgr.getSceneId(scene).has_value()) {
logger.warn("loadScene") << "The scene " << scene << " doesn't exist.";
return;
}
// Set the scene as the active one
scenemgr.setCurrentSceneId(scenemgr.getSceneId(scene).value());
}});
// std::string file = "C:/Users/Najo/eip/pivot/libscript/tests/loadScene.pvt";
// engine.loadFile(file);
std::string fileContent = "component C\n"
"\tString str\n"
"system S(anyEntity<C>) event Tick(Number deltaTime)\n"
"\tloadScene(\"Scene1\")\n";
engine.loadFile(fileContent, true);

REQUIRE(sind.getDescription("S").has_value());
REQUIRE(cind.getDescription("C").has_value());

auto Cdescription = cind.getDescription("C").value();
auto Sdescription = sind.getDescription("S").value();
auto array1 = Cdescription.createContainer(Cdescription);
std::vector<data::Value> entity = {data::Record{{"str", "foo"}}};
array1->setValueForEntity(0, entity.at(0));
component::ArrayCombination combinations{{std::ref(*array1)}};
event::EventWithComponent evt = {
.event = event::Event{.description = Sdescription.eventListener, .entities = {1, 2}, .payload = 0.12}};

Sdescription.system(Sdescription, combinations, evt);

// Check that after execution, current active scene is Scene1
REQUIRE(scenemgr.getCurrentSceneId() == 0);

std::cout << "------Interpreter LoadScene------end" << std::endl;
}