Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Source/Game-Lib/Game-Lib/Application/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ AutoCVar_Int CVAR_ApplicationNumThreads(CVarCategory::Client, "numThreads", "num
AutoCVar_Int CVAR_ClientDBSaveMethod(CVarCategory::Client, "clientDBSaveMethod", "specifies when clientDBs are saved. (0 = Immediately, 1 = Every x Seconds, 2 = On Shutdown, 3+ = Disabled, default is 1)", 1);
AutoCVar_Float CVAR_ClientDBSaveTimer(CVarCategory::Client, "clientDBSaveTimer", "specifies how often clientDBs are saved when using save method 1 (Specified in seconds, default is 5 seconds)", 5.0f);
AutoCVar_String CVAR_ImguiTheme(CVarCategory::Client, "imguiTheme", "specifies the current imgui theme", "Blue Teal", CVarFlags::Hidden);
AutoCVar_Int CVAR_DeveloperMode(CVarCategory::Client, "developerMode", "enables developer-only Luau APIs (Editor, Time) and dev-tool scripts under Resources/Scripts/Editor", 1, CVarFlags::EditCheckbox);

Application::Application() : _messagesInbound(256), _messagesOutbound(256) { }
Application::~Application()
Expand Down Expand Up @@ -361,6 +362,14 @@ bool Application::Init()
auto globalKey = Scripting::ZenithInfoKey::MakeGlobal(0, 0);
_luaManager->GetZenithStateManager().Add(globalKey);

_luaManager->SetDeveloperMode(CVAR_DeveloperMode.Get() != 0);

CVarSystem::Get()->AddOnIntValueChanged(CVarCategory::Client, "developerMode"_h,
[this](const i32& value)
{
_luaManager->SetDeveloperMode(value != 0);
});

_luaManager->Init();
}

Expand Down
16 changes: 16 additions & 0 deletions Source/Game-Lib/Game-Lib/ECS/Components/UI/LayoutEventInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once
#include <Base/Types.h>

namespace ECS::Components::UI
{
struct LayoutEventInfo
{
public:
// Lua function ref (LUA_REGISTRYINDEX) of the layout's refresh callback,
// installed by Lua-side LinearLayout/GridLayout via Widget:RegisterLayoutRefresh.
// Cleared on entity destroy by ReleaseLayoutEventInfoRefs (UIRefCleanup).
i32 onLayoutRefresh = -1;
};

struct DirtyLayoutTag {};
}
3 changes: 3 additions & 0 deletions Source/Game-Lib/Game-Lib/ECS/Components/UI/PanelTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace ECS::Components::UI
u8 cornerRadius : 1 = 0;
u8 texCoords : 1 = 0;
u8 nineSliceCoords : 1 = 0;
u8 border : 1 = 0;
};
SetFlags setFlags;

Expand All @@ -32,6 +33,8 @@ namespace ECS::Components::UI
std::string foreground;
Color color = Color::White;
f32 cornerRadius = 0.0f;
Color borderColor = Color(0.0f, 0.0f, 0.0f, 1.0f);
f32 borderSize = 0.0f;
::UI::Box texCoords;
::UI::Box nineSliceCoords;

Expand Down
6 changes: 5 additions & 1 deletion Source/Game-Lib/Game-Lib/ECS/Scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ namespace ECS

joltState.updateTimer += glm::clamp(clampedDeltaTime, 0.0f, Singletons::JoltState::FixedDeltaTime);

Systems::UpdateDayNightCycle::Update(gameRegistry, clampedDeltaTime);
// Day/night cycle is a wall-clock-style timer: pass the unclamped deltaTime so
// the in-game time tracks real seconds 1:1. Clamping (as the rest of this
// function uses for physics/animation stability) makes the cycle drift behind
// wall-clock whenever the framerate dips below 60 FPS.
Systems::UpdateDayNightCycle::Update(gameRegistry, deltaTime);
Systems::NetworkConnection::Update(gameRegistry, clampedDeltaTime);
Systems::DrawDebugMesh::Update(gameRegistry, clampedDeltaTime);
Systems::Animation::Update(gameRegistry, clampedDeltaTime);
Expand Down
11 changes: 9 additions & 2 deletions Source/Game-Lib/Game-Lib/ECS/Singletons/DayNightCycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ namespace ECS::Singletons
static constexpr f32 SecondsPerMinute = 60.0f;
static constexpr f32 SecondsPerDay = SecondsPerMinute * MinutesPerHour * HoursPerDay;

f32 timeInSeconds = 0.0f;
// f64: f32 ULP at 86400 is ~4-8 ms, comparable to deltaTime, so an f32
// accumulator drifts by seconds per minute.
f64 timeInSeconds = 0.0;
f32 speedModifier = 1.0f;

// -1 so the first Update fires the second-changed callback.
i32 lastIntegerSecond = -1;

f32 GetTimeInSecondsF32() const { return static_cast<f32>(timeInSeconds); }
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ namespace ECS::Systems
auto& dayNightCycle = ctx.get<Singletons::DayNightCycle>();

// Get light settings
vec3 lightDirection = UpdateAreaLights::GetLightDirection(dayNightCycle.timeInSeconds);
vec3 lightDirection = UpdateAreaLights::GetLightDirection(dayNightCycle.GetTimeInSecondsF32());

// Get active render camera
auto& activeCamera = ctx.get<ECS::Singletons::ActiveCamera>();
Expand Down
11 changes: 4 additions & 7 deletions Source/Game-Lib/Game-Lib/ECS/Systems/UI/HandleInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,15 +439,12 @@ namespace ECS::Systems::UI

if (isWithin)
{
Components::Transform2D& transform = registry.get<Components::Transform2D>(childEntity);

vec2 middlePoint = (min + max) * 0.5f;
u32 distanceToMouse = static_cast<u32>(glm::distance(middlePoint, mousePos));

u16 numParents = std::numeric_limits<u16>::max() - static_cast<u16>(transform.GetHierarchyDepth());
u16 layer = std::numeric_limits<u16>::max() - static_cast<u16>(transform.GetLayer());
u32 distanceToMouse = static_cast<u32>(glm::distance(middlePoint, mousePos)); // Distance in pixels

u64 key = (static_cast<u64>(numParents) << 48) | (static_cast<u64>(layer) << 32) | distanceToMouse;
// Invert sortKey: higher sortKey draws on top, but the map dispatches smallest first.
u32 invertedSortKey = std::numeric_limits<u32>::max() - widget.sortKey;
u64 key = (static_cast<u64>(invertedSortKey) << 32) | distanceToMouse;
allHoveredEntities[key] = childEntity;
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Game-Lib/Game-Lib/ECS/Systems/UpdateAreaLights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ namespace ECS::Systems

MaterialRenderer* materialRenderer = ServiceLocator::GetGameRenderer()->GetMaterialRenderer();

vec3 direction = GetLightDirection(dayNightCycle.timeInSeconds);
vec3 direction = GetLightDirection(dayNightCycle.GetTimeInSecondsF32());
const vec3& diffuseColor = glm::normalize(areaLightInfo.finalColorData.diffuseColor);
const vec3& ambientColor = glm::normalize(areaLightInfo.finalColorData.ambientColor);
vec3 groundAmbientColor = ambientColor * 0.7f;
Expand Down
36 changes: 31 additions & 5 deletions Source/Game-Lib/Game-Lib/ECS/Systems/UpdateDayNightCycle.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#include "UpdateDayNightCycle.h"
#include "Game-Lib/Application/EnttRegistries.h"
#include "Game-Lib/ECS/Singletons/DayNightCycle.h"
#include "Game-Lib/Scripting/Handlers/UIHandler.h"
#include "Game-Lib/Scripting/Util/ZenithUtil.h"
#include "Game-Lib/Util/ServiceLocator.h"

#include <MetaGen/Game/Lua/Lua.h>

#include <Scripting/LuaManager.h>
#include <Scripting/Zenith.h>

#include <entt/entt.hpp>
#include <tracy/Tracy.hpp>
Expand Down Expand Up @@ -34,17 +43,34 @@ namespace ECS::Systems
entt::registry::context& context = registry.ctx();
auto& dayNightCycle = context.get<Singletons::DayNightCycle>();

dayNightCycle.timeInSeconds += (1.0f * dayNightCycle.speedModifier) * deltaTime;
dayNightCycle.timeInSeconds += static_cast<f64>(dayNightCycle.speedModifier) * static_cast<f64>(deltaTime);

while (dayNightCycle.timeInSeconds > Singletons::DayNightCycle::SecondsPerDay)
{
dayNightCycle.timeInSeconds -= Singletons::DayNightCycle::SecondsPerDay;
}

i32 currentInteger = static_cast<i32>(dayNightCycle.timeInSeconds);
if (currentInteger != dayNightCycle.lastIntegerSecond)
{
dayNightCycle.lastIntegerSecond = currentInteger;

Scripting::LuaManager* luaManager = ServiceLocator::GetLuaManager();
Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
if (luaManager && zenith)
{
Scripting::UI::UIHandler* uiHandler = luaManager->GetLuaHandler<Scripting::UI::UIHandler>(static_cast<u16>(MetaGen::Game::Lua::LuaHandlerTypeEnum::UI));
if (uiHandler)
{
uiHandler->OnSecondChanged(zenith, dayNightCycle.timeInSeconds);
}
}
}
}

void UpdateDayNightCycle::SetTimeToDefault(entt::registry& registry)
{
f32 secondsSinceMidnightUTC = static_cast<f32>(GetSecondsSinceMidnightUTC());
f64 secondsSinceMidnightUTC = static_cast<f64>(GetSecondsSinceMidnightUTC());
while (secondsSinceMidnightUTC > Singletons::DayNightCycle::SecondsPerDay)
{
secondsSinceMidnightUTC -= Singletons::DayNightCycle::SecondsPerDay;
Expand All @@ -53,7 +79,7 @@ namespace ECS::Systems
SetTime(registry, secondsSinceMidnightUTC);
}

void UpdateDayNightCycle::SetTime(entt::registry& registry, f32 time)
void UpdateDayNightCycle::SetTime(entt::registry& registry, f64 time)
{
entt::registry::context& context = registry.ctx();
auto& dayNightCycle = context.get<Singletons::DayNightCycle>();
Expand All @@ -67,9 +93,9 @@ namespace ECS::Systems

dayNightCycle.speedModifier = speedModifier;
}
void UpdateDayNightCycle::SetTimeAndSpeedModifier(entt::registry& registry, f32 time, f32 speedModifier)
void UpdateDayNightCycle::SetTimeAndSpeedModifier(entt::registry& registry, f64 time, f32 speedModifier)
{
SetTime(registry, time);
SetSpeedModifier(registry, speedModifier);
}
}
}
4 changes: 2 additions & 2 deletions Source/Game-Lib/Game-Lib/ECS/Systems/UpdateDayNightCycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ namespace ECS::Systems
static void Update(entt::registry& registry, f32 deltaTime);

static void SetTimeToDefault(entt::registry& registry);
static void SetTime(entt::registry& registry, f32 time);
static void SetTime(entt::registry& registry, f64 time);
static void SetSpeedModifier(entt::registry& registry, f32 speedModifier);
static void SetTimeAndSpeedModifier(entt::registry& registry, f32 time, f32 speedModifier);
static void SetTimeAndSpeedModifier(entt::registry& registry, f64 time, f32 speedModifier);
};
}
39 changes: 39 additions & 0 deletions Source/Game-Lib/Game-Lib/ECS/Util/UIRefCleanup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "UIRefCleanup.h"
#include "Game-Lib/ECS/Components/UI/EventInputInfo.h"
#include "Game-Lib/ECS/Components/UI/LayoutEventInfo.h"
#include "Game-Lib/Scripting/Util/ZenithUtil.h"

#include <entt/entt.hpp>

namespace ECS::Util::UIRefCleanup
{
void ReleaseEventInputInfoRefs(entt::registry& registry, entt::entity entity)
{
// Shutdown order: the registry may destroy entities after the LuaManager
// is gone. Skip rather than crash; the Lua state is being torn down anyway.
::Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
if (zenith == nullptr) return;

auto& info = registry.get<ECS::Components::UI::EventInputInfo>(entity);
Scripting::Util::Zenith::Unref(zenith, info.onMouseDownEvent);
Scripting::Util::Zenith::Unref(zenith, info.onMouseUpEvent);
Scripting::Util::Zenith::Unref(zenith, info.onMouseHeldEvent);
Scripting::Util::Zenith::Unref(zenith, info.onMouseScrollEvent);
Scripting::Util::Zenith::Unref(zenith, info.onHoverBeginEvent);
Scripting::Util::Zenith::Unref(zenith, info.onHoverEndEvent);
Scripting::Util::Zenith::Unref(zenith, info.onHoverHeldEvent);
Scripting::Util::Zenith::Unref(zenith, info.onFocusBeginEvent);
Scripting::Util::Zenith::Unref(zenith, info.onFocusEndEvent);
Scripting::Util::Zenith::Unref(zenith, info.onFocusHeldEvent);
Scripting::Util::Zenith::Unref(zenith, info.onKeyboardEvent);
}

void ReleaseLayoutEventInfoRefs(entt::registry& registry, entt::entity entity)
{
::Scripting::Zenith* zenith = Scripting::Util::Zenith::GetGlobal();
if (zenith == nullptr) return;

auto& info = registry.get<ECS::Components::UI::LayoutEventInfo>(entity);
Scripting::Util::Zenith::Unref(zenith, info.onLayoutRefresh);
}
}
13 changes: 13 additions & 0 deletions Source/Game-Lib/Game-Lib/ECS/Util/UIRefCleanup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once
#include <entt/fwd.hpp>

namespace ECS::Util::UIRefCleanup
{
// entt on_destroy observers attached at UI registry construction
// (Application.cpp). Each iterates the i32 Lua-registry refs on the
// outgoing component and lua_unref's the populated ones, so callbacks
// installed via SetOnMouseUp / RegisterLayoutRefresh / etc. don't
// leak the registry slot when the widget entity is destroyed.
void ReleaseEventInputInfoRefs(entt::registry& registry, entt::entity entity);
void ReleaseLayoutEventInfoRefs(entt::registry& registry, entt::entity entity);
}
80 changes: 0 additions & 80 deletions Source/Game-Lib/Game-Lib/Editor/Clock.cpp

This file was deleted.

15 changes: 0 additions & 15 deletions Source/Game-Lib/Game-Lib/Editor/Clock.h

This file was deleted.

3 changes: 1 addition & 2 deletions Source/Game-Lib/Game-Lib/Editor/EditorHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#include "ActionStack.h"
#include "AnimationController.h"
#include "AssetBrowser.h"
#include "BaseEditor.h"
#include "CameraInfo.h"
#include "CDBEditor.h"
#include "Clock.h"
#include "CVarEditor.h"
#include "EaseCurveTool.h"
#include "Hierarchy.h"
Expand Down Expand Up @@ -50,7 +50,6 @@ namespace Editor
_editors.push_back(new CVarEditor());
_editors.push_back(new CameraInfo());
_editors.push_back(new CDBEditor());
_editors.push_back(new Clock());
_editors.push_back(new PerformanceDiagnostics());
_editors.push_back(new MapSelector());
_editors.push_back(new NetworkedInfo());
Expand Down
Loading
Loading