Skip to content

Commit

Permalink
Merge pull request #7 from PiratesAhoy/feature/editor
Browse files Browse the repository at this point in the history
Implement in-game editor
  • Loading branch information
Hammie authored Jan 13, 2024
2 parents 9055e1d + 1f83918 commit 9f9f169
Show file tree
Hide file tree
Showing 26 changed files with 467 additions and 34 deletions.
11 changes: 11 additions & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class StormEngine(ConanFile):
# dependencies used in deploy binaries
# conan-center
requires = ["zlib/1.2.13", "spdlog/1.9.2", "fast_float/3.4.0", "mimalloc/2.0.3", "sentry-native/0.6.5", "tomlplusplus/3.3.0", "nlohmann_json/3.11.2",
"imgui/1.90-docking",
"cli11/2.3.2",
# storm.jfrog.io
"directx/9.0@storm/prebuilt", "fmod/2.02.05@storm/prebuilt"]
# aux dependencies (e.g. for tests)
Expand Down Expand Up @@ -51,6 +53,12 @@ def imports(self):
self.__install_folder("/src/techniques", "/resource/techniques")
self.__install_folder("/src/libs/shared_headers/include/shared", "/resource/shared")

self.__copy_imgui_binding("imgui_impl_sdl2.cpp")
self.__copy_imgui_binding("imgui_impl_sdl2.h")
if self.settings.os == "Windows":
self.__copy_imgui_binding("imgui_impl_dx9.cpp")
self.__copy_imgui_binding("imgui_impl_dx9.h")

if self.settings.os == "Windows":
if self.settings.build_type == "Debug":
self.__install_lib("fmodL.dll")
Expand Down Expand Up @@ -113,3 +121,6 @@ def __install_lib(self, name):

def __install_folder(self, src, dst):
copy_tree(self.recipe_folder + src, self.__dest + dst)

def __copy_imgui_binding(self, name):
self.copy(name, dst=str(self.options.output_directory) + "/imgui", src="res/bindings")
1 change: 1 addition & 0 deletions src/apps/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ STORM_SETUP(
sentry-native
${SDL2_LIBRARIES}
zlib
cli11

# system
${SYSTEM_DEPS}
Expand Down
27 changes: 24 additions & 3 deletions src/apps/engine/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
#include <mimalloc-new-delete.h>
#include <mimalloc.h>
#include <spdlog/spdlog.h>
#include <CLI/CLI.hpp>

#include "core_private.h"
#include "fs.h"
#include "lifecycle_diagnostics_service.hpp"
#include "logging.hpp"
#include "os_window.hpp"
#include "steam_api.hpp"
#include "v_sound_service.h"
#include "fs.h"
#include "watermark.hpp"

namespace
Expand Down Expand Up @@ -120,6 +121,20 @@ void HandleWindowEvent(const storm::OSWindow::Event &event)

int main(int argc, char *argv[])
{
CLI::App app("Storm Engine");

bool enable_editor = false;
app.add_flag("--editor", enable_editor, "Enable in-game editor");

try
{
app.parse(argc, argv);
}
catch (const CLI::ParseError &e)
{
return app.exit(e);
}

// Prevent multiple instances
#ifdef _WIN32 // CreateEventA
if (!CreateEventA(nullptr, false, false, "Global\\FBBD2286-A9F1-4303-B60C-743C3D7AA7BE") ||
Expand Down Expand Up @@ -171,6 +186,7 @@ int main(int argc, char *argv[])

// Init core
core_private = static_cast<CorePrivate *>(&core);
core_private->EnableEditor(enable_editor);
core_private->Init();

// Read config
Expand Down Expand Up @@ -235,8 +251,13 @@ int main(int argc, char *argv[])
isRunning = true;
while (isRunning)
{
SDL_PumpEvents();
SDL_FlushEvents(0, SDL_LASTEVENT);
SDL_Event event{};
while (SDL_PollEvent(&event) )
{
if (auto *editor = core.GetEditor(); editor != nullptr) {
editor->ProcessEvent(event);
}
}

if (bActive || run_in_background)
{
Expand Down
2 changes: 1 addition & 1 deletion src/libs/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
STORM_SETUP(
TARGET_NAME core
TYPE library
DEPENDENCIES diagnostics math shared_headers steam_api fast_float ${SDL2_LIBRARIES} window tomlplusplus nlohmann_json
DEPENDENCIES diagnostics editor math shared_headers steam_api fast_float ${SDL2_LIBRARIES} window tomlplusplus nlohmann_json
)
7 changes: 7 additions & 0 deletions src/libs/core/include/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "v_data.h"
#include "v_file_service.h"

#include <storm/editor/engine_editor.hpp>

struct IFUNCINFO;

struct ScreenSize
Expand Down Expand Up @@ -51,6 +53,9 @@ class Core
public:
virtual ~Core() = default;

virtual void InitializeEditor(IDirect3DDevice9 *device) = 0;
virtual bool IsEditorEnabled() = 0;

// return application window
virtual storm::OSWindow *GetWindow() = 0;
// set time scale; affect on std entity functions DeltaTime parameter
Expand Down Expand Up @@ -131,6 +136,8 @@ class Core
virtual bool IsLayerFrozen(layer_index_t index) const = 0;
virtual void ForEachEntity(const std::function<void(entptr_t)> &f) = 0;

[[nodiscard]] virtual storm::editor::EngineEditor *GetEditor() = 0;

CONTROLS *Controls{};
};

Expand Down
2 changes: 2 additions & 0 deletions src/libs/core/include/core_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ class CorePrivate : public Core
virtual void collectCrashInfo() const = 0;

virtual void SetWindow(std::shared_ptr<storm::OSWindow> window) = 0;

virtual void EnableEditor(bool enable) = 0;
};
2 changes: 2 additions & 0 deletions src/libs/core/include/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class Entity
return {};
}

virtual void ShowEditor();

private:
EntitySelfData data_{};
};
28 changes: 25 additions & 3 deletions src/libs/core/src/core_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,25 @@ void CoreImpl::Init()
SetLayerType(EDITOR_REALIZE, layer_type_t::realize);
SetLayerType(INFO_REALIZE, layer_type_t::realize);
SetLayerType(SOUND_DEBUG_REALIZE, layer_type_t::realize);

storm::editor::EngineEditor::RegisterEditorTool("Entities", [this] (bool &active) {
entity_manager_.ShowEditor(active);
});
}

void CoreImpl::InitializeEditor(IDirect3DDevice9 *device)
{
editor_ = std::make_unique<storm::editor::EngineEditor>(GetWindow()->SDLHandle(), device);
}

bool CoreImpl::IsEditorEnabled()
{
return isEditorEnabled_;
}

void CoreImpl::EnableEditor(bool enable)
{
isEditorEnabled_ = enable;
}

void CoreImpl::InitBase()
Expand Down Expand Up @@ -299,9 +318,7 @@ void CoreImpl::ProcessEngineIniFile()

if (iScriptVersion != ENGINE_SCRIPT_VERSION)
{
#ifdef _WIN32 // FIX_LINUX Cursor
ShowCursor(true);
#endif
GetWindow()->ShowCursor(true);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", "Wrong script version", nullptr);
Compiler->ExitProgram();
}
Expand Down Expand Up @@ -1022,6 +1039,11 @@ void CoreImpl::ForEachEntity(const std::function<void(entptr_t)> &f)
entity_manager_.ForEachEntity(f);
}

storm::editor::EngineEditor *CoreImpl::GetEditor()
{
return editor_.get();
}

void CoreImpl::collectCrashInfo() const
{
Compiler->CollectCallStack();
Expand Down
8 changes: 8 additions & 0 deletions src/libs/core/src/core_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class CoreImpl final : public CorePrivate
{
public:
void Init() override;
void InitializeEditor(IDirect3DDevice9 *device) override;
bool IsEditorEnabled() override;
void EnableEditor(bool enable) override;

void InitBase() override;
void ReleaseBase() override;
Expand Down Expand Up @@ -133,6 +136,8 @@ class CoreImpl final : public CorePrivate
bool IsLayerFrozen(layer_index_t index) const override;
void ForEachEntity(const std::function<void(entptr_t)>& f) override;

storm::editor::EngineEditor *GetEditor() override;

void collectCrashInfo() const override;

[[nodiscard]] bool initialized() const override
Expand All @@ -151,6 +156,8 @@ class CoreImpl final : public CorePrivate

EntityManager entity_manager_;

std::unique_ptr<storm::editor::EngineEditor> editor_;

storm::ENGINE_VERSION targetVersion_ = storm::ENGINE_VERSION::LATEST;

bool stopFrameProcessing_ = false;
Expand All @@ -164,6 +171,7 @@ class CoreImpl final : public CorePrivate
char gstring[MAX_PATH]{}; // general purpose string
bool State_loading;
bool bEnableTimeScale{};
bool isEditorEnabled_ = false;

SERVICES_LIST Services_List; // list for subsequent calls RunStart/RunEnd service functions

Expand Down
8 changes: 8 additions & 0 deletions src/libs/core/src/entity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "entity.h"

#include <imgui.h>

void Entity::ShowEditor()
{
ImGui::Text("Selected entity does not expose any properties");
}
63 changes: 63 additions & 0 deletions src/libs/core/src/entity_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <chrono>
#include <functional>
#include <imgui.h>

namespace
{
Expand Down Expand Up @@ -486,3 +487,65 @@ void EntityManager::ForEachEntity(const std::function<void(entptr_t)> &f)
}
});
}

void EntityManager::ShowEditor(bool &active)
{
if (ImGui::Begin("Entities", &active, 0))
{
auto text = std::format("There are currently {} entities", entities_.size() - freeIndices_.size());
ImGui::Text(text.c_str());

static entid_t selected_entity = invalid_entity;

if (ImGui::BeginTable("Entities", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable) )
{
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Class", ImGuiTableColumnFlags_WidthStretch);

ImGui::TableHeadersRow();

std::ranges::for_each(entities_, [&](const EntityInternalData &data) {
if (data.state == kValid)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();

std::string label = std::to_string(data.id);
if (ImGui::Selectable(label.c_str(), data.id == selected_entity, ImGuiSelectableFlags_SpanAllColumns) )
{
selected_entity = data.id;
}
ImGui::TableNextColumn();

VMA *pClass = nullptr;
for (const auto &c : __STORM_CLASSES_REGISTRY)
{
if (c->GetHash() == data.hash)
{
pClass = c;
break;
}
}
if (pClass != nullptr)
{
ImGui::Text("%s", pClass->GetName());
}
}
});

ImGui::EndTable();
}

if (ImGui::Begin("Entity Properties") )
{
Entity *entity = GetEntityPointer(selected_entity);
if (entity != nullptr)
{
entity->ShowEditor();
}
ImGui::End();
}

ImGui::End();
}
}
2 changes: 2 additions & 0 deletions src/libs/core/src/entity_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class EntityManager final
void NewLifecycle();
void ForEachEntity(const std::function<void(entptr_t)> &f);

void ShowEditor(bool &active);

private:
constexpr static size_t kMaxLayerNum = sizeof(uint32_t) * 8;

Expand Down
22 changes: 22 additions & 0 deletions src/libs/editor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
if (NOT WIN32)
set(SYSTEM_DEPS "${NATIVE_D3D9_LIBS}")
endif()

set(IMGUI_BINGINDS_DIR "${CMAKE_BINARY_DIR}/imgui")

add_library(imgui_backend STATIC
"${IMGUI_BINGINDS_DIR}/imgui_impl_sdl2.cpp"
)
if (WIN32)
target_sources(imgui_backend PRIVATE "${IMGUI_BINGINDS_DIR}/imgui_impl_dx9.cpp")
endif()

target_include_directories(imgui_backend PUBLIC ${IMGUI_BINGINDS_DIR})
target_link_libraries(imgui_backend PUBLIC imgui ${SDL2_LIBRARIES} ${SYSTEM_DEPS})

STORM_SETUP(
TARGET_NAME editor
TYPE storm_module
DEPENDENCIES core imgui_backend
TEST_DEPENDENCIES catch2
)
48 changes: 48 additions & 0 deletions src/libs/editor/include/storm/editor/engine_editor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#include <functional>
#include <memory>
#include <string_view>

struct SDL_Window;
union SDL_Event;
struct IDirect3DDevice9;

namespace storm::editor
{

enum class DebugFlag
{
RenderWireframe,
SoundDebug,
LocationDebug,
ExtendedLocationDebug,
CannonDebug,
};

using EditorToolCallback = std::function<void(bool &active)>;

class EngineEditor final
{
public:
explicit EngineEditor(SDL_Window *window, IDirect3DDevice9 *device);
~EngineEditor();

void StartFrame();
void EndFrame();

void ProcessEvent(SDL_Event &event);

bool IsFocused() const;

bool IsDebugFlagEnabled(DebugFlag flag) const;

static void RegisterEditorTool(const std::string_view &title, EditorToolCallback callback);

private:
class Impl;

std::unique_ptr<Impl> impl_;
};

} // namespace storm::editor
Loading

0 comments on commit 9f9f169

Please sign in to comment.