more styling. TODO: finish window.hpp

This commit is contained in:
Bailey Harrison 2023-04-29 15:56:49 +01:00
parent c5b7a09e63
commit bbc9af3b11
11 changed files with 466 additions and 292 deletions

249
.clang-format Normal file
View File

@ -0,0 +1,249 @@
---
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: NextLine
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PenaltyIndentedWhitespace: 0
PointerAlignment: Left
PPIndentWidth: -1
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RequiresClausePosition: OwnLine
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...

View File

@ -2,6 +2,7 @@
#define ENGINE_INCLUDE_APPLICATION_H_ #define ENGINE_INCLUDE_APPLICATION_H_
#include <assert.h> #include <assert.h>
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
#include <string> #include <string>
@ -44,8 +45,7 @@ struct RenderData {
}; };
class Application { class Application {
public:
public:
Application(const char* app_name, const char* app_version, Application(const char* app_name, const char* app_version,
gfx::GraphicsSettings graphics_settings); gfx::GraphicsSettings graphics_settings);
~Application(); ~Application();
@ -55,8 +55,7 @@ public:
/* resource stuff */ /* resource stuff */
template <typename T> template <typename T>
void RegisterResourceManager() void RegisterResourceManager() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(resource_managers_.contains(hash) == false && assert(resource_managers_.contains(hash) == false &&
"Registering resource manager type more than once."); "Registering resource manager type more than once.");
@ -65,15 +64,13 @@ public:
template <typename T> template <typename T>
std::shared_ptr<T> AddResource(const std::string& name, std::shared_ptr<T> AddResource(const std::string& name,
std::unique_ptr<T>&& resource) std::unique_ptr<T>&& resource) {
{
auto resource_manager = GetResourceManager<T>(); auto resource_manager = GetResourceManager<T>();
return resource_manager->Add(name, std::move(resource)); return resource_manager->Add(name, std::move(resource));
} }
template <typename T> template <typename T>
std::shared_ptr<T> GetResource(const std::string& name) std::shared_ptr<T> GetResource(const std::string& name) {
{
auto resource_manager = GetResourceManager<T>(); auto resource_manager = GetResourceManager<T>();
return resource_manager->Get(name); return resource_manager->Get(name);
} }
@ -95,7 +92,7 @@ public:
RenderData render_data_{}; RenderData render_data_{};
private: private:
std::unique_ptr<Window> window_; std::unique_ptr<Window> window_;
std::unique_ptr<InputManager> input_manager_; std::unique_ptr<InputManager> input_manager_;
std::unique_ptr<SceneManager> scene_manager_; std::unique_ptr<SceneManager> scene_manager_;
@ -106,8 +103,7 @@ private:
bool enable_frame_limiter_ = true; bool enable_frame_limiter_ = true;
template <typename T> template <typename T>
ResourceManager<T>* GetResourceManager() ResourceManager<T>* GetResourceManager() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto it = resource_managers_.find(hash); auto it = resource_managers_.find(hash);
if (it == resource_managers_.end()) { if (it == resource_managers_.end()) {
@ -118,9 +114,8 @@ private:
assert(casted_ptr != nullptr); assert(casted_ptr != nullptr);
return casted_ptr; return casted_ptr;
} }
}; };
} } // namespace engine
#endif #endif

View File

@ -15,28 +15,22 @@ class Scene;
constexpr size_t kMaxComponents = 64; constexpr size_t kMaxComponents = 64;
class IComponentArray { class IComponentArray {
public: public:
virtual ~IComponentArray() = default; virtual ~IComponentArray() = default;
}; };
template<typename T> template <typename T>
class ComponentArray : public IComponentArray { class ComponentArray : public IComponentArray {
public:
public: void InsertData(uint32_t entity, T component) {
void InsertData(uint32_t entity, T component)
{
assert(component_array_.find(entity) == component_array_.end() && assert(component_array_.find(entity) == component_array_.end() &&
"Adding component which already exists to entity"); "Adding component which already exists to entity");
component_array_.emplace(entity, component); component_array_.emplace(entity, component);
} }
void DeleteData(uint32_t entity) void DeleteData(uint32_t entity) { component_array_.erase(entity); }
{
component_array_.erase(entity);
}
T* GetData(uint32_t entity) T* GetData(uint32_t entity) {
{
if (component_array_.contains(entity)) { if (component_array_.contains(entity)) {
return &(component_array_.at(entity)); return &(component_array_.at(entity));
} else { } else {
@ -44,14 +38,12 @@ public:
} }
} }
private: private:
std::map<uint32_t, T> component_array_{}; std::map<uint32_t, T> component_array_{};
}; };
class System { class System {
public:
public:
System(Scene* scene, std::set<size_t> required_component_hashes); System(Scene* scene, std::set<size_t> required_component_hashes);
virtual ~System() {} virtual ~System() {}
System(const System&) = delete; System(const System&) = delete;
@ -68,7 +60,6 @@ public:
// entities that contain the needed components // entities that contain the needed components
std::set<uint32_t> entities_{}; std::set<uint32_t> entities_{};
}; };
} // namespace engine } // namespace engine

View File

@ -16,13 +16,13 @@ enum class EventSubscriberKind {
// Event handler base-class // Event handler base-class
template <typename T> template <typename T>
class EventHandler { class EventHandler {
public: public:
virtual void OnEvent(T data) = 0; virtual void OnEvent(T data) = 0;
}; };
// Event queue interface to allow for different type queues to be in the map // Event queue interface to allow for different type queues to be in the map
class IEventQueue { class IEventQueue {
public: public:
virtual ~IEventQueue() {} virtual ~IEventQueue() {}
virtual void DespatchEvents() = 0; virtual void DespatchEvents() = 0;
}; };
@ -31,29 +31,26 @@ template <typename T>
class EventQueue : public IEventQueue { class EventQueue : public IEventQueue {
// holds events of type T and subscribers to those events // holds events of type T and subscribers to those events
public: public:
void Subscribe(EventSubscriberKind kind, uint32_t id, void Subscribe(EventSubscriberKind kind, uint32_t id,
EventHandler<T>* handler) EventHandler<T>* handler) {
{
// For the time being, ignore kind (TODO) // For the time being, ignore kind (TODO)
(void)kind; (void)kind;
assert(subscribers_.contains(id) == false && assert(subscribers_.contains(id) == false &&
"subscribing to an event with ID that's already in use!"); "subscribing to an event with ID that's already in use!");
subscribers_.emplace(id, handler); subscribers_.emplace(id, handler);
} }
void QueueEvent(EventSubscriberKind kind, uint32_t id, T event) void QueueEvent(EventSubscriberKind kind, uint32_t id, T event) {
{
// For the time being, ignore kind (TODO) // For the time being, ignore kind (TODO)
(void)kind; (void)kind;
assert(subscribers_.contains(id) && assert(subscribers_.contains(id) &&
"Attempt to submit event to non-existing subscriber!"); "Attempt to submit event to non-existing subscriber!");
EventHandler<T>* handler = subscribers_.at(id); EventHandler<T>* handler = subscribers_.at(id);
event_queue_.emplace(handler, event); event_queue_.emplace(handler, event);
} }
void DespatchEvents() override void DespatchEvents() override {
{
while (event_queue_.empty() == false) { while (event_queue_.empty() == false) {
auto [handler, event] = event_queue_.front(); auto [handler, event] = event_queue_.front();
handler->OnEvent(event); handler->OnEvent(event);
@ -61,74 +58,65 @@ public:
} }
} }
private: private:
std::unordered_map<uint32_t, EventHandler<T>*> subscribers_; std::unordered_map<uint32_t, EventHandler<T>*> subscribers_;
struct QueuedEvent { struct QueuedEvent {
QueuedEvent(EventHandler<T>* handler, T event)
QueuedEvent(EventHandler<T>* handler, T event) : : handler(handler), event(event) {}
handler(handler),
event(event) {}
EventHandler<T>* handler; EventHandler<T>* handler;
T event; T event;
}; };
std::queue<QueuedEvent> event_queue_{}; std::queue<QueuedEvent> event_queue_{};
}; };
class EventSystem { class EventSystem {
public:
public:
EventSystem() {} EventSystem() {}
EventSystem(const EventSystem&) = delete; EventSystem(const EventSystem&) = delete;
EventSystem& operator=(const EventSystem&) = delete; EventSystem& operator=(const EventSystem&) = delete;
~EventSystem() {} ~EventSystem() {}
template <typename T> template <typename T>
void RegisterEventType() void RegisterEventType() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(event_queues_.contains(hash) == false && assert(event_queues_.contains(hash) == false &&
"Registering an event queue more than once!"); "Registering an event queue more than once!");
event_queues_.emplace(hash, std::make_unique<EventQueue<T>>()); event_queues_.emplace(hash, std::make_unique<EventQueue<T>>());
} }
template <typename T> template <typename T>
void SubscribeToEventType(EventSubscriberKind kind, uint32_t id, void SubscribeToEventType(EventSubscriberKind kind, uint32_t id,
EventHandler<T>* handler) EventHandler<T>* handler) {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(event_queues_.contains(hash) && assert(event_queues_.contains(hash) &&
"Subscribing to event type that isn't registered!"); "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>( EventQueue<T>* queue =
event_queues_.at(hash).get()); dynamic_cast<EventQueue<T>*>(event_queues_.at(hash).get());
assert(queue != nullptr && "This cast should work?!! wot"); assert(queue != nullptr && "This cast should work?!! wot");
queue->Subscribe(kind, id, handler); queue->Subscribe(kind, id, handler);
} }
template <typename T> template <typename T>
void QueueEvent(EventSubscriberKind kind, uint32_t subscriber_id, T event) void QueueEvent(EventSubscriberKind kind, uint32_t subscriber_id, T event) {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(event_queues_.contains(hash) && assert(event_queues_.contains(hash) &&
"Subscribing to event type that isn't registered!"); "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>( EventQueue<T>* queue =
event_queues_.at(hash).get()); dynamic_cast<EventQueue<T>*>(event_queues_.at(hash).get());
assert(queue != nullptr && "This cast should work?!! wot"); assert(queue != nullptr && "This cast should work?!! wot");
queue->QueueEvent(kind, subscriber_id, event); queue->QueueEvent(kind, subscriber_id, event);
} }
void DespatchEvents() void DespatchEvents() {
{
for (auto& [hash, queue] : event_queues_) { for (auto& [hash, queue] : event_queues_) {
queue->DespatchEvents(); queue->DespatchEvents();
} }
} }
private: private:
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> event_queues_{}; std::unordered_map<size_t, std::unique_ptr<IEventQueue>> event_queues_{};
}; };
} // namespace engine } // namespace engine

View File

@ -30,9 +30,7 @@ enum class MSAALevel {
}; };
struct GraphicsSettings { struct GraphicsSettings {
GraphicsSettings() {
GraphicsSettings()
{
// sane defaults // sane defaults
enable_validation = true; enable_validation = true;
vsync = true; vsync = true;
@ -47,7 +45,6 @@ struct GraphicsSettings {
// (no affect with V-sync disabled) // (no affect with V-sync disabled)
bool wait_for_present; bool wait_for_present;
MSAALevel msaa_level; MSAALevel msaa_level;
}; };
enum class ShaderType { enum class ShaderType {
@ -69,11 +66,7 @@ enum class Primitive {
kTriangleStrip, kTriangleStrip,
}; };
enum class VertexAttribFormat { enum class VertexAttribFormat { kFloat2, kFloat3, kFloat4 };
kFloat2,
kFloat3,
kFloat4
};
enum class Filter : int { enum class Filter : int {
kLinear, kLinear,
@ -86,20 +79,18 @@ enum class DescriptorType {
}; };
namespace ShaderStageFlags { namespace ShaderStageFlags {
enum Bits : uint32_t { enum Bits : uint32_t {
kVertex = 1 << 0, kVertex = 1 << 0,
kFragment = 1 << 1, kFragment = 1 << 1,
}; };
typedef std::underlying_type<Bits>::type Flags; typedef std::underlying_type<Bits>::type Flags;
} } // namespace ShaderStageFlags
struct VertexAttribDescription { struct VertexAttribDescription {
VertexAttribDescription(uint32_t location, VertexAttribFormat format, VertexAttribDescription(uint32_t location, VertexAttribFormat format,
uint32_t offset) : uint32_t offset)
location(location), : location(location), format(format), offset(offset) {}
format(format), uint32_t location; // the index to use in the shader
offset(offset) {}
uint32_t location; // the index to use in the shader
VertexAttribFormat format; VertexAttribFormat format;
uint32_t offset; uint32_t offset;
}; };
@ -136,11 +127,9 @@ struct SamplerInfo {
} // namespace engine } // namespace engine
namespace std { namespace std {
template<> template <>
struct std::hash<engine::gfx::SamplerInfo> struct std::hash<engine::gfx::SamplerInfo> {
{ std::size_t operator()(const engine::gfx::SamplerInfo& k) const {
std::size_t operator()(const engine::gfx::SamplerInfo& k) const
{
using std::hash; using std::hash;
size_t h1 = hash<int>()(static_cast<int>(k.minify)); size_t h1 = hash<int>()(static_cast<int>(k.minify));
@ -148,9 +137,7 @@ struct std::hash<engine::gfx::SamplerInfo>
size_t h3 = hash<int>()(static_cast<int>(k.mipmap)); size_t h3 = hash<int>()(static_cast<int>(k.mipmap));
size_t h4 = hash<bool>()(k.anisotropic_filtering); size_t h4 = hash<bool>()(k.anisotropic_filtering);
return ((h1 & 0xFF) << 24) | return ((h1 & 0xFF) << 24) | ((h2 & 0xFF) << 16) | ((h3 & 0xFF) << 8) |
((h2 & 0xFF) << 16) |
((h3 & 0xFF) << 8) |
((h4 & 0xFF) << 0); ((h4 & 0xFF) << 0);
} }
}; };

View File

@ -5,148 +5,138 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "window.hpp"
#include "inputs/mouse.hpp"
#include "inputs/keyboard.hpp" #include "inputs/keyboard.hpp"
#include "inputs/mouse.hpp"
#include "window.hpp"
namespace engine { namespace engine {
enum class InputDevice : int { enum class InputDevice : int { kMouse, kKeyboard, kController, kSize };
kMouse,
kKeyboard,
kController,
kSize
};
// This class should be used to get platform/input-device independent input // This class should be used to get platform/input-device independent input
class InputManager { class InputManager {
public:
/* The Window object here is stored for the duration of the InputManager.
* 'win' must point to a valid Window object. */
InputManager(const Window* win) : win_(win) {
assert(win != nullptr);
enabled_devices_.fill(true);
}
InputManager(const InputManager&) = delete;
public: InputManager& operator=(const InputManager&) = delete;
/* The Window object here is stored for the duration of the InputManager. ~InputManager() {}
* 'win' must point to a valid Window object. */
InputManager(const Window* win) : win_(win) {
assert(win != nullptr);
enabled_devices_.fill(true);
}
InputManager(const InputManager&) = delete;
InputManager& operator=(const InputManager&) = delete; void AddInputButton(const std::string& name, inputs::MouseButton button) {
AddInputDeviceButton(name, InputDevice::kMouse, static_cast<int>(button));
}
~InputManager() {} void AddInputButton(const std::string& name, inputs::Key button) {
AddInputDeviceButton(name, InputDevice::kKeyboard,
void AddInputButton(const std::string& name, inputs::MouseButton button) {
AddInputDeviceButton(name, InputDevice::kMouse,
static_cast<int>(button)); static_cast<int>(button));
} }
void AddInputButton(const std::string& name, inputs::Key button) { void AddInputAxis(const std::string& name, inputs::MouseAxis axis) {
AddInputDeviceButton(name, InputDevice::kKeyboard, AddInputDeviceAxis(name, InputDevice::kMouse, static_cast<int>(axis));
static_cast<int>(button)); }
}
void AddInputAxis(const std::string& name, inputs::MouseAxis axis) { void AddInputButtonAsAxis(const std::string& name, inputs::MouseButton high,
AddInputDeviceAxis(name, InputDevice::kMouse, static_cast<int>(axis));
}
void AddInputButtonAsAxis(const std::string& name, inputs::MouseButton high,
inputs::MouseButton low) { inputs::MouseButton low) {
AddInputDeviceButtonAsAxis(name, InputDevice::kMouse, AddInputDeviceButtonAsAxis(name, InputDevice::kMouse,
static_cast<int>(high), static_cast<int>(low)); static_cast<int>(high), static_cast<int>(low));
} }
void AddInputButtonAsAxis(const std::string& name, inputs::Key high, void AddInputButtonAsAxis(const std::string& name, inputs::Key high,
inputs::Key low) { inputs::Key low) {
AddInputDeviceButtonAsAxis(name, InputDevice::kKeyboard, AddInputDeviceButtonAsAxis(name, InputDevice::kKeyboard,
static_cast<int>(high), static_cast<int>(low)); static_cast<int>(high), static_cast<int>(low));
} }
void DelInputButton(int index) { void DelInputButton(int index) {
std::vector<struct ButtonEntry>::iterator it = button_entries_.begin(); std::vector<struct ButtonEntry>::iterator it = button_entries_.begin();
std::advance(it, index); std::advance(it, index);
button_entries_.erase(it); button_entries_.erase(it);
} }
void DelInputAxis(int index) { void DelInputAxis(int index) {
std::vector<struct AxisEntry>::iterator it = axis_entries_.begin(); std::vector<struct AxisEntry>::iterator it = axis_entries_.begin();
std::advance(it, index); std::advance(it, index);
axis_entries_.erase(it); axis_entries_.erase(it);
} }
void SetDeviceActive(enum InputDevice device, bool active) { void SetDeviceActive(enum InputDevice device, bool active) {
enabled_devices_[static_cast<int>(device)] = active; enabled_devices_[static_cast<int>(device)] = active;
} }
bool GetDeviceActive(enum InputDevice device) const { bool GetDeviceActive(enum InputDevice device) const {
return enabled_devices_[static_cast<int>(device)]; return enabled_devices_[static_cast<int>(device)];
} }
float GetAxis(const std::string& axis_name) const; float GetAxis(const std::string& axis_name) const;
bool GetButton(const std::string& button_name) const; bool GetButton(const std::string& button_name) const;
bool GetButtonPress(const std::string& button_name) const; bool GetButtonPress(const std::string& button_name) const;
bool GetButtonRelease(const std::string& button_name) const; bool GetButtonRelease(const std::string& button_name) const;
private: private:
struct ButtonEntry {
std::string name;
enum InputDevice device;
int button; // enumeration of device buttons or axes
};
struct ButtonEntry { struct AxisEntry {
std::string name; std::string name;
enum InputDevice device; enum InputDevice device;
int button; // enumeration of device buttons or axes int axis;
}; bool is_button_axis;
int high;
int low;
};
struct AxisEntry { const Window* win_;
std::string name;
enum InputDevice device;
int axis;
bool is_button_axis;
int high;
int low;
};
const Window* win_; std::vector<struct ButtonEntry> button_entries_;
std::vector<struct AxisEntry> axis_entries_;
std::vector<struct ButtonEntry> button_entries_; std::array<bool, static_cast<int>(InputDevice::kSize)> enabled_devices_;
std::vector<struct AxisEntry> axis_entries_;
std::array<bool, static_cast<int>(InputDevice::kSize)> enabled_devices_; // private methods
// private methods float GetDeviceAxis(enum InputDevice device, int axis) const;
float GetDeviceAxis(enum InputDevice device, int axis) const; bool GetDeviceButton(enum InputDevice device, int button) const;
bool GetDeviceButton(enum InputDevice device, int button) const; bool getDeviceButtonDown(enum InputDevice device, int button) const;
bool getDeviceButtonDown(enum InputDevice device, int button) const; bool GetDeviceButtonUp(enum InputDevice device, int button) const;
bool GetDeviceButtonUp(enum InputDevice device, int button) const; float GetButtonAxis(enum InputDevice device, int high, int low) const {
float value = 0.0f;
if (GetDeviceButton(device, high)) value += 1.0f;
if (low != 0) {
if (GetDeviceButton(device, low)) value += -1.0f;
}
return value;
}
float GetButtonAxis(enum InputDevice device, int high, int low) const { void AddInputDeviceButton(const std::string& name, InputDevice device,
float value = 0.0f;
if (GetDeviceButton(device, high)) value += 1.0f;
if (low != 0) {
if (GetDeviceButton(device, low)) value += -1.0f;
}
return value;
}
void AddInputDeviceButton(const std::string& name, InputDevice device,
int button) { int button) {
button_entries_.push_back({ name, device, button }); button_entries_.push_back({name, device, button});
} }
void AddInputDeviceAxis(const std::string& name, InputDevice device, void AddInputDeviceAxis(const std::string& name, InputDevice device,
int axis) { int axis) {
axis_entries_.push_back({ name, device, axis, false, 0, 0 }); axis_entries_.push_back({name, device, axis, false, 0, 0});
} }
void AddInputDeviceButtonAsAxis(const std::string& name, InputDevice device, void AddInputDeviceButtonAsAxis(const std::string& name, InputDevice device,
int high, int low) { int high, int low) {
axis_entries_.push_back({ name, device, 0, true, high, low }); axis_entries_.push_back({name, device, 0, true, high, low});
} }
}; };
} // namespace engine } // namespace engine

View File

@ -1,28 +1,27 @@
#ifndef ENGINE_INCLUDE_LOGGER_H_ #ifndef ENGINE_INCLUDE_LOGGER_H_
#define ENGINE_INCLUDE_LOGGER_H_ #define ENGINE_INCLUDE_LOGGER_H_
#include "log.hpp"
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <filesystem> #include <filesystem>
#include <memory> #include <memory>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include "log.hpp"
namespace engine { namespace engine {
// To be executed in the target application, NOT engine.dll // To be executed in the target application, NOT engine.dll
void SetupLog(const char* appName) { void SetupLog(const char* appName) {
const std::string LOG_FILENAME{std::string(appName) + ".log"};
const std::string LOG_FILENAME{ std::string(appName) + ".log"};
#ifdef NDEBUG #ifdef NDEBUG
// RELEASE // RELEASE
const std::filesystem::path log_path{ const std::filesystem::path log_path{std::filesystem::temp_directory_path() /
std::filesystem::temp_directory_path() / LOG_FILENAME}; LOG_FILENAME};
#else #else
// DEBUG // DEBUG
const std::filesystem::path log_path{ LOG_FILENAME }; const std::filesystem::path log_path{LOG_FILENAME};
#endif #endif
std::vector<spdlog::sink_ptr> sinks; std::vector<spdlog::sink_ptr> sinks;
@ -34,8 +33,8 @@ void SetupLog(const char* appName) {
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
sinks.back()->set_pattern("[%H:%M:%S.%e] [%l] %v"); sinks.back()->set_pattern("[%H:%M:%S.%e] [%l] %v");
auto logger = std::make_shared<spdlog::logger>(appName, sinks.begin(), auto logger =
sinks.end()); std::make_shared<spdlog::logger>(appName, sinks.begin(), sinks.end());
// Logs below INFO are ignored through macros in release (see log.hpp) // Logs below INFO are ignored through macros in release (see log.hpp)
logger->set_level(spdlog::level::trace); logger->set_level(spdlog::level::trace);
@ -45,7 +44,6 @@ void SetupLog(const char* appName) {
spdlog::flush_every(std::chrono::seconds(60)); spdlog::flush_every(std::chrono::seconds(60));
LOG_INFO("Created log with path: {}", log_path.string()); LOG_INFO("Created log with path: {}", log_path.string());
} }
} // namespace engine } // namespace engine

View File

@ -10,33 +10,29 @@
namespace engine { namespace engine {
class IResourceManager { class IResourceManager {
public: public:
virtual ~IResourceManager() = default; virtual ~IResourceManager() = default;
}; };
template <class T> template <class T>
class ResourceManager : public IResourceManager { class ResourceManager : public IResourceManager {
public:
public: std::shared_ptr<T> Add(const std::string& name,
std::shared_ptr<T> Add(const std::string& name, std::unique_ptr<T>&& resource) std::unique_ptr<T>&& resource) {
{
if (resources_.contains(name) == false) { if (resources_.contains(name) == false) {
std::shared_ptr<T> resource_shared(std::move(resource)); std::shared_ptr<T> resource_shared(std::move(resource));
resources_.emplace(name, resource_shared); resources_.emplace(name, resource_shared);
return resource_shared; return resource_shared;
} } else {
else {
throw std::runtime_error("Cannot add a resource which already exists"); throw std::runtime_error("Cannot add a resource which already exists");
} }
} }
void AddPersistent(const std::string& name, std::unique_ptr<T>&& resource) void AddPersistent(const std::string& name, std::unique_ptr<T>&& resource) {
{
persistent_resources_.push_back(Add(name, std::move(resource))); persistent_resources_.push_back(Add(name, std::move(resource)));
} }
std::shared_ptr<T> Get(const std::string& name) std::shared_ptr<T> Get(const std::string& name) {
{
if (resources_.contains(name)) { if (resources_.contains(name)) {
std::weak_ptr<T> ptr = resources_.at(name); std::weak_ptr<T> ptr = resources_.at(name);
if (ptr.expired() == false) { if (ptr.expired() == false) {
@ -50,11 +46,10 @@ public:
return {}; return {};
} }
private: private:
std::unordered_map<std::string, std::weak_ptr<T>> resources_{}; std::unordered_map<std::string, std::weak_ptr<T>> resources_{};
// This array owns persistent resources // This array owns persistent resources
std::vector<std::shared_ptr<T>> persistent_resources_{}; std::vector<std::shared_ptr<T>> persistent_resources_{};
}; };
} // namespace engine } // namespace engine

View File

@ -14,8 +14,7 @@ namespace engine {
class Application; class Application;
class Scene { class Scene {
public:
public:
Scene(Application* app); Scene(Application* app);
Scene(const Scene&) = delete; Scene(const Scene&) = delete;
Scene& operator=(const Scene&) = delete; Scene& operator=(const Scene&) = delete;
@ -36,31 +35,28 @@ public:
size_t GetComponentSignaturePosition(size_t hash); size_t GetComponentSignaturePosition(size_t hash);
template <typename T> template <typename T>
void registerComponent() void registerComponent() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(component_arrays_.contains(hash) == false && assert(component_arrays_.contains(hash) == false &&
"Registering component type more than once."); "Registering component type more than once.");
component_arrays_.emplace(hash, std::make_unique<ComponentArray<T>>()); component_arrays_.emplace(hash, std::make_unique<ComponentArray<T>>());
size_t signature_position = next_signature_position_; size_t signature_position = next_signature_position_;
++next_signature_position_; ++next_signature_position_;
assert(signature_position < kMaxComponents && assert(signature_position < kMaxComponents &&
"Registering too many components!"); "Registering too many components!");
assert(component_signature_positions_.contains(hash) == false); assert(component_signature_positions_.contains(hash) == false);
component_signature_positions_.emplace(hash, signature_position); component_signature_positions_.emplace(hash, signature_position);
} }
template <typename T> template <typename T>
T* GetComponent(uint32_t entity) T* GetComponent(uint32_t entity) {
{
auto array = GetComponentArray<T>(); auto array = GetComponentArray<T>();
return array->GetData(entity); return array->GetData(entity);
} }
template <typename T> template <typename T>
T* AddComponent(uint32_t entity) T* AddComponent(uint32_t entity) {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto array = GetComponentArray<T>(); auto array = GetComponentArray<T>();
@ -71,8 +67,7 @@ public:
auto& signature_ref = signatures_.at(entity); auto& signature_ref = signatures_.at(entity);
signature_ref.set(signature_position); signature_ref.set(signature_position);
for (auto& [system_name, system] : systems_) for (auto& [system_name, system] : systems_) {
{
if (system->entities_.contains(entity)) continue; if (system->entities_.contains(entity)) continue;
if ((system->signature_ & signature_ref) == system->signature_) { if ((system->signature_ & signature_ref) == system->signature_) {
system->entities_.insert(entity); system->entities_.insert(entity);
@ -84,17 +79,15 @@ public:
} }
template <typename T> template <typename T>
void RegisterSystem() void RegisterSystem() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(systems_.find(hash) == systems_.end() && assert(systems_.find(hash) == systems_.end() &&
"Registering system more than once."); "Registering system more than once.");
systems_.emplace(hash, std::make_unique<T>(this)); systems_.emplace(hash, std::make_unique<T>(this));
} }
template <typename T> template <typename T>
T* GetSystem() T* GetSystem() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto it = systems_.find(hash); auto it = systems_.find(hash);
if (it == systems_.end()) { if (it == systems_.end()) {
@ -106,7 +99,7 @@ public:
return casted_ptr; return casted_ptr;
} }
private: private:
Application* const app_; Application* const app_;
uint32_t next_entity_id_ = 1000; uint32_t next_entity_id_ = 1000;
@ -123,8 +116,7 @@ private:
std::map<size_t, std::unique_ptr<System>> systems_{}; std::map<size_t, std::unique_ptr<System>> systems_{};
template <typename T> template <typename T>
ComponentArray<T>* GetComponentArray() ComponentArray<T>* GetComponentArray() {
{
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto it = component_arrays_.find(hash); auto it = component_arrays_.find(hash);
if (it == component_arrays_.end()) { if (it == component_arrays_.end()) {
@ -137,7 +129,6 @@ private:
} }
std::unique_ptr<EventSystem> event_system_{}; std::unique_ptr<EventSystem> event_system_{};
}; };
} // namespace engine } // namespace engine

View File

@ -4,16 +4,15 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "scene.hpp"
#include "resource_manager.hpp" #include "resource_manager.hpp"
#include "scene.hpp"
namespace engine { namespace engine {
class Application; class Application;
class SceneManager { class SceneManager {
public:
public:
SceneManager(Application* app); SceneManager(Application* app);
~SceneManager(); ~SceneManager();
SceneManager(const SceneManager&) = delete; SceneManager(const SceneManager&) = delete;
@ -24,12 +23,11 @@ public:
void UpdateActiveScene(float ts); void UpdateActiveScene(float ts);
private: private:
Application* const app_; Application* const app_;
std::vector<std::unique_ptr<Scene>> scenes_; std::vector<std::unique_ptr<Scene>> scenes_;
int active_scene_index_ = -1; int active_scene_index_ = -1;
}; };
} // namespace engine } // namespace engine

View File

@ -4,8 +4,8 @@
#include <array> #include <array>
#include <string> #include <string>
#include <glm/vec2.hpp>
#include <SDL.h> #include <SDL.h>
#include <glm/vec2.hpp>
#include "inputs/keyboard.hpp" #include "inputs/keyboard.hpp"
#include "inputs/mouse.hpp" #include "inputs/mouse.hpp"
@ -13,80 +13,79 @@
namespace engine { namespace engine {
class Window { class Window {
public:
public:
Window(const std::string& title, bool resizable = true, Window(const std::string& title, bool resizable = true,
bool fullscreen = true); bool fullscreen = true);
Window(const Window&) = delete; Window(const Window&) = delete;
Window& operator=(const Window&) = delete; Window& operator=(const Window&) = delete;
~Window(); ~Window();
SDL_Window* getHandle() const; SDL_Window* GetHandle() const;
// Return the title name // Return the title name
std::string getTitle() const; std::string GetTitle() const;
// Update the window state to capture any events that have occurred. // Update the window state to capture any events that have occurred.
// Run this on every frame. // Run this on every frame.
void getInputAndEvents(); void GetInputAndEvents();
void setTitle(std::string title); void SetTitle(std::string title);
// Hides the window (it will appear closed to the user). // Hides the window (it will appear closed to the user).
void hide(); void Hide();
// Shows the window again. // Shows the window again.
void show(); void Show();
// Raises the window above other windows and sets the input focus // Raises the window above other windows and sets the input focus
void focus(); void Focus();
// Returns true if the window has focus // Returns true if the window has focus
bool hasFocus() const; bool HasFocus() const;
// Sets the close flag, check this with shouldClose() // Sets the close flag, check this with shouldClose()
void setCloseFlag(); void SetCloseFlag();
// Returns true if the window should remain open // Returns true if the window should remain open
bool isRunning() const; bool IsRunning() const;
void setFullscreen(bool fullscreen, bool exclusive = false); void SetFullscreen(bool fullscreen, bool exclusive = false);
void toggleFullscreen(); void ToggleFullscreen();
bool isFullscreen() const; bool IsFullscreen() const;
// Relative mouse mode captures the cursor for FPS style use. // Relative mouse mode captures the cursor for FPS style use.
// Returns false if unsupported. // Returns false if unsupported.
bool setRelativeMouseMode(bool enabled); bool SetRelativeMouseMode(bool enabled);
// returns true if relative mouse mode is enabled // returns true if relative mouse mode is enabled
bool mouseCaptured(); bool MouseCaptured();
// window events // window events
// Returns true if the window was just resized during the previous frame // Returns true if the window was just resized during the previous frame
bool getWindowResized() const; bool GetWindowResized() const;
// Set the window resized flag (to recalculate aspect ratios and such) // Set the window resized flag (to recalculate aspect ratios and such)
void setResizedFlag(); void SetResizedFlag();
// keyboard events // keyboard events
// returns true if key is down // returns true if key is down
bool getKey(inputs::Key key) const; bool GetKey(inputs::Key key) const;
// returns true if key was just pressed // returns true if key was just pressed
bool getKeyPress(inputs::Key key) const; bool GetKeyPress(inputs::Key key) const;
// returns true if key was just released // returns true if key was just released
bool getKeyRelease(inputs::Key key) const; bool GetKeyRelease(inputs::Key key) const;
// mouse events // mouse events
// returns true if button is down // returns true if button is down
bool getButton(inputs::MouseButton button) const; bool GetButton(inputs::MouseButton button) const;
// returns true if button was just pressed // returns true if button was just pressed
bool getButtonPress(inputs::MouseButton button) const; bool GetButtonPress(inputs::MouseButton button) const;
// returns true if button was just released // returns true if button was just released
bool getButtonRelease(inputs::MouseButton button) const; bool GetButtonRelease(inputs::MouseButton button) const;
// retrieves x coordinate of the mouse // retrieves x coordinate of the mouse
int getMouseX() const; int GetMouseX() const;
// retrieves y coordinate of the mouse // retrieves y coordinate of the mouse
int getMouseY() const; int GetMouseY() const;
// retrieves mouse x coordinate normalised for OpenGL // retrieves mouse x coordinate normalised for OpenGL
float getMouseNormX() const; float getMouseNormX() const;
// retrieves mouse y coordinate normalised for OpenGL // retrieves mouse y coordinate normalised for OpenGL
@ -102,8 +101,6 @@ public:
// joystick/gamepad events (maybe), other misc events // joystick/gamepad events (maybe), other misc events
// returns the performance counter value in nanoseconds; // returns the performance counter value in nanoseconds;
uint64_t getNanos() const; uint64_t getNanos() const;
// get the time recorded at the end of the last frame // get the time recorded at the end of the last frame
@ -112,7 +109,7 @@ public:
// returns the number of frames elapsed since window creation // returns the number of frames elapsed since window creation
uint64_t getFrameCount() const; uint64_t getFrameCount() const;
uint64_t getStartTime() const; uint64_t getStartTime() const;
float dt() const; // returns delta time in seconds float dt() const; // returns delta time in seconds
uint64_t getFPS() const; uint64_t getFPS() const;
uint64_t getAvgFPS() const; uint64_t getAvgFPS() const;
@ -123,8 +120,7 @@ public:
/* STATIC METHODS */ /* STATIC METHODS */
static void errorBox(const std::string& message); static void errorBox(const std::string& message);
private: private:
SDL_Window* m_handle; SDL_Window* m_handle;
bool m_shouldClose = false; bool m_shouldClose = false;
@ -152,22 +148,18 @@ private:
// in nanoseconds // in nanoseconds
uint64_t m_lastFrameStamp; uint64_t m_lastFrameStamp;
// in nanoseconds; elapsed time between frames // in nanoseconds; elapsed time between frames
uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero
// in nanoseconds // in nanoseconds
uint64_t m_avgFpsStart; uint64_t m_avgFpsStart;
// input stuff // input stuff
enum class ButtonDelta { enum class ButtonDelta { SAME = 0, PRESSED, RELEASED };
SAME = 0,
PRESSED,
RELEASED
};
struct { struct {
std::array<bool, SDL_NUM_SCANCODES> keys; std::array<bool, SDL_NUM_SCANCODES> keys;
std::array<enum ButtonDelta, SDL_NUM_SCANCODES> deltas; std::array<enum ButtonDelta, SDL_NUM_SCANCODES> deltas;
} m_keyboard{ }; } m_keyboard{};
struct { struct {
std::array<bool, static_cast<int>(inputs::MouseButton::M_SIZE)> buttons; std::array<bool, static_cast<int>(inputs::MouseButton::M_SIZE)> buttons;
@ -179,7 +171,7 @@ private:
float xscroll; float xscroll;
float yscroll; float yscroll;
bool captured = false; bool captured = false;
} m_mouse{ }; } m_mouse{};
// private methods // private methods
@ -195,6 +187,6 @@ private:
void onMouseWheelEvent(SDL_MouseWheelEvent& e); void onMouseWheelEvent(SDL_MouseWheelEvent& e);
}; };
} } // namespace engine
#endif #endif