Initial Commit
This commit is contained in:
commit
edea0b2f9b
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# IDE Files
|
||||||
|
.vscode/
|
||||||
|
.jb/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Build directories
|
||||||
|
build/
|
||||||
|
build-vs/
|
||||||
|
build-debug/
|
||||||
|
build-release/
|
||||||
|
build-minsizerel/
|
||||||
|
cmake-build-debug/
|
||||||
|
|
||||||
|
# Tooling files
|
||||||
|
output.txt
|
||||||
|
buildall.bat
|
||||||
|
typer.py
|
231
CMakeLists.txt
Normal file
231
CMakeLists.txt
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.24)
|
||||||
|
|
||||||
|
project(IsoEngine LANGUAGES CXX)
|
||||||
|
|
||||||
|
# Options for shared/static libraries, testbeds, and sandbox
|
||||||
|
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs) instead of static libraries" OFF)
|
||||||
|
option(BUILD_CLIENT "Build the client testbed executable" ON)
|
||||||
|
option(BUILD_SANDBOX "Build sandbox client and server" ON)
|
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
message(STATUS "No build type specified, defaulting to Debug")
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_XCODE_GENERATE_SCHEME ON)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# Output directory settings
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
|
if(POLICY CMP0077)
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(FETCHCONTENT_QUIET OFF)
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
# ENet is header-only, provide include directory
|
||||||
|
set(ENET_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/thirdparty/enet")
|
||||||
|
|
||||||
|
# Fetch Raylib and other dependencies
|
||||||
|
FetchContent_Declare(
|
||||||
|
raylib
|
||||||
|
URL https://github.com/raysan5/raylib/archive/refs/tags/5.0.zip
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(raylib)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
imgui
|
||||||
|
GIT_REPOSITORY https://github.com/ocornut/imgui.git
|
||||||
|
GIT_TAG v1.91.1
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(imgui)
|
||||||
|
|
||||||
|
add_library(ImGui ${imgui_SOURCE_DIR}/imgui.cpp
|
||||||
|
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||||
|
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||||
|
${imgui_SOURCE_DIR}/imgui_tables.cpp
|
||||||
|
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(ImGui PUBLIC ${imgui_SOURCE_DIR})
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
rlimgui
|
||||||
|
GIT_REPOSITORY https://github.com/raylib-extras/rlImGui.git
|
||||||
|
GIT_TAG main
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(rlimgui)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
box2d
|
||||||
|
GIT_REPOSITORY https://github.com/erincatto/box2d.git
|
||||||
|
GIT_TAG v3.0.0
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(box2d)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
entt
|
||||||
|
GIT_REPOSITORY https://github.com/skypjack/entt.git
|
||||||
|
GIT_TAG v3.13.2
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(entt)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
physfs
|
||||||
|
GIT_REPOSITORY https://github.com/icculus/physfs.git
|
||||||
|
GIT_TAG release-3.2.0
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(physfs)
|
||||||
|
|
||||||
|
# PhysFS settings
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
set(PHYSFS_BUILD_SHARED ON CACHE BOOL "Build PhysFS shared library" FORCE)
|
||||||
|
set(PHYSFS_BUILD_STATIC OFF CACHE BOOL "Do not build PhysFS static library" FORCE)
|
||||||
|
else()
|
||||||
|
set(PHYSFS_BUILD_STATIC ON CACHE BOOL "Build PhysFS static library" FORCE)
|
||||||
|
set(PHYSFS_BUILD_SHARED OFF CACHE BOOL "Do not build PhysFS shared library" FORCE)
|
||||||
|
endif()
|
||||||
|
set(PHYSFS_BUILD_TEST OFF CACHE BOOL "Disable PhysFS test program" FORCE)
|
||||||
|
|
||||||
|
# Main Engine Library
|
||||||
|
set(ENGINE_SOURCES
|
||||||
|
src/IsoEngine.cpp
|
||||||
|
src/enet_client.cpp
|
||||||
|
src/enet_server.cpp
|
||||||
|
|
||||||
|
src/components/sprite_component.cpp
|
||||||
|
src/Logger.cpp
|
||||||
|
src/Logger.h
|
||||||
|
src/components/transform_component.h
|
||||||
|
src/components/physics_component.cpp
|
||||||
|
src/components/physics_component.h
|
||||||
|
src/components/input_component.cpp
|
||||||
|
src/components/input_component.h
|
||||||
|
src/components/health_component.h
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(IsoEngine ${ENGINE_SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(IsoEngine PUBLIC
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/src/components
|
||||||
|
${raylib_SOURCE_DIR}
|
||||||
|
${imgui_SOURCE_DIR}
|
||||||
|
${rlimgui_SOURCE_DIR}
|
||||||
|
${box2d_SOURCE_DIR}/include
|
||||||
|
${physfs_SOURCE_DIR}/src
|
||||||
|
${entt_SOURCE_DIR}/src
|
||||||
|
${ENET_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(IsoEngine PRIVATE raylib box2d EnTT::EnTT)
|
||||||
|
|
||||||
|
# PhysFS linkage
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
target_link_libraries(IsoEngine PRIVATE PhysFS::PhysFS)
|
||||||
|
else()
|
||||||
|
target_link_libraries(IsoEngine PRIVATE PhysFS::PhysFS-static)
|
||||||
|
target_compile_definitions(IsoEngine PRIVATE PHYSFS_STATIC)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# rlImGui library linking
|
||||||
|
add_library(rlImGui ${rlimgui_SOURCE_DIR}/rlImGui.cpp)
|
||||||
|
target_include_directories(rlImGui PUBLIC ${rlimgui_SOURCE_DIR} ${imgui_SOURCE_DIR})
|
||||||
|
target_link_libraries(rlImGui PRIVATE raylib ImGui)
|
||||||
|
target_link_libraries(IsoEngine PRIVATE ImGui rlImGui)
|
||||||
|
|
||||||
|
# Testbed and Sandbox executables (client/server)
|
||||||
|
if(BUILD_CLIENT OR BUILD_SANDBOX)
|
||||||
|
# Client executable
|
||||||
|
set(CLIENT_SOURCE "${CMAKE_CURRENT_LIST_DIR}/sandbox/client.cpp")
|
||||||
|
add_executable(client ${CLIENT_SOURCE})
|
||||||
|
target_include_directories(client PRIVATE ${ENET_INCLUDE_DIR})
|
||||||
|
target_link_libraries(client PRIVATE IsoEngine raylib)
|
||||||
|
|
||||||
|
# Platform-specific linking for client (Windows)
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(client PRIVATE winmm ws2_32)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Server executable
|
||||||
|
set(SERVER_SOURCE "${CMAKE_CURRENT_LIST_DIR}/sandbox/server.cpp")
|
||||||
|
add_executable(server ${SERVER_SOURCE})
|
||||||
|
target_include_directories(server PRIVATE ${ENET_INCLUDE_DIR})
|
||||||
|
target_link_libraries(server PRIVATE IsoEngine)
|
||||||
|
|
||||||
|
# Platform-specific linking for server (Windows)
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(server PRIVATE winmm ws2_32)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Platform-specific linking for IsoEngine (Raylib and Winsock for ENet on Windows)
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(IsoEngine PRIVATE winmm ws2_32)
|
||||||
|
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||||
|
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS)
|
||||||
|
add_definitions(-D_HAS_EXCEPTIONS=0)
|
||||||
|
elseif(APPLE)
|
||||||
|
target_link_libraries(IsoEngine PRIVATE "-framework CoreVideo" "-framework IOKit" "-framework Cocoa" "-framework GLUT" "-framework OpenGL")
|
||||||
|
else()
|
||||||
|
target_link_libraries(IsoEngine PRIVATE m pthread GL dl X11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build Configuration Optimizations
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message(STATUS "Configuring Debug build: No optimizations applied.")
|
||||||
|
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
message(STATUS "Configuring Release build: Applying moderate optimizations.")
|
||||||
|
target_compile_options(IsoEngine PRIVATE -O2)
|
||||||
|
if(BUILD_CLIENT OR BUILD_SANDBOX)
|
||||||
|
target_compile_options(client PRIVATE -O2)
|
||||||
|
target_compile_options(server PRIVATE -O2)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Strip symbols after building
|
||||||
|
if(NOT MSVC)
|
||||||
|
add_custom_command(TARGET IsoEngine POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-unneeded $<TARGET_FILE:IsoEngine>
|
||||||
|
COMMENT "Stripping unneeded symbols from the IsoEngine binary in Release build."
|
||||||
|
)
|
||||||
|
if(BUILD_CLIENT OR BUILD_SANDBOX)
|
||||||
|
add_custom_command(TARGET client POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-unneeded $<TARGET_FILE:client>
|
||||||
|
COMMENT "Stripping unneeded symbols from the client binary in Release build."
|
||||||
|
)
|
||||||
|
add_custom_command(TARGET server POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-unneeded $<TARGET_FILE:server>
|
||||||
|
COMMENT "Stripping unneeded symbols from the server binary in Release build."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
|
||||||
|
message(STATUS "Configuring MinSizeRel build: Applying aggressive size optimizations.")
|
||||||
|
target_compile_options(IsoEngine PRIVATE -Os -ffunction-sections -fdata-sections)
|
||||||
|
target_link_options(IsoEngine PRIVATE -Wl,--gc-sections -Wl,--as-needed)
|
||||||
|
|
||||||
|
# Strip symbols aggressively after building
|
||||||
|
if(NOT MSVC)
|
||||||
|
add_custom_command(TARGET IsoEngine POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:IsoEngine>
|
||||||
|
COMMENT "Stripping all symbols from the IsoEngine binary in MinSizeRel build."
|
||||||
|
)
|
||||||
|
if(BUILD_CLIENT OR BUILD_SANDBOX)
|
||||||
|
add_custom_command(TARGET client POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:client>
|
||||||
|
COMMENT "Stripping all symbols from the client binary in MinSizeRel build."
|
||||||
|
)
|
||||||
|
add_custom_command(TARGET server POST_BUILD
|
||||||
|
COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:server>
|
||||||
|
COMMENT "Stripping all symbols from the server binary in MinSizeRel build."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
2
README.md
Normal file
2
README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Iso Engine
|
||||||
|
Smol little game engine since I have no idea what I'm doing
|
45
sandbox/client.cpp
Normal file
45
sandbox/client.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "IsoEngine.h"
|
||||||
|
#include "components/transform_component.h"
|
||||||
|
#include "components/input_component.h"
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
IsoEngine engine(800, 600, nullptr);
|
||||||
|
engine.Initialize();
|
||||||
|
|
||||||
|
SceneManager& sceneManager = engine.GetSceneManager();
|
||||||
|
entt::entity gameScene = sceneManager.CreateScene();
|
||||||
|
sceneManager.SetActiveScene(gameScene);
|
||||||
|
|
||||||
|
entt::entity player = engine.GetRegistry().create();
|
||||||
|
engine.GetRegistry().emplace<TransformComponent>(player, 400.0f, 300.0f, 1.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
auto& inputComponent = engine.GetRegistry().emplace<InputComponent>(player);
|
||||||
|
|
||||||
|
inputComponent.BindKey(InputAction::MOVE_UP, KEY_W);
|
||||||
|
inputComponent.BindKey(InputAction::MOVE_DOWN, KEY_S);
|
||||||
|
inputComponent.BindKey(InputAction::MOVE_LEFT, KEY_A);
|
||||||
|
inputComponent.BindKey(InputAction::MOVE_RIGHT, KEY_D);
|
||||||
|
|
||||||
|
inputComponent.SetActionCallback(InputAction::MOVE_UP, [&]() {
|
||||||
|
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
transform.y -= 5.0f;
|
||||||
|
});
|
||||||
|
inputComponent.SetActionCallback(InputAction::MOVE_DOWN, [&]() {
|
||||||
|
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
transform.y += 5.0f;
|
||||||
|
});
|
||||||
|
inputComponent.SetActionCallback(InputAction::MOVE_LEFT, [&]() {
|
||||||
|
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
transform.x -= 5.0f;
|
||||||
|
});
|
||||||
|
inputComponent.SetActionCallback(InputAction::MOVE_RIGHT, [&]() {
|
||||||
|
auto& transform = engine.GetRegistry().get<TransformComponent>(player);
|
||||||
|
transform.x += 5.0f;
|
||||||
|
});
|
||||||
|
|
||||||
|
engine.Run();
|
||||||
|
|
||||||
|
engine.Shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
4
sandbox/server.cpp
Normal file
4
sandbox/server.cpp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
61
src/IsoEngine.cpp
Normal file
61
src/IsoEngine.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include "IsoEngine.h"
|
||||||
|
#include "components.h"
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
IsoEngine::IsoEngine(int screenWidth, int screenHeight, Network* network)
|
||||||
|
: screenWidth(screenWidth), screenHeight(screenHeight), network(network), sceneManager(registry) {}
|
||||||
|
|
||||||
|
IsoEngine::~IsoEngine() {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsoEngine::Initialize() {
|
||||||
|
InitWindow(screenWidth, screenHeight, "IsoEngine Game");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
|
||||||
|
if (network) {
|
||||||
|
network->Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Engine initialized." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsoEngine::Run() {
|
||||||
|
while (isRunning && !WindowShouldClose()) {
|
||||||
|
Update();
|
||||||
|
Render();
|
||||||
|
|
||||||
|
if (network) {
|
||||||
|
network->ReceiveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsoEngine::Shutdown() {
|
||||||
|
sceneManager.RenderActiveScene();
|
||||||
|
CloseWindow();
|
||||||
|
|
||||||
|
if (network) {
|
||||||
|
network->Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Engine shut down." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsoEngine::Update() {
|
||||||
|
if (IsKeyPressed(KEY_ESCAPE)) {
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sceneManager.UpdateActiveScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IsoEngine::Render() {
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
sceneManager.RenderActiveScene();
|
||||||
|
|
||||||
|
DrawText("IsoEngine Running!", 10, 10, 20, DARKGRAY);
|
||||||
|
EndDrawing();
|
||||||
|
}
|
31
src/IsoEngine.h
Normal file
31
src/IsoEngine.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include "network.h"
|
||||||
|
#include "scene_manager.h"
|
||||||
|
|
||||||
|
class IsoEngine {
|
||||||
|
public:
|
||||||
|
IsoEngine(int screenWidth, int screenHeight, Network* network);
|
||||||
|
~IsoEngine();
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
void Run();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
SceneManager& GetSceneManager() { return sceneManager; }
|
||||||
|
|
||||||
|
entt::registry& GetRegistry() { return registry; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Update();
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
bool isRunning = true;
|
||||||
|
int screenWidth;
|
||||||
|
int screenHeight;
|
||||||
|
Network* network;
|
||||||
|
entt::registry registry;
|
||||||
|
SceneManager sceneManager;
|
||||||
|
};
|
109
src/Logger.cpp
Normal file
109
src/Logger.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
void Logger::Initialize(const std::string &logFile, LogLevel consoleLevel, LogLevel fileLevel) {
|
||||||
|
logFileName = logFile;
|
||||||
|
consoleLogLevel = consoleLevel;
|
||||||
|
fileLogLevel = fileLevel;
|
||||||
|
if (!logFile.empty()) {
|
||||||
|
logFileStream.open(logFile, std::ios::out | std::ios::app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::~Logger() {
|
||||||
|
if (logFileStream.is_open()) {
|
||||||
|
logFileStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Log(LogLevel level, const std::string& message, const std::string& scope) {
|
||||||
|
std::lock_guard<std::mutex> lock(logMutex);
|
||||||
|
|
||||||
|
std::string formattedMessage = FormatMessage(level, message, scope);
|
||||||
|
|
||||||
|
memoryLogs.push_back(formattedMessage);
|
||||||
|
if (memoryLogs.size() > memoryLogSize) {
|
||||||
|
memoryLogs.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShouldLogToConsole(level)) {
|
||||||
|
std::cout << formattedMessage << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShouldLogToFile(level)) {
|
||||||
|
if (logFileStream.is_open()) {
|
||||||
|
logFileStream << formattedMessage << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogInfo(const std::string& message, const std::string& scope) {
|
||||||
|
Log(LogLevel::INFO, message, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogDebug(const std::string& message, const std::string& scope) {
|
||||||
|
Log(LogLevel::DEBUG, message, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogWarning(const std::string& message, const std::string& scope) {
|
||||||
|
Log(LogLevel::WARNING, message, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogError(const std::string& message, const std::string& scope) {
|
||||||
|
Log(LogLevel::ERROR, message, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogCritical(const std::string& message, const std::string& scope) {
|
||||||
|
Log(LogLevel::CRITICAL, message, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::DumpLogs(const std::string& dumpFileName) {
|
||||||
|
std::lock_guard<std::mutex> lock(logMutex);
|
||||||
|
|
||||||
|
std::ofstream dumpFile(dumpFileName, std::ios::out | std::ios::app);
|
||||||
|
if (!dumpFile.is_open()) {
|
||||||
|
std::cerr << "Failed to open dump file: " << dumpFileName << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpFile << "---- Log Dump ----" << std::endl;
|
||||||
|
dumpFile << "Timestamp: " << GetTimestamp() << std::endl;
|
||||||
|
dumpFile << "------------------" << std::endl;
|
||||||
|
|
||||||
|
for (const std::string& log : memoryLogs) {
|
||||||
|
dumpFile << log << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Logger::FormatMessage(LogLevel level, const std::string& message, const std::string& scope) {
|
||||||
|
std::string levelStr = LogLevelToString(level);
|
||||||
|
std::string timestamp = GetTimestamp();
|
||||||
|
return timestamp + " [" + levelStr + "] [" + scope + "] " + message;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Logger::GetTimestamp() {
|
||||||
|
std::time_t now = std::time(nullptr);
|
||||||
|
char buf[20];
|
||||||
|
std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Logger::LogLevelToString(LogLevel level) {
|
||||||
|
switch (level) {
|
||||||
|
case LogLevel::DEBUG: return "DEBUG";
|
||||||
|
case LogLevel::INFO: return "INFO";
|
||||||
|
case LogLevel::WARNING: return "WARNING";
|
||||||
|
case LogLevel::ERROR: return "ERROR";
|
||||||
|
case LogLevel::CRITICAL: return "CRITICAL";
|
||||||
|
default: return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logger::ShouldLogToConsole(LogLevel level) {
|
||||||
|
return level >= consoleLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logger::ShouldLogToFile(LogLevel level) {
|
||||||
|
return level >= fileLogLevel && !logFileName.empty();
|
||||||
|
}
|
56
src/Logger.h
Normal file
56
src/Logger.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <ctime>
|
||||||
|
#include <deque>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
enum class LogLevel {
|
||||||
|
DEBUG = 0,
|
||||||
|
INFO = 10,
|
||||||
|
WARNING = 20,
|
||||||
|
ERROR = 30,
|
||||||
|
CRITICAL = 40
|
||||||
|
};
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
static Logger& GetInstance() {
|
||||||
|
static Logger instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger(const Logger&) = delete;
|
||||||
|
Logger& operator=(const Logger&) = delete;
|
||||||
|
|
||||||
|
void Initialize(const std::string &logFile = "", LogLevel consoleLevel = LogLevel::DEBUG, LogLevel fileLevel = LogLevel::DEBUG);
|
||||||
|
void Log(LogLevel level, const std::string &message, const std::string &scope = "");
|
||||||
|
void LogDebug(const std::string& message, const std::string& scope = "");
|
||||||
|
void LogInfo(const std::string& message, const std::string& scope = "");
|
||||||
|
void LogWarning(const std::string& message, const std::string& scope = "");
|
||||||
|
void LogError(const std::string& message, const std::string& scope = "");
|
||||||
|
void LogCritical(const std::string& message, const std::string& scope = "");
|
||||||
|
|
||||||
|
void DumpLogs(const std::string& dumpFileName = "crash_dump.log");
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger() = default;
|
||||||
|
~Logger();
|
||||||
|
|
||||||
|
std::ofstream logFileStream;
|
||||||
|
std::string logFileName;
|
||||||
|
LogLevel consoleLogLevel;
|
||||||
|
LogLevel fileLogLevel;
|
||||||
|
std::mutex logMutex;
|
||||||
|
|
||||||
|
std::deque<std::string> memoryLogs;
|
||||||
|
size_t memoryLogSize = 100;
|
||||||
|
|
||||||
|
std::string FormatMessage(LogLevel level, const std::string& message, const std::string& scope);
|
||||||
|
std::string GetTimestamp();
|
||||||
|
std::string LogLevelToString(LogLevel level);
|
||||||
|
bool ShouldLogToConsole(LogLevel level);
|
||||||
|
bool ShouldLogToFile(LogLevel level);
|
||||||
|
};
|
8
src/components.h
Normal file
8
src/components.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "components/sprite_component.h"
|
||||||
|
#include "components/scene_component.h"
|
||||||
|
#include "components/transform_component.h"
|
||||||
|
#include "components/health_component.h"
|
||||||
|
#include "components/input_component.h"
|
||||||
|
#include "components/physics_component.h"
|
8
src/components/health_component.h
Normal file
8
src/components/health_component.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct HealthComponent {
|
||||||
|
int currentHealth;
|
||||||
|
int maxHealth;
|
||||||
|
|
||||||
|
HealthComponent(int max) : maxHealth(max), currentHealth(max) {}
|
||||||
|
};
|
20
src/components/input_component.cpp
Normal file
20
src/components/input_component.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "input_component.h"
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
void InputComponent::BindKey(InputAction action, int key) {
|
||||||
|
keyBindings[action] = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputComponent::Update() {
|
||||||
|
for (const auto& [action, key] : keyBindings) {
|
||||||
|
if (IsKeyDown(key)) {
|
||||||
|
if (actionCallbacks.find(action) != actionCallbacks.end()) {
|
||||||
|
actionCallbacks[action]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputComponent::SetActionCallback(InputAction action, std::function<void()> callback) {
|
||||||
|
actionCallbacks[action] = std::move(callback);
|
||||||
|
}
|
25
src/components/input_component.h
Normal file
25
src/components/input_component.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
enum class InputAction {
|
||||||
|
MOVE_UP,
|
||||||
|
MOVE_DOWN,
|
||||||
|
MOVE_LEFT,
|
||||||
|
MOVE_RIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
class InputComponent {
|
||||||
|
public:
|
||||||
|
InputComponent() = default;
|
||||||
|
|
||||||
|
void BindKey(InputAction action, int key);
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
void SetActionCallback(InputAction action, std::function<void()> callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<InputAction, int> keyBindings;
|
||||||
|
std::unordered_map<InputAction, std::function<void()>> actionCallbacks;
|
||||||
|
};
|
6
src/components/physics_component.cpp
Normal file
6
src/components/physics_component.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "physics_component.h"
|
||||||
|
|
||||||
|
void PhysicsComponent::Update(float deltaTime) {
|
||||||
|
velocityX += accelerationX * deltaTime;
|
||||||
|
velocityY += accelerationY * deltaTime;
|
||||||
|
}
|
10
src/components/physics_component.h
Normal file
10
src/components/physics_component.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct PhysicsComponent {
|
||||||
|
float velocityX = 0.0f;
|
||||||
|
float velocityY = 0.0f;
|
||||||
|
float accelerationX = 0.0f;
|
||||||
|
float accelerationY = 0.0f;
|
||||||
|
|
||||||
|
void Update(float deltaTime);
|
||||||
|
};
|
1
src/components/scene_component.cpp
Normal file
1
src/components/scene_component.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "scene_component.h"
|
5
src/components/scene_component.h
Normal file
5
src/components/scene_component.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct SceneComponent {
|
||||||
|
bool isActive;
|
||||||
|
};
|
8
src/components/sprite_component.cpp
Normal file
8
src/components/sprite_component.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "sprite_component.h"
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
void SpriteComponent::Render(float x, float y) const {
|
||||||
|
if (texture) {
|
||||||
|
DrawTexture(*reinterpret_cast<Texture2D*>(texture), x, y, WHITE);
|
||||||
|
}
|
||||||
|
}
|
11
src/components/sprite_component.h
Normal file
11
src/components/sprite_component.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct SpriteComponent {
|
||||||
|
public:
|
||||||
|
void* texture; // void* to abstract Texture2D
|
||||||
|
void Render(float x, float y) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Usage:
|
||||||
|
// SpriteComponent sprite;
|
||||||
|
// sprite.texture = static_cast<void*>(&your_texture);
|
10
src/components/transform_component.h
Normal file
10
src/components/transform_component.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
class TransformComponent {
|
||||||
|
float x = 0.0f;
|
||||||
|
float y = 0.0f;
|
||||||
|
float scaleX = 1.0f;
|
||||||
|
float scaleY = 1.0f;
|
||||||
|
float rotation = 0.0f;
|
||||||
|
};
|
73
src/enet_client.cpp
Normal file
73
src/enet_client.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "network.h"
|
||||||
|
#include <enet.h>
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
class ENetClient : public Network {
|
||||||
|
public:
|
||||||
|
ENetClient() : client(nullptr), peer(nullptr) {}
|
||||||
|
|
||||||
|
void Initialize() override {
|
||||||
|
Logger& logger = Logger::GetInstance();
|
||||||
|
|
||||||
|
if (enet_initialize() != 0) {
|
||||||
|
logger.LogError("An error occurred while initializing ENet.", "ENetClient");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
client = enet_host_create(nullptr, 1, 2, 0, 0);
|
||||||
|
if (!client) {
|
||||||
|
logger.LogError("An error occurred while creating the ENet client.", "ENetClient");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetAddress address;
|
||||||
|
enet_address_set_host(&address, "localhost");
|
||||||
|
address.port = 1234;
|
||||||
|
|
||||||
|
peer = enet_host_connect(client, &address, 2, 0);
|
||||||
|
if (!peer) {
|
||||||
|
logger.LogError("No available peers for initiating connection.", "ENetClient");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogInfo("ENet client initialized and connected to server.", "ENetClient");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() override {
|
||||||
|
Logger& logger = Logger::GetInstance();
|
||||||
|
|
||||||
|
if (peer) {
|
||||||
|
enet_peer_disconnect(peer, 0);
|
||||||
|
logger.LogInfo("Disconnected from peer.", "ENetClient");
|
||||||
|
}
|
||||||
|
enet_host_destroy(client);
|
||||||
|
enet_deinitialize();
|
||||||
|
logger.LogInfo("ENet client shut down.", "ENetClient");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendData(const void* data, size_t size) override {
|
||||||
|
Logger& logger = Logger::GetInstance();
|
||||||
|
|
||||||
|
if (peer) {
|
||||||
|
ENetPacket* packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(peer, 0, packet);
|
||||||
|
logger.LogDebug("Data sent to server.", "ENetClient");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveData() override {
|
||||||
|
Logger& logger = Logger::GetInstance();
|
||||||
|
|
||||||
|
ENetEvent event;
|
||||||
|
while (enet_host_service(client, &event, 0) > 0) {
|
||||||
|
if (event.type == ENET_EVENT_TYPE_RECEIVE) {
|
||||||
|
logger.LogInfo("Received packet: " + std::string(reinterpret_cast<const char*>(event.packet->data)), "ENetClient");
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ENetHost* client;
|
||||||
|
ENetPeer* peer;
|
||||||
|
};
|
48
src/enet_server.cpp
Normal file
48
src/enet_server.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include "network.h"
|
||||||
|
#include <enet.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ENetServer : public Network {
|
||||||
|
public:
|
||||||
|
ENetServer() : server(nullptr) {}
|
||||||
|
|
||||||
|
void Initialize() override {
|
||||||
|
if (enet_initialize() != 0) {
|
||||||
|
std::cerr << "An error occurred while initializing ENet.\n";
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENetAddress address;
|
||||||
|
address.host = ENET_HOST_ANY;
|
||||||
|
address.port = 1234;
|
||||||
|
|
||||||
|
server = enet_host_create(&address, 32, 2, 0, 0);
|
||||||
|
if (!server) {
|
||||||
|
std::cerr << "An error occurred while trying to create the server.\n";
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() override {
|
||||||
|
enet_host_destroy(server);
|
||||||
|
enet_deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendData(const void* data, size_t size) override {
|
||||||
|
ENetPacket* packet = enet_packet_create(data, size, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_host_broadcast(server, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveData() override {
|
||||||
|
ENetEvent event;
|
||||||
|
while (enet_host_service(server, &event, 0) > 0) {
|
||||||
|
if (event.type == ENET_EVENT_TYPE_RECEIVE) {
|
||||||
|
std::cout << "Received packet from client: " << event.packet->data << "\n";
|
||||||
|
enet_packet_destroy(event.packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ENetHost* server;
|
||||||
|
};
|
16
src/network.h
Normal file
16
src/network.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define SERVER_PORT 6771
|
||||||
|
#define SERVER_ADDRESS "127.0.0.1"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Network {
|
||||||
|
public:
|
||||||
|
virtual void Initialize() = 0;
|
||||||
|
virtual void Shutdown() = 0;
|
||||||
|
virtual void SendData(const void* data, size_t size) = 0;
|
||||||
|
virtual void ReceiveData() = 0;
|
||||||
|
|
||||||
|
virtual ~Network() = default;
|
||||||
|
};
|
40
src/scene_manager.h
Normal file
40
src/scene_manager.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <components.h>
|
||||||
|
|
||||||
|
class SceneManager {
|
||||||
|
public:
|
||||||
|
SceneManager(entt::registry& registry) : registry(registry), activeScene(entt::null) {}
|
||||||
|
|
||||||
|
void SetActiveScene(entt::entity scene) {
|
||||||
|
if (activeScene != entt::null) {
|
||||||
|
auto& currentScene = registry.get<SceneComponent>(activeScene);
|
||||||
|
currentScene.isActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeScene = scene;
|
||||||
|
auto& newScene = registry.get<SceneComponent>(activeScene);
|
||||||
|
newScene.isActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
entt::entity CreateScene() {
|
||||||
|
entt::entity scene = registry.create();
|
||||||
|
registry.emplace<SceneComponent>(scene, false);
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateActiveScene() {
|
||||||
|
if (activeScene != entt::null) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderActiveScene() {
|
||||||
|
if (activeScene != entt::null) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
entt::registry& registry;
|
||||||
|
entt::entity activeScene;
|
||||||
|
};
|
6102
thirdparty/enet/enet.h
vendored
Normal file
6102
thirdparty/enet/enet.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user