added: ECS -> Testing ECS With basics windows a stuff
This commit is contained in:
parent
9ed91cd672
commit
4d18863e97
21
src/Components.h
Normal file
21
src/Components.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Components.h
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <glm/glm.hpp> // Ensure you have GLM installed and linked
|
||||||
|
|
||||||
|
struct TransformComponent {
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 rotation;
|
||||||
|
glm::vec3 scale;
|
||||||
|
|
||||||
|
TransformComponent()
|
||||||
|
: position(0.0f), rotation(0.0f), scale(1.0f) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpriteComponent {
|
||||||
|
std::string texturePath;
|
||||||
|
// Add more sprite-related properties here
|
||||||
|
|
||||||
|
SpriteComponent(const std::string& path = "")
|
||||||
|
: texturePath(path) {}
|
||||||
|
};
|
204
src/ECS.h
Normal file
204
src/ECS.h
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
// ECS.h
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
class ComponentManager;
|
||||||
|
|
||||||
|
// Type alias for Entity
|
||||||
|
using Entity = uint32_t;
|
||||||
|
const Entity MAX_ENTITIES = 5000;
|
||||||
|
|
||||||
|
// Simple Vector3 struct to replace glm::vec3
|
||||||
|
struct Vector3 {
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
Vector3(float x_=0.0f, float y_=0.0f, float z_=0.0f)
|
||||||
|
: x(x_), y(y_), z(z_) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// Components
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
struct TransformComponent {
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 rotation;
|
||||||
|
Vector3 scale;
|
||||||
|
|
||||||
|
TransformComponent()
|
||||||
|
: position(0.0f, 0.0f, 0.0f),
|
||||||
|
rotation(0.0f, 0.0f, 0.0f),
|
||||||
|
scale(1.0f, 1.0f, 1.0f) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpriteComponent {
|
||||||
|
std::string texturePath;
|
||||||
|
// Add more sprite-related properties here
|
||||||
|
|
||||||
|
SpriteComponent(const std::string& path = "")
|
||||||
|
: texturePath(path) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// ECS Core Classes
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
// Base class for Component Arrays
|
||||||
|
class IComponentArray {
|
||||||
|
public:
|
||||||
|
virtual ~IComponentArray() = default;
|
||||||
|
virtual void EntityDestroyed(Entity entity) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Template class for storing components of type T
|
||||||
|
template<typename T>
|
||||||
|
class ComponentArray : public IComponentArray {
|
||||||
|
public:
|
||||||
|
void InsertData(Entity entity, T component) {
|
||||||
|
if (entityToIndex.find(entity) != entityToIndex.end())
|
||||||
|
return; // Component already exists for this entity
|
||||||
|
size_t newIndex = components.size();
|
||||||
|
entityToIndex[entity] = newIndex;
|
||||||
|
indexToEntity[newIndex] = entity;
|
||||||
|
components.emplace_back(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveData(Entity entity) {
|
||||||
|
auto it = entityToIndex.find(entity);
|
||||||
|
if (it == entityToIndex.end())
|
||||||
|
return; // Component does not exist
|
||||||
|
|
||||||
|
size_t index = it->second;
|
||||||
|
size_t lastIndex = components.size() - 1;
|
||||||
|
components[index] = components[lastIndex];
|
||||||
|
|
||||||
|
Entity lastEntity = indexToEntity[lastIndex];
|
||||||
|
entityToIndex[lastEntity] = index;
|
||||||
|
indexToEntity[index] = lastEntity;
|
||||||
|
|
||||||
|
components.pop_back();
|
||||||
|
entityToIndex.erase(entity);
|
||||||
|
indexToEntity.erase(lastIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasData(Entity entity) const {
|
||||||
|
return entityToIndex.find(entity) != entityToIndex.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
T& GetData(Entity entity) {
|
||||||
|
return components.at(entityToIndex.at(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityDestroyed(Entity entity) override {
|
||||||
|
if (entityToIndex.find(entity) != entityToIndex.end()) {
|
||||||
|
RemoveData(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<T> components;
|
||||||
|
std::unordered_map<Entity, size_t> entityToIndex;
|
||||||
|
std::unordered_map<size_t, Entity> indexToEntity;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ComponentManager handles all components
|
||||||
|
class ComponentManager {
|
||||||
|
public:
|
||||||
|
template<typename T>
|
||||||
|
void RegisterComponent() {
|
||||||
|
const std::type_index typeName = typeid(T);
|
||||||
|
if (componentArrays.find(typeName) != componentArrays.end()) {
|
||||||
|
// Component already registered
|
||||||
|
// Logger is not accessible here; handle logging in main.cpp
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
componentArrays[typeName] = std::make_shared<ComponentArray<T>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void AddComponent(Entity entity, T component) {
|
||||||
|
GetComponentArray<T>()->InsertData(entity, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void RemoveComponent(Entity entity) {
|
||||||
|
GetComponentArray<T>()->RemoveData(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool HasComponent(Entity entity) const {
|
||||||
|
return GetComponentArray<T>()->HasData(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T& GetComponent(Entity entity) {
|
||||||
|
return GetComponentArray<T>()->GetData(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityDestroyed(Entity entity) {
|
||||||
|
for (auto const& pair : componentArrays) {
|
||||||
|
auto const& component = pair.second;
|
||||||
|
component->EntityDestroyed(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::type_index, std::shared_ptr<IComponentArray>> componentArrays;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::shared_ptr<ComponentArray<T>> GetComponentArray() const {
|
||||||
|
const std::type_index typeName = typeid(T);
|
||||||
|
auto it = componentArrays.find(typeName);
|
||||||
|
if (it == componentArrays.end()) {
|
||||||
|
throw std::runtime_error("Component not registered.");
|
||||||
|
}
|
||||||
|
return std::static_pointer_cast<ComponentArray<T>>(it->second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// EntityManager handles entity creation and destruction
|
||||||
|
class EntityManager {
|
||||||
|
public:
|
||||||
|
EntityManager() : livingEntityCount(0) {}
|
||||||
|
|
||||||
|
void Init() {
|
||||||
|
for (Entity entity = 0; entity < MAX_ENTITIES; ++entity)
|
||||||
|
availableEntities.push_back(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity CreateEntity() {
|
||||||
|
if (livingEntityCount >= MAX_ENTITIES) {
|
||||||
|
throw std::runtime_error("Too many entities in existence.");
|
||||||
|
}
|
||||||
|
Entity id = availableEntities.back();
|
||||||
|
availableEntities.pop_back();
|
||||||
|
activeEntities.emplace_back(id);
|
||||||
|
++livingEntityCount;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyEntity(Entity entity, ComponentManager& cm) {
|
||||||
|
if (entity >= MAX_ENTITIES) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
availableEntities.push_back(entity);
|
||||||
|
activeEntities.erase(std::remove(activeEntities.begin(), activeEntities.end(), entity), activeEntities.end());
|
||||||
|
cm.EntityDestroyed(entity);
|
||||||
|
--livingEntityCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<Entity>& GetActiveEntities() const { return activeEntities; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Entity> availableEntities{};
|
||||||
|
std::vector<Entity> activeEntities{};
|
||||||
|
uint32_t livingEntityCount;
|
||||||
|
};
|
375
src/main.cpp
375
src/main.cpp
@ -7,21 +7,17 @@
|
|||||||
#include "imgui_impl_opengl3.h"
|
#include "imgui_impl_opengl3.h"
|
||||||
#include "../IconsFontAwesome6.h" // Include the Font Awesome icons header
|
#include "../IconsFontAwesome6.h" // Include the Font Awesome icons header
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define DEBUG 1
|
#include "ECS.h" // Include the ECS header
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define LOGPOINT(msg) std::cout << "[TESRCT] [" << __func__ << ":" << __LINE__ << "] " << (msg) << std::endl;
|
|
||||||
#else
|
|
||||||
#define LOGPOINT(msg)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// =====================
|
||||||
// Logger Implementation
|
// Logger Implementation
|
||||||
|
// =====================
|
||||||
|
|
||||||
enum class LogLevel { INFO, WARNING, ERROR };
|
enum class LogLevel { INFO, WARNING, ERROR };
|
||||||
|
|
||||||
struct LogEntry {
|
struct LogEntry {
|
||||||
@ -54,19 +50,44 @@ private:
|
|||||||
size_t max_entries;
|
size_t max_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define LOGPOINT(msg) std::cout << "[TESRCT] [" << __func__ << ":" << __LINE__ << "] " << (msg) << std::endl;
|
||||||
|
#else
|
||||||
|
#define LOGPOINT(msg)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// ECS Instances
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
EntityManager entityManager;
|
||||||
|
ComponentManager componentManager;
|
||||||
|
|
||||||
|
// =====================
|
||||||
// Function Declarations
|
// Function Declarations
|
||||||
|
// =====================
|
||||||
|
|
||||||
void ShowMainMenuBar();
|
void ShowMainMenuBar();
|
||||||
void ShowViewport();
|
void ShowViewport();
|
||||||
void ShowConsole(bool* p_open);
|
void ShowConsole(bool* p_open);
|
||||||
|
void ShowEntityTree(EntityManager& em, ComponentManager& cm, Entity& selectedEntity);
|
||||||
|
void ShowInspector(EntityManager& em, ComponentManager& cm, Entity selectedEntity);
|
||||||
|
|
||||||
|
// =====================
|
||||||
// Callback for GLFW errors
|
// Callback for GLFW errors
|
||||||
|
// =====================
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description)
|
static void glfw_error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
// Helper function to get color based on log level
|
// Helper function to get color based on log level
|
||||||
|
// =====================
|
||||||
|
|
||||||
ImVec4 GetColorForLogLevel(LogLevel level)
|
ImVec4 GetColorForLogLevel(LogLevel level)
|
||||||
{
|
{
|
||||||
switch (level)
|
switch (level)
|
||||||
@ -82,6 +103,224 @@ ImVec4 GetColorForLogLevel(LogLevel level)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// UI Function Definitions
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
// 1. Main Menu Bar
|
||||||
|
void ShowMainMenuBar()
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMainMenuBar())
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("File"))
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("New", "Ctrl+N")) { /* Handle New */ }
|
||||||
|
if (ImGui::MenuItem("Open", "Ctrl+O")) { /* Handle Open */ }
|
||||||
|
if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Handle Save */ }
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("Exit")) { /* Handle Exit */ }
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginMenu("Edit"))
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Undo", "Ctrl+Z")) { /* Handle Undo */ }
|
||||||
|
if (ImGui::MenuItem("Redo", "Ctrl+Y")) { /* Handle Redo */ }
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::MenuItem("Copy", "Ctrl+C")) { /* Handle Copy */ }
|
||||||
|
if (ImGui::MenuItem("Paste", "Ctrl+V")) { /* Handle Paste */ }
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginMenu("View"))
|
||||||
|
{
|
||||||
|
static bool show_console = true;
|
||||||
|
if (ImGui::MenuItem("Show Console", NULL, &show_console)) { /* Toggle Console */ }
|
||||||
|
// Add more view toggles as needed
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndMainMenuBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Viewport Panel
|
||||||
|
void ShowViewport()
|
||||||
|
{
|
||||||
|
ImGui::Begin("Viewport", NULL, ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
// Get the size of the viewport
|
||||||
|
ImVec2 viewport_size = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
|
// For demonstration, we'll render a colored rectangle
|
||||||
|
// In a real engine, you'd render your scene here
|
||||||
|
|
||||||
|
// Calculate the position relative to window
|
||||||
|
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||||
|
|
||||||
|
// Define rectangle dimensions
|
||||||
|
ImVec2 rect_min = pos;
|
||||||
|
ImVec2 rect_max = ImVec2(pos.x + viewport_size.x, pos.y + viewport_size.y);
|
||||||
|
|
||||||
|
// Render a colored rectangle
|
||||||
|
ImGui::GetWindowDrawList()->AddRectFilled(rect_min, rect_max, IM_COL32(100, 100, 200, 255));
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Console Panel
|
||||||
|
void ShowConsole(bool* p_open)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Console", p_open, ImGuiWindowFlags_NoCollapse);
|
||||||
|
|
||||||
|
// Options menu
|
||||||
|
if (ImGui::BeginPopupContextWindow())
|
||||||
|
{
|
||||||
|
if (ImGui::MenuItem("Clear")) {
|
||||||
|
Logger::GetInstance().Clear();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve enough left-over height for 1 separator and 1 input text
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Begin child region for scrolling
|
||||||
|
ImGui::BeginChild("ConsoleChild", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||||
|
|
||||||
|
// Iterate through log entries
|
||||||
|
for (const auto& entry : Logger::GetInstance().GetEntries())
|
||||||
|
{
|
||||||
|
ImVec4 color = GetColorForLogLevel(entry.level);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||||
|
ImGui::TextUnformatted(entry.message.c_str());
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-scroll to the bottom
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Entity Tree
|
||||||
|
void ShowEntityTree(EntityManager& em, ComponentManager& cm, Entity& selectedEntity)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Entities");
|
||||||
|
|
||||||
|
// Button to create a new entity
|
||||||
|
if (ImGui::Button("Add Entity")) {
|
||||||
|
try {
|
||||||
|
Entity newEntity = em.CreateEntity();
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Created Entity " + std::to_string(newEntity));
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
Logger::GetInstance().Log(LogLevel::ERROR, e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Iterate through active entities
|
||||||
|
const auto& entities = em.GetActiveEntities();
|
||||||
|
for (auto entity : entities) {
|
||||||
|
char label[32];
|
||||||
|
sprintf(label, "Entity %d", entity);
|
||||||
|
if (ImGui::Selectable(label, selectedEntity == entity)) {
|
||||||
|
selectedEntity = entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option to destroy the selected entity
|
||||||
|
if (selectedEntity != UINT32_MAX) {
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::Button("Delete Entity")) {
|
||||||
|
em.DestroyEntity(selectedEntity, cm);
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Destroyed Entity " + std::to_string(selectedEntity));
|
||||||
|
selectedEntity = UINT32_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Inspector Panel
|
||||||
|
void ShowInspector(EntityManager& em, ComponentManager& cm, Entity selectedEntity)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Inspector");
|
||||||
|
|
||||||
|
if (selectedEntity == UINT32_MAX) {
|
||||||
|
ImGui::Text("No entity selected.");
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char label[32];
|
||||||
|
sprintf(label, "Entity %d", selectedEntity);
|
||||||
|
ImGui::Text("%s", label);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// Display Transform Component
|
||||||
|
if (cm.HasComponent<TransformComponent>(selectedEntity)) {
|
||||||
|
if (ImGui::TreeNode("Transform")) {
|
||||||
|
auto& transform = cm.GetComponent<TransformComponent>(selectedEntity);
|
||||||
|
ImGui::DragFloat3("Position", &transform.position.x, 0.1f);
|
||||||
|
ImGui::DragFloat3("Rotation", &transform.rotation.x, 0.1f);
|
||||||
|
ImGui::DragFloat3("Scale", &transform.scale.x, 0.1f);
|
||||||
|
|
||||||
|
if (ImGui::Button("Remove Transform")) {
|
||||||
|
cm.RemoveComponent<TransformComponent>(selectedEntity);
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Removed TransformComponent from Entity " + std::to_string(selectedEntity));
|
||||||
|
ImGui::TreePop();
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ImGui::Button("Add Transform")) {
|
||||||
|
cm.AddComponent<TransformComponent>(selectedEntity, TransformComponent());
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Added TransformComponent to Entity " + std::to_string(selectedEntity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display Sprite Component
|
||||||
|
if (cm.HasComponent<SpriteComponent>(selectedEntity)) {
|
||||||
|
if (ImGui::TreeNode("Sprite")) {
|
||||||
|
auto& sprite = cm.GetComponent<SpriteComponent>(selectedEntity);
|
||||||
|
char buffer[256];
|
||||||
|
strncpy(buffer, sprite.texturePath.c_str(), sizeof(buffer));
|
||||||
|
buffer[sizeof(buffer) - 1] = '\0'; // Ensure null-termination
|
||||||
|
if (ImGui::InputText("Texture Path", buffer, sizeof(buffer))) {
|
||||||
|
sprite.texturePath = std::string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Remove Sprite")) {
|
||||||
|
cm.RemoveComponent<SpriteComponent>(selectedEntity);
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Removed SpriteComponent from Entity " + std::to_string(selectedEntity));
|
||||||
|
ImGui::TreePop();
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ImGui::Button("Add Sprite")) {
|
||||||
|
cm.AddComponent<SpriteComponent>(selectedEntity, SpriteComponent("path/to/texture.png"));
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Added SpriteComponent to Entity " + std::to_string(selectedEntity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// Main Function
|
||||||
|
// =====================
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
LOGPOINT("Loading Engine");
|
LOGPOINT("Loading Engine");
|
||||||
@ -106,8 +345,6 @@ int main(int, char**)
|
|||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSwapInterval(1); // Enable vsync
|
glfwSwapInterval(1); // Enable vsync
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Setup Dear ImGui context
|
// Setup Dear ImGui context
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
@ -166,15 +403,23 @@ int main(int, char**)
|
|||||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||||
|
|
||||||
// Example log messages
|
// Initialize ECS
|
||||||
//Logger::GetInstance().Log(LogLevel::INFO, "Engine initialized successfully.");
|
entityManager.Init();
|
||||||
//Logger::GetInstance().Log(LogLevel::WARNING, "This is a warning message.");
|
componentManager.RegisterComponent<TransformComponent>();
|
||||||
//Logger::GetInstance().Log(LogLevel::ERROR, "This is an error message.");
|
componentManager.RegisterComponent<SpriteComponent>();
|
||||||
Logger::GetInstance().Log(LogLevel::INFO, "Done!");
|
|
||||||
|
// Create a default entity with TransformComponent
|
||||||
|
Entity defaultEntity = entityManager.CreateEntity();
|
||||||
|
componentManager.AddComponent<TransformComponent>(defaultEntity, TransformComponent());
|
||||||
|
|
||||||
|
Logger::GetInstance().Log(LogLevel::INFO, "Engine initialized successfully.");
|
||||||
|
|
||||||
// Variables for Console
|
// Variables for Console
|
||||||
bool show_console = true;
|
bool show_console = true;
|
||||||
|
|
||||||
|
// Variable to track the selected entity
|
||||||
|
Entity selectedEntity = defaultEntity;
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (!glfwWindowShouldClose(window))
|
while (!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
@ -213,6 +458,10 @@ int main(int, char**)
|
|||||||
ShowViewport();
|
ShowViewport();
|
||||||
ShowConsole(&show_console);
|
ShowConsole(&show_console);
|
||||||
|
|
||||||
|
// Show ECS UI panels
|
||||||
|
ShowEntityTree(entityManager, componentManager, selectedEntity);
|
||||||
|
ShowInspector(entityManager, componentManager, selectedEntity);
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
int display_w, display_h;
|
int display_w, display_h;
|
||||||
@ -246,99 +495,3 @@ int main(int, char**)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function Definitions
|
|
||||||
|
|
||||||
// 1. Main Menu Bar
|
|
||||||
void ShowMainMenuBar()
|
|
||||||
{
|
|
||||||
if (ImGui::BeginMainMenuBar())
|
|
||||||
{
|
|
||||||
if (ImGui::BeginMenu("File"))
|
|
||||||
{
|
|
||||||
if (ImGui::MenuItem("New", "Ctrl+N")) { /* Handle New */ }
|
|
||||||
if (ImGui::MenuItem("Open", "Ctrl+O")) { /* Handle Open */ }
|
|
||||||
if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Handle Save */ }
|
|
||||||
ImGui::Separator();
|
|
||||||
if (ImGui::MenuItem("Exit")) { /* Handle Exit */ }
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if (ImGui::BeginMenu("Edit"))
|
|
||||||
{
|
|
||||||
if (ImGui::MenuItem("Undo", "Ctrl+Z")) { /* Handle Undo */ }
|
|
||||||
if (ImGui::MenuItem("Redo", "Ctrl+Y")) { /* Handle Redo */ }
|
|
||||||
ImGui::Separator();
|
|
||||||
if (ImGui::MenuItem("Copy", "Ctrl+C")) { /* Handle Copy */ }
|
|
||||||
if (ImGui::MenuItem("Paste", "Ctrl+V")) { /* Handle Paste */ }
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if (ImGui::BeginMenu("View"))
|
|
||||||
{
|
|
||||||
if (ImGui::MenuItem("Show Console", NULL, true)) { /* Toggle Console */ }
|
|
||||||
if (ImGui::MenuItem("Toggle Viewport")) { /* Toggle Viewport */ }
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Viewport Panel
|
|
||||||
void ShowViewport()
|
|
||||||
{
|
|
||||||
ImGui::Begin("Viewport", NULL, ImGuiWindowFlags_NoCollapse);
|
|
||||||
|
|
||||||
// Get the size of the viewport
|
|
||||||
ImVec2 viewport_size = ImGui::GetContentRegionAvail();
|
|
||||||
|
|
||||||
// For demonstration, we'll render a colored rectangle
|
|
||||||
// In a real engine, you'd render your scene here
|
|
||||||
|
|
||||||
// Calculate the center position
|
|
||||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
|
||||||
|
|
||||||
// Define rectangle dimensions
|
|
||||||
ImVec2 rect_min = pos;
|
|
||||||
ImVec2 rect_max = ImVec2(pos.x + viewport_size.x, pos.y + viewport_size.y);
|
|
||||||
|
|
||||||
// Render a colored rectangle
|
|
||||||
ImGui::GetWindowDrawList()->AddRectFilled(rect_min, rect_max, IM_COL32(100, 100, 200, 255));
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Console Panel
|
|
||||||
void ShowConsole(bool* p_open)
|
|
||||||
{
|
|
||||||
ImGui::Begin("Console", p_open, ImGuiWindowFlags_NoCollapse);
|
|
||||||
|
|
||||||
// Options menu
|
|
||||||
if (ImGui::BeginPopupContextWindow())
|
|
||||||
{
|
|
||||||
if (ImGui::MenuItem("Clear")) {
|
|
||||||
Logger::GetInstance().Clear();
|
|
||||||
}
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reserve enough left-over height for 1 separator and 1 input text
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
// Begin child region for scrolling
|
|
||||||
ImGui::BeginChild("ConsoleChild", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
|
||||||
|
|
||||||
// Iterate through log entries
|
|
||||||
for (const auto& entry : Logger::GetInstance().GetEntries())
|
|
||||||
{
|
|
||||||
ImVec4 color = GetColorForLogLevel(entry.level);
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
|
||||||
ImGui::TextUnformatted(entry.message.c_str());
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-scroll to the bottom
|
|
||||||
ImGui::SetScrollHereY(1.0f);
|
|
||||||
|
|
||||||
ImGui::EndChild();
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user