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 ECS support for Fabulist. #445

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
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
6 changes: 6 additions & 0 deletions include/NovelRT/Ecs/Configurator.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,14 @@ namespace NovelRT::Ecs
Input::InputEventComponent{0, NovelRT::Input::KeyState::Idle, 0, 0},
"NovelRT::Ecs::Input::InputEventComponent");

// You can register additional components here. - Matt
target.GetComponentCache().RegisterComponentType(
Narrative::NarrativePlayerStateComponent{Narrative::NarrativePlayerState::RequestDestroy,0, 0}, "NovelRT::Ecs::Narrative::NarrativePlayerStateComponent");

target.RegisterSystem(
std::make_shared<Ecs::Input::InputSystem>(_windowingPluginProvider, _inputPluginProvider));

target.RegisterSystem(std::make_shared<Ecs::Narrative::NarrativePlayerSystem>());
}

public:
Expand Down
1 change: 1 addition & 0 deletions include/NovelRT/Ecs/Ecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ namespace NovelRT::Ecs
#include "Graphics/Ecs.Graphics.h"
#include "Audio/Ecs.Audio.h"
#include "Input/Ecs.Input.h"
#include "Narrative/Ecs.Narrative.h"
#include "Configurator.h"
#include "LinkedEntityListView.h"
#include "EntityGraphView.h"
Expand Down
39 changes: 39 additions & 0 deletions include/NovelRT/Ecs/Narrative/CharacterInformation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <utility>

// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root
// for more information.

#ifndef NOVELRT_CHARACTERINFORMATION_H
#define NOVELRT_CHARACTERINFORMATION_H

#ifndef NOVELRT_ECS_H
#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset.
#endif

namespace NovelRT::Ecs::Narrative
{
// This type currently does not have a CPP file due to its simplicity. Feel free to add one if you end up writing logic that shouldn't be inlined.
class CharacterInformation
{
private:
Atom _characterId;
std::string _name;

public:
CharacterInformation(Atom characterId, std::string name) noexcept : _characterId(characterId), _name(std::move(name))
{
}

[[nodiscard]] inline Atom GetCharacterId() const noexcept
{
return _characterId;
}

[[nodiscard]] const std::string& GetName() const noexcept
{
return _name;
}
};
}

#endif // NOVELRT_CHARACTERINFORMATION_H
40 changes: 40 additions & 0 deletions include/NovelRT/Ecs/Narrative/DefaultNarrativeComponentTypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root
// for more information.

#ifndef NOVELRT_ECS_NARRATIVE_DEFAULTNARRATIVECOMPONENTTYPES_H
#define NOVELRT_ECS_NARRATIVE_DEFAULTNARRATIVECOMPONENTTYPES_H

#ifndef NOVELRT_ECS_H
#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset.
#endif

namespace NovelRT::Ecs::Narrative
{
// I couldn't think of any other component types we might need, so for now this is all we got. - Matt
struct NarrativePlayerStateComponent
{
NarrativePlayerState currentState = NarrativePlayerState::Idle;
Atom sectionId = 0;
Atom characterId = 0;

inline NarrativePlayerStateComponent& operator+=(const NarrativePlayerStateComponent& other)
{
currentState = other.currentState;
sectionId = other.sectionId;
characterId = other.characterId;
return *this;
}

inline bool operator==(const NarrativePlayerStateComponent& other) const noexcept
{
return currentState == other.currentState && sectionId == other.sectionId && characterId == other.characterId;
}

inline bool operator!=(const NarrativePlayerStateComponent& other) const noexcept
{
return !(*this == other);
}
};
}

#endif // NOVELRT_ECS_NARRATIVE_DEFAULTNARRATIVECOMPONENTTYPES_H
26 changes: 26 additions & 0 deletions include/NovelRT/Ecs/Narrative/Ecs.Narrative.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root
// for more information.

#ifndef NOVELRT_ECS_NARRATIVE_H
#define NOVELRT_ECS_NARRATIVE_H

#ifndef NOVELRT_ECS_H
#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset.
#endif

namespace NovelRT::Ecs::Narrative
{
enum class NarrativePlayerState : uint32_t;
struct NarrativePlayerStateComponent;
class NarrativePlayerSystem;
class CharacterInformation;
}

// clang-format off
#include "NarrativePlayerState.h"
#include "DefaultNarrativeComponentTypes.h"
#include "NarrativePlayerSystem.h"
#include "CharacterInformation.h"
// clang-format on

#endif // NOVELRT_ECS_NARRATIVE_H
23 changes: 23 additions & 0 deletions include/NovelRT/Ecs/Narrative/NarrativePlayerState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root
// for more information.

#ifndef NOVELRT_NARRATIVEPLAYERSTATE_H
#define NOVELRT_NARRATIVEPLAYERSTATE_H

#ifndef NOVELRT_ECS_H
#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset.
#endif

namespace NovelRT::Ecs::Narrative
{
enum class NarrativePlayerState : uint32_t
{
Idle = 0,
RequestPlay = 1,
Playing = 2,
RequestStop = 3,
RequestDestroy = 4
};
}

#endif // NOVELRT_NARRATIVEPLAYERSTATE_H
32 changes: 32 additions & 0 deletions include/NovelRT/Ecs/Narrative/NarrativePlayerSystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root
// for more information.

#ifndef NOVELRT_NARRATIVEPLAYERSYSTEM_H
#define NOVELRT_NARRATIVEPLAYERSYSTEM_H

#ifndef NOVELRT_ECS_H
#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset.
#endif

namespace NovelRT::Ecs::Narrative
{
// This type should be as immutable as possible. Any methods that mutate the system that aren't Update() either need to be made thread-safe or specified it should be called from some well-defined location. - Matt
class NarrativePlayerSystem final : public IEcsSystem
{
private:
// Nothing here yet lol. - Matt

public:
void Update(Timing::Timestamp delta, Catalogue catalogue) final; // update loop for the ECS. - Matt

// These four should be inlined, if possible. - Matt
[[nodiscard]] const std::string& GetSectionName(Atom sectionId) const;
[[nodiscard]] Atom GetSectionName(const std::string& name) const;
[[nodiscard]] const CharacterInformation& GetCharacterInformation(Atom characterId) const;
[[nodiscard]] const CharacterInformation& GetCharacterInformation(const std::string& characterName) const;

void RegisterInformationToCharacter(const std::string& name); // We will probably update/expand this as we figure out what information would be good for a CharacterInformation object. - Matt
};
}

#endif // NOVELRT_NARRATIVEPLAYERSYSTEM_H
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace NovelRT::ResourceManagement::Desktop
protected:
[[nodiscard]] TextureMetadata LoadTexture(std::filesystem::path filePath) final;
[[nodiscard]] std::vector<uint8_t> LoadShaderSourceInternal(std::filesystem::path filePath) final;
[[nodiscard]] std::unique_ptr<std::istream> GetStreamToAsset(std::filesystem::path filePath) final;

public:
~DesktopResourceLoader() final = default;
Expand Down
7 changes: 7 additions & 0 deletions include/NovelRT/ResourceManagement/ResourceLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ namespace NovelRT::ResourceManagement
return LoadShaderSourceInternal(_resourcesRootDirectory / "Shaders" / fileName);
}

[[nodiscard]] virtual std::unique_ptr<std::istream> GetStreamToAsset(std::filesystem::path filePath) = 0;

[[nodiscard]] inline std::unique_ptr<std::istream> GetStreamToAssetRelativePath(const std::filesystem::path& relativeFilePath)
{
return GetStreamToAsset(ResourcesRootDirectory() / relativeFilePath);
}

virtual ~ResourceLoader() = default;
};
}
Expand Down
1 change: 1 addition & 0 deletions src/NovelRT/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ set(SOURCES
Ecs/Graphics/DefaultRenderingSystem.cpp
Ecs/Audio/AudioSystem.cpp
Ecs/Input/InputSystem.cpp
Ecs/Narrative/NarrativePlayerSystem.cpp

EngineConfig.cpp

Expand Down
41 changes: 41 additions & 0 deletions src/NovelRT/Ecs/Narrative/NarrativePlayerSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root
// for more information.

#include <NovelRT/Ecs/Ecs.h>
#include "NovelRT/Ecs/Narrative/NarrativePlayerSystem.h"

namespace NovelRT::Ecs::Narrative
{
void NarrativePlayerSystem::Update(Timing::Timestamp delta, Catalogue catalogue)
{
auto playerStateBuffer = catalogue.GetComponentView<NarrativePlayerStateComponent>();

for (auto [entity, playerStateComponent] : playerStateBuffer)
{
switch (playerStateComponent.currentState)
{
// Do nothing. - Matt
case NarrativePlayerState::Idle:
break;
// Set state to playing and execute the section accordingly. You should update the instruction call here to represent correct state. - Matt
case NarrativePlayerState::RequestPlay:
playerStateBuffer.PushComponentUpdateInstruction(entity, NarrativePlayerStateComponent{NarrativePlayerState::Playing, playerStateComponent.sectionId, playerStateComponent.characterId});
break;
// Ensure that the player state component gets an update on accurate information e.g. which character is talking and which section is running. - Matt
case NarrativePlayerState::Playing:
break;
// Set state to Idle and stop executing. - Matt
case NarrativePlayerState::RequestStop:
break;
// Destroy the narrative player state component and then do whatever you see fit internally based on that. - Matt
case NarrativePlayerState::RequestDestroy:
playerStateBuffer.RemoveComponent(entity);
break;
}
}
}

void NarrativePlayerSystem::RegisterInformationToCharacter(const std::string& name)
{
}
}
12 changes: 12 additions & 0 deletions src/NovelRT/ResourceManagement/Desktop/DesktopResourceLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,16 @@ namespace NovelRT::ResourceManagement::Desktop

return buffer;
}

std::unique_ptr<std::istream> DesktopResourceLoader::GetStreamToAsset(std::filesystem::path filePath)
{
auto file = std::make_unique<std::ifstream>(filePath.string());

if (!file->is_open())
{
throw NovelRT::Exceptions::FileNotFoundException(filePath.string());
}

return file;
}
}