Replace float/UInt64 durations by a more precise Time class (#388)
Improve Clock class with atomic RestartIfOver method and allows to choose required precision
This commit is contained in:
parent
1de5f65536
commit
dd421a6385
|
|
@ -1063,16 +1063,16 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock updateClock;
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
std::size_t totalFrameCount = 0;
|
||||
|
||||
Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
Nz::Time elapsedTime = Nz::Time::Zero();
|
||||
Nz::Time time = Nz::GetElapsedNanoseconds();
|
||||
|
||||
auto ComputeLightAnimationSpeed = [](const Nz::Vector3f& position)
|
||||
{
|
||||
|
|
@ -1095,9 +1095,9 @@ int main()
|
|||
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
Nz::Time now = Nz::GetElapsedNanoseconds();
|
||||
if (lightAnimation)
|
||||
elapsedTime += (now - time) / 1'000'000.f;
|
||||
elapsedTime += now - time;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
|
|
@ -1129,13 +1129,14 @@ int main()
|
|||
{
|
||||
if (event.key.scancode == Nz::Keyboard::Scancode::Space)
|
||||
{
|
||||
float elapsedSeconds = elapsedTime.AsSeconds();
|
||||
float rotationSpeed = ComputeLightAnimationSpeed(viewerPos);
|
||||
|
||||
auto& spotLight = spotLights.emplace_back();
|
||||
spotLight.color = Nz::Color(0.4f, 0.4f, 1.f);
|
||||
spotLight.radius = 5.f;
|
||||
spotLight.position = AnimateLightPosition(viewerPos, rotationSpeed, -elapsedTime);
|
||||
spotLight.direction = AnimateLightDirection(camQuat * Nz::Vector3f::Forward(), rotationSpeed, -elapsedTime);
|
||||
spotLight.position = AnimateLightPosition(viewerPos, rotationSpeed, -elapsedSeconds);
|
||||
spotLight.direction = AnimateLightDirection(camQuat * Nz::Vector3f::Forward(), rotationSpeed, -elapsedSeconds);
|
||||
|
||||
lightUpdate = true;
|
||||
}
|
||||
|
|
@ -1163,10 +1164,9 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
float cameraSpeed = 2.f * updateClock.GetSeconds();
|
||||
updateClock.Restart();
|
||||
float cameraSpeed = 2.f * deltaTime->AsSeconds();
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
|
||||
viewerPos += camQuat * Nz::Vector3f::Forward() * cameraSpeed;
|
||||
|
|
@ -1465,7 +1465,9 @@ int main()
|
|||
modelInstance2.OnTransfer(frame, builder);
|
||||
planeInstance.OnTransfer(frame, builder);
|
||||
|
||||
Nz::EulerAnglesf flareRotation(0.f, 0.f, elapsedTime * 10.f);
|
||||
float elapsedSeconds = elapsedTime.AsSeconds();
|
||||
|
||||
Nz::EulerAnglesf flareRotation(0.f, 0.f, elapsedSeconds * 10.f);
|
||||
flareInstance.UpdateWorldMatrix(Nz::Matrix4f::Transform(viewerPos + flarePosition, flareRotation));
|
||||
flareInstance.OnTransfer(frame, builder);
|
||||
|
||||
|
|
@ -1481,8 +1483,8 @@ int main()
|
|||
{
|
||||
float rotationSpeed = ComputeLightAnimationSpeed(spotLight.position);
|
||||
|
||||
Nz::Vector3f position = AnimateLightPosition(spotLight.position, rotationSpeed, elapsedTime);
|
||||
Nz::Vector3f direction = AnimateLightDirection(spotLight.direction, rotationSpeed, elapsedTime);
|
||||
Nz::Vector3f position = AnimateLightPosition(spotLight.position, rotationSpeed, elapsedSeconds);
|
||||
Nz::Vector3f direction = AnimateLightDirection(spotLight.direction, rotationSpeed, elapsedSeconds);
|
||||
|
||||
Nz::AccessByOffset<Nz::Vector3f&>(lightDataPtr, colorOffset) = Nz::Vector3f(spotLight.color.r, spotLight.color.g, spotLight.color.b);
|
||||
Nz::AccessByOffset<Nz::Vector3f&>(lightDataPtr, positionOffset) = position;
|
||||
|
|
@ -1565,23 +1567,10 @@ int main()
|
|||
fps++;
|
||||
totalFrameCount++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
// Et on insère ces données dans le titre de la fenêtre
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
||||
/*
|
||||
Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier,
|
||||
via quelque chose de similaire à u8"Cha\u00CEne de caract\u00E8res".
|
||||
Cependant, si le code source est encodé en UTF-8 (Comme c'est le cas dans ce fichier),
|
||||
cela fonctionnera aussi comme ceci : "Chaîne de caractères".
|
||||
*/
|
||||
|
||||
// Et on réinitialise le compteur de FPS
|
||||
fps = 0;
|
||||
|
||||
// Et on relance l'horloge pour refaire ça dans une seconde
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,17 +53,17 @@ int main()
|
|||
sound.Play();
|
||||
|
||||
// La boucle du programme (Pour déplacer le son)
|
||||
Nz::Clock clock;
|
||||
Nz::MillisecondClock clock;
|
||||
while (sound.GetStatus() == Nz::SoundStatus::Playing)
|
||||
{
|
||||
// Comme le son se joue dans un thread séparé, on peut mettre en pause le principal régulièrement
|
||||
int sleepTime = int(1000/60 - clock.GetMilliseconds()); // 60 FPS
|
||||
Nz::Time sleepTime = Nz::Time::TickDuration(60) - clock.GetElapsedTime(); // 60 FPS
|
||||
|
||||
if (sleepTime > 0)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
|
||||
if (sleepTime > Nz::Time::Millisecond())
|
||||
std::this_thread::sleep_for(sleepTime.AsDuration<std::chrono::milliseconds>());
|
||||
|
||||
// On bouge la source du son en fonction du temps depuis chaque mise à jour
|
||||
Nz::Vector3f pos = sound.GetPosition() + sound.GetVelocity()*clock.GetSeconds();
|
||||
Nz::Vector3f pos = sound.GetPosition() + sound.GetVelocity() * clock.GetElapsedTime().AsSeconds();
|
||||
sound.SetPosition(pos);
|
||||
|
||||
std::cout << "Sound position: " << pos << std::endl;
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock updateClock;
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
|
@ -161,10 +161,9 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
float cameraSpeed = 2.f * updateClock.GetSeconds();
|
||||
updateClock.Restart();
|
||||
float cameraSpeed = 2.f * deltaTime->AsSeconds();
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
|
||||
viewerPos += camQuat * Nz::Vector3f::Forward() * cameraSpeed;
|
||||
|
|
@ -209,23 +208,10 @@ int main()
|
|||
// On incrémente le compteur de FPS improvisé
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
// Et on insère ces données dans le titre de la fenêtre
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
||||
/*
|
||||
Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier,
|
||||
via quelque chose de similaire à u8"Cha\u00CEne de caract\u00E8res".
|
||||
Cependant, si le code source est encodé en UTF-8 (Comme c'est le cas dans ce fichier),
|
||||
cela fonctionnera aussi comme ceci : "Chaîne de caractères".
|
||||
*/
|
||||
|
||||
// Et on réinitialise le compteur de FPS
|
||||
fps = 0;
|
||||
|
||||
// Et on relance l'horloge pour refaire ça dans une seconde
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ int main()
|
|||
texParams.renderDevice = device;
|
||||
texParams.loadFormat = Nz::PixelFormat::RGBA8;
|
||||
|
||||
std::shared_ptr<Nz::MaterialInstance> material = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->Instantiate();
|
||||
material->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "box.png", texParams));
|
||||
std::shared_ptr<Nz::MaterialInstance> spriteMaterial = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->Instantiate();
|
||||
spriteMaterial->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "box.png", texParams));
|
||||
|
||||
for (std::size_t y = 0; y < 30; ++y)
|
||||
{
|
||||
|
|
@ -77,7 +77,7 @@ int main()
|
|||
{
|
||||
entt::entity spriteEntity = registry.create();
|
||||
{
|
||||
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(material);
|
||||
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(spriteMaterial);
|
||||
sprite->SetSize({ 32.f, 32.f });
|
||||
sprite->SetOrigin({ 0.5f, 0.5f });
|
||||
|
||||
|
|
@ -97,10 +97,10 @@ int main()
|
|||
tilemap->SetOrigin({ 0.5f, 0.5f });
|
||||
for (std::size_t i = 0; i < 18; ++i)
|
||||
{
|
||||
std::shared_ptr<Nz::MaterialInstance> material = Nz::Graphics::Instance()->GetDefaultMaterials().basicTransparent->Clone();
|
||||
material->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "tiles" / (std::to_string(i + 1) + ".png"), texParams));
|
||||
std::shared_ptr<Nz::MaterialInstance> tileMaterial = Nz::Graphics::Instance()->GetDefaultMaterials().basicTransparent->Clone();
|
||||
tileMaterial->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "tiles" / (std::to_string(i + 1) + ".png"), texParams));
|
||||
|
||||
tilemap->SetMaterial(i, material);
|
||||
tilemap->SetMaterial(i, tileMaterial);
|
||||
}
|
||||
|
||||
for (unsigned int y = 0; y < 20; ++y)
|
||||
|
|
@ -122,14 +122,12 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock secondClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
//Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
|
||||
Nz::PidController<Nz::Vector3f> headingController(0.5f, 0.f, 0.05f);
|
||||
Nz::PidController<Nz::Vector3f> upController(1.f, 0.f, 0.1f);
|
||||
|
|
@ -137,10 +135,6 @@ int main()
|
|||
bool showColliders = false;
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
elapsedTime = (now - time) / 1'000'000.f;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
while (window.PollEvent(&event))
|
||||
{
|
||||
|
|
@ -165,13 +159,10 @@ int main()
|
|||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
if (secondClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,25 +198,18 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock updateClock;
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
|
||||
Nz::PidController<Nz::Vector3f> headingController(0.3f, 0.f, 0.1f);
|
||||
Nz::PidController<Nz::Vector3f> upController(1.f, 0.f, 0.1f);
|
||||
|
||||
bool showColliders = false;
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
elapsedTime = (now - time) / 1'000'000.f;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
while (window.PollEvent(&event))
|
||||
{
|
||||
|
|
@ -286,8 +279,10 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
float elapsedTime = deltaTime->AsSeconds();
|
||||
|
||||
auto spaceshipView = registry.view<Nz::NodeComponent, Nz::RigidBody3DComponent>();
|
||||
for (auto&& [entity, node, _] : spaceshipView.each())
|
||||
{
|
||||
|
|
@ -338,13 +333,10 @@ int main()
|
|||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -357,12 +357,11 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock fpsClock, updateClock;
|
||||
Nz::MillisecondClock fpsClock, updateClock;
|
||||
float incr = 0.f;
|
||||
unsigned int currentFrame = 0;
|
||||
unsigned int nextFrame = 1;
|
||||
Nz::EulerAnglesf camAngles = Nz::EulerAnglesf(-30.f, 0.f, 0.f);
|
||||
Nz::UInt64 lastTime = Nz::GetElapsedMicroseconds();
|
||||
Nz::UInt64 fps = 0;
|
||||
bool paused = false;
|
||||
|
||||
|
|
@ -409,9 +408,9 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
float updateTime = updateClock.Restart() / 1'000'000.f;
|
||||
float updateTime = deltaTime->AsSeconds();
|
||||
|
||||
/*auto& playerBody = registry.get<Nz::RigidBody3DComponent>(playerEntity);
|
||||
|
||||
|
|
@ -533,12 +532,9 @@ int main()
|
|||
|
||||
fps++;
|
||||
|
||||
if (fpsClock.GetMilliseconds() >= 1000)
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
fpsClock.Restart();
|
||||
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||
|
||||
fps = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,19 +127,11 @@ int main()
|
|||
|
||||
mainWindow.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
float elapsedTime = 0.f;
|
||||
Nz::UInt64 time = Nz::GetElapsedMicroseconds();
|
||||
|
||||
while (mainWindow.IsOpen())
|
||||
{
|
||||
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
|
||||
elapsedTime = (now - time) / 1'000'000.f;
|
||||
time = now;
|
||||
|
||||
Nz::WindowEvent event;
|
||||
while (mainWindow.PollEvent(&event))
|
||||
{
|
||||
|
|
@ -158,13 +150,10 @@ int main()
|
|||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
mainWindow.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(registry.alive()) + " entities");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -34,6 +35,7 @@ namespace Nz
|
|||
virtual float GetAttenuation() const = 0;
|
||||
virtual float GetMinDistance() const = 0;
|
||||
virtual float GetPitch() const = 0;
|
||||
virtual Time GetPlayingOffset() const = 0;
|
||||
virtual Vector3f GetPosition() const = 0;
|
||||
virtual UInt32 GetSampleOffset() const = 0;
|
||||
virtual OffsetWithLatency GetSampleOffsetAndLatency() const = 0;
|
||||
|
|
@ -53,6 +55,7 @@ namespace Nz
|
|||
virtual void SetBuffer(std::shared_ptr<AudioBuffer> audioBuffer) = 0;
|
||||
virtual void SetMinDistance(float minDistance) = 0;
|
||||
virtual void SetPitch(float pitch) = 0;
|
||||
virtual void SetPlayingOffset(Time offset) = 0;
|
||||
virtual void SetPosition(const Vector3f& position) = 0;
|
||||
virtual void SetSampleOffset(UInt32 offset) = 0;
|
||||
virtual void SetVelocity(const Vector3f& velocity) = 0;
|
||||
|
|
@ -70,7 +73,7 @@ namespace Nz
|
|||
struct OffsetWithLatency
|
||||
{
|
||||
UInt64 sampleOffset;
|
||||
UInt64 sourceLatency;
|
||||
Time sourceLatency;
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <Nazara/Audio/AudioBuffer.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -23,7 +24,7 @@ namespace Nz
|
|||
~DummyAudioBuffer() = default;
|
||||
|
||||
AudioFormat GetAudioFormat() const;
|
||||
UInt32 GetDuration() const;
|
||||
Time GetDuration() const;
|
||||
UInt64 GetSampleCount() const override;
|
||||
UInt64 GetSize() const override;
|
||||
UInt32 GetSampleRate() const override;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace Nz
|
|||
float GetAttenuation() const override;
|
||||
float GetMinDistance() const override;
|
||||
float GetPitch() const override;
|
||||
Time GetPlayingOffset() const override;
|
||||
Vector3f GetPosition() const override;
|
||||
UInt32 GetSampleOffset() const override;
|
||||
OffsetWithLatency GetSampleOffsetAndLatency() const override;
|
||||
|
|
@ -49,6 +50,7 @@ namespace Nz
|
|||
void SetBuffer(std::shared_ptr<AudioBuffer> audioBuffer) override;
|
||||
void SetMinDistance(float minDistance) override;
|
||||
void SetPitch(float pitch) override;
|
||||
void SetPlayingOffset(Time offset) override;
|
||||
void SetPosition(const Vector3f& position) override;
|
||||
void SetSampleOffset(UInt32 offset) override;
|
||||
void SetVelocity(const Vector3f& velocity) override;
|
||||
|
|
@ -65,11 +67,11 @@ namespace Nz
|
|||
|
||||
private:
|
||||
void RequeueBuffers();
|
||||
UInt64 UpdateTime() const;
|
||||
Time UpdateTime() const;
|
||||
|
||||
mutable std::vector<std::shared_ptr<DummyAudioBuffer>> m_queuedBuffers;
|
||||
mutable std::vector<std::shared_ptr<DummyAudioBuffer>> m_processedBuffers;
|
||||
mutable Clock m_playClock;
|
||||
mutable MillisecondClock m_playClock;
|
||||
mutable SoundStatus m_status;
|
||||
Vector3f m_position;
|
||||
Vector3f m_velocity;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Nz
|
|||
{
|
||||
inline DummyAudioSource::DummyAudioSource(std::shared_ptr<AudioDevice> device) :
|
||||
AudioSource(std::move(device)),
|
||||
m_playClock(0, true),
|
||||
m_playClock(Time::Zero(), true),
|
||||
m_status(SoundStatus::Stopped),
|
||||
m_position(Vector3f::Zero()),
|
||||
m_velocity(Vector3f::Zero()),
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Nz
|
|||
{
|
||||
class AudioBuffer;
|
||||
|
||||
class NAZARA_AUDIO_API Music : public Resource, public SoundEmitter
|
||||
class NAZARA_AUDIO_API Music final : public Resource, public SoundEmitter
|
||||
{
|
||||
public:
|
||||
Music();
|
||||
|
|
@ -36,11 +36,12 @@ namespace Nz
|
|||
|
||||
void EnableLooping(bool loop) override;
|
||||
|
||||
UInt32 GetDuration() const override;
|
||||
Time GetDuration() const override;
|
||||
AudioFormat GetFormat() const;
|
||||
UInt32 GetPlayingOffset() const override;
|
||||
Time GetPlayingOffset() const;
|
||||
UInt64 GetSampleCount() const;
|
||||
UInt32 GetSampleRate() const;
|
||||
UInt64 GetSampleOffset() const override;
|
||||
UInt32 GetSampleRate() const override;
|
||||
SoundStatus GetStatus() const override;
|
||||
|
||||
bool IsLooping() const override;
|
||||
|
|
@ -52,7 +53,7 @@ namespace Nz
|
|||
void Pause() override;
|
||||
void Play() override;
|
||||
|
||||
void SetPlayingOffset(UInt32 offset);
|
||||
void SeekToSampleOffset(UInt64 offset);
|
||||
|
||||
void Stop() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ namespace Nz
|
|||
float GetAttenuation() const override;
|
||||
float GetMinDistance() const override;
|
||||
float GetPitch() const override;
|
||||
Time GetPlayingOffset() const override;
|
||||
Vector3f GetPosition() const override;
|
||||
UInt32 GetSampleOffset() const override;
|
||||
OffsetWithLatency GetSampleOffsetAndLatency() const override;
|
||||
|
|
@ -53,6 +54,7 @@ namespace Nz
|
|||
void SetBuffer(std::shared_ptr<AudioBuffer> audioBuffer) override;
|
||||
void SetMinDistance(float minDistance) override;
|
||||
void SetPitch(float pitch) override;
|
||||
void SetPlayingOffset(Time offset) override;
|
||||
void SetPosition(const Vector3f& position) override;
|
||||
void SetSampleOffset(UInt32 offset) override;
|
||||
void SetVelocity(const Vector3f& velocity) override;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_AUDIO_API Sound : public SoundEmitter
|
||||
class NAZARA_AUDIO_API Sound final : public SoundEmitter
|
||||
{
|
||||
public:
|
||||
using SoundEmitter::SoundEmitter;
|
||||
|
|
@ -27,8 +27,10 @@ namespace Nz
|
|||
void EnableLooping(bool loop) override;
|
||||
|
||||
const std::shared_ptr<SoundBuffer>& GetBuffer() const;
|
||||
UInt32 GetDuration() const override;
|
||||
UInt32 GetPlayingOffset() const override;
|
||||
Time GetDuration() const override;
|
||||
Time GetPlayingOffset() const override;
|
||||
UInt64 GetSampleOffset() const override;
|
||||
UInt32 GetSampleRate() const override;
|
||||
SoundStatus GetStatus() const override;
|
||||
|
||||
bool IsLooping() const override;
|
||||
|
|
@ -42,7 +44,8 @@ namespace Nz
|
|||
void Play() override;
|
||||
|
||||
void SetBuffer(std::shared_ptr<SoundBuffer> soundBuffer);
|
||||
void SetPlayingOffset(UInt32 offset);
|
||||
|
||||
void SeekToSampleOffset(UInt64 offset) override;
|
||||
|
||||
void Stop() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceManager.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
@ -52,7 +53,7 @@ namespace Nz
|
|||
|
||||
const std::shared_ptr<AudioBuffer>& GetAudioBuffer(AudioDevice* device);
|
||||
|
||||
inline UInt32 GetDuration() const;
|
||||
inline Time GetDuration() const;
|
||||
inline AudioFormat GetFormat() const;
|
||||
inline const Int16* GetSamples() const;
|
||||
inline UInt64 GetSampleCount() const;
|
||||
|
|
@ -76,7 +77,7 @@ namespace Nz
|
|||
std::unordered_map<AudioDevice*, AudioDeviceEntry> m_audioBufferByDevice;
|
||||
std::unique_ptr<Int16[]> m_samples;
|
||||
AudioFormat m_format;
|
||||
UInt32 m_duration;
|
||||
Time m_duration;
|
||||
UInt32 m_sampleRate;
|
||||
UInt64 m_sampleCount;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,10 +10,8 @@ namespace Nz
|
|||
/*!
|
||||
* \brief Gets the duration of the sound buffer
|
||||
* \return Duration of the sound buffer in milliseconds
|
||||
*
|
||||
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||
*/
|
||||
inline UInt32 SoundBuffer::GetDuration() const
|
||||
inline Time SoundBuffer::GetDuration() const
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Audio/Enums.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <limits>
|
||||
|
||||
|
|
@ -32,11 +33,13 @@ namespace Nz
|
|||
void EnableSpatialization(bool spatialization);
|
||||
|
||||
float GetAttenuation() const;
|
||||
virtual UInt32 GetDuration() const = 0;
|
||||
virtual Time GetDuration() const = 0;
|
||||
float GetMinDistance() const;
|
||||
float GetPitch() const;
|
||||
virtual UInt32 GetPlayingOffset() const = 0;
|
||||
virtual Time GetPlayingOffset() const = 0;
|
||||
Vector3f GetPosition() const;
|
||||
virtual UInt64 GetSampleOffset() const = 0;
|
||||
virtual UInt32 GetSampleRate() const = 0;
|
||||
Vector3f GetVelocity() const;
|
||||
virtual SoundStatus GetStatus() const = 0;
|
||||
float GetVolume() const;
|
||||
|
|
@ -48,6 +51,9 @@ namespace Nz
|
|||
virtual void Pause() = 0;
|
||||
virtual void Play() = 0;
|
||||
|
||||
virtual void SeekToPlayingOffset(Time offset);
|
||||
virtual void SeekToSampleOffset(UInt64 offset) = 0;
|
||||
|
||||
void SetAttenuation(float attenuation);
|
||||
void SetMinDistance(float minDistance);
|
||||
void SetPitch(float pitch);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/ResourceParameters.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <mutex>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -35,7 +36,7 @@ namespace Nz
|
|||
SoundStream() = default;
|
||||
virtual ~SoundStream();
|
||||
|
||||
virtual UInt32 GetDuration() const = 0;
|
||||
virtual Time GetDuration() const = 0;
|
||||
virtual AudioFormat GetFormat() const = 0;
|
||||
virtual std::mutex& GetMutex() = 0;
|
||||
virtual UInt64 GetSampleCount() const = 0;
|
||||
|
|
|
|||
|
|
@ -9,40 +9,46 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_CORE_API Clock
|
||||
template<bool HighPrecision>
|
||||
class Clock
|
||||
{
|
||||
public:
|
||||
Clock(UInt64 startingValue = 0, bool paused = false);
|
||||
Clock(Time startingValue = Time::Zero(), bool paused = false);
|
||||
Clock(const Clock& clock) = default;
|
||||
Clock(Clock&& clock) = default;
|
||||
Clock(Clock&& clock) noexcept = default;
|
||||
~Clock() = default;
|
||||
|
||||
float GetSeconds() const;
|
||||
UInt64 GetMicroseconds() const;
|
||||
UInt64 GetMilliseconds() const;
|
||||
Time GetElapsedTime() const;
|
||||
|
||||
bool IsPaused() const;
|
||||
|
||||
void Pause();
|
||||
UInt64 Restart(UInt64 startingValue = 0, bool paused = false);
|
||||
|
||||
Time Restart(Time startingPoint = Time::Zero(), bool paused = false);
|
||||
std::optional<Time> RestartIfOver(Time time);
|
||||
|
||||
void Unpause();
|
||||
|
||||
Clock& operator=(const Clock& clock) = default;
|
||||
Clock& operator=(Clock&& clock) = default;
|
||||
Clock& operator=(Clock&& clock) noexcept = default;
|
||||
|
||||
static Time Now();
|
||||
|
||||
private:
|
||||
UInt64 m_elapsedTime;
|
||||
UInt64 m_refTime;
|
||||
Time m_elapsedTime;
|
||||
Time m_refTime;
|
||||
bool m_paused;
|
||||
};
|
||||
|
||||
using ClockFunction = UInt64 (*)();
|
||||
|
||||
extern NAZARA_CORE_API ClockFunction GetElapsedMicroseconds;
|
||||
extern NAZARA_CORE_API ClockFunction GetElapsedMilliseconds;
|
||||
using HighPrecisionClock = Clock<true>;
|
||||
using MillisecondClock = Clock<false>;
|
||||
}
|
||||
|
||||
#include <Nazara/Core/Clock.inl>
|
||||
|
||||
#endif // NAZARA_CORE_CLOCK_HPP
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \class Nz::Clock
|
||||
* \brief Utility class that measure the elapsed time
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Clock object
|
||||
*
|
||||
* \param startingValue The starting time value, in microseconds
|
||||
* \param paused The clock pause state
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
Clock<HighPrecision>::Clock(Time startingValue, bool paused) :
|
||||
m_elapsedTime(startingValue),
|
||||
m_refTime(Now()),
|
||||
m_paused(paused)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the elapsed time
|
||||
* \return Duration elapsed
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
Time Clock<HighPrecision>::GetElapsedTime() const
|
||||
{
|
||||
Time elapsedNanoseconds = m_elapsedTime;
|
||||
if (!m_paused)
|
||||
elapsedNanoseconds += Now() - m_refTime;
|
||||
|
||||
return elapsedNanoseconds;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the current pause state of the clock
|
||||
* \return Boolean indicating if the clock is currently paused
|
||||
*
|
||||
* \see Pause, Unpause
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
bool Clock<HighPrecision>::IsPaused() const
|
||||
{
|
||||
return m_paused;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pause the clock
|
||||
*
|
||||
* Pauses the clock, making the time retrieving functions to always return the value at the time the clock was paused
|
||||
* This has no effect if the clock is already paused
|
||||
*
|
||||
* \see IsPaused, Unpause
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
void Clock<HighPrecision>::Pause()
|
||||
{
|
||||
if (!m_paused)
|
||||
{
|
||||
m_elapsedTime += Now() - m_refTime;
|
||||
m_paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Restart the clock
|
||||
* \return Time elapsed since creation or last restart call
|
||||
*
|
||||
* Restarts the clock, putting its time counter back to the starting value
|
||||
* It also compute the elapsed microseconds since the last Restart() call without any time loss (a problem that the combination of GetElapsedTime and Restart have).
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
Time Clock<HighPrecision>::Restart(Time startingValue, bool paused)
|
||||
{
|
||||
Time now = Now();
|
||||
|
||||
Time elapsedTime = m_elapsedTime;
|
||||
if (!m_paused)
|
||||
elapsedTime += now - m_refTime;
|
||||
|
||||
m_elapsedTime = startingValue;
|
||||
m_refTime = now;
|
||||
m_paused = paused;
|
||||
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Restart the clock if more than time elapsed
|
||||
* \return If more than time elapsed since creation or last restart call
|
||||
*
|
||||
* Restarts the clock, putting its time counter back to zero
|
||||
* This function allows to check the elapsed time of a clock and restart it if over some value in a single call, preventing some loss between GetElapsedTime and Restart
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
std::optional<Time> Clock<HighPrecision>::RestartIfOver(Time time)
|
||||
{
|
||||
Time now = Now();
|
||||
|
||||
Time elapsedTime = m_elapsedTime;
|
||||
if (!m_paused)
|
||||
elapsedTime += now - m_refTime;
|
||||
|
||||
if (elapsedTime < time)
|
||||
return std::nullopt;
|
||||
|
||||
m_elapsedTime = Time::Zero();
|
||||
m_refTime = now;
|
||||
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Unpause the clock
|
||||
*
|
||||
* Unpauses the clock, making the clock continue to measure the time
|
||||
* This has no effect if the clock is already unpaused
|
||||
*
|
||||
* \see IsPaused, Unpause
|
||||
*/
|
||||
template<bool HighPrecision>
|
||||
void Clock<HighPrecision>::Unpause()
|
||||
{
|
||||
if (m_paused)
|
||||
{
|
||||
m_refTime = Now();
|
||||
m_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool HighPrecision>
|
||||
Time Clock<HighPrecision>::Now()
|
||||
{
|
||||
if constexpr (HighPrecision)
|
||||
return GetElapsedNanoseconds();
|
||||
else
|
||||
return GetElapsedMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_CORE_COMPONENTS_LIFETIMECOMPONENT_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -15,14 +16,14 @@ namespace Nz
|
|||
class LifetimeComponent
|
||||
{
|
||||
public:
|
||||
inline LifetimeComponent(float lifetime);
|
||||
inline LifetimeComponent(Time lifetime);
|
||||
LifetimeComponent(const LifetimeComponent&) = default;
|
||||
LifetimeComponent(LifetimeComponent&&) = default;
|
||||
~LifetimeComponent() = default;
|
||||
|
||||
inline void DecreaseLifetime(float elapsedTime);
|
||||
inline void DecreaseLifetime(Time elapsedTime);
|
||||
|
||||
inline float GetRemainingLifeTime() const;
|
||||
inline Time GetRemainingLifeTime() const;
|
||||
|
||||
inline bool IsAlive() const;
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ namespace Nz
|
|||
LifetimeComponent& operator=(LifetimeComponent&&) = default;
|
||||
|
||||
private:
|
||||
float m_remainingLifetime;
|
||||
Time m_remainingLifetime;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,24 +7,24 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline LifetimeComponent::LifetimeComponent(float lifetime) :
|
||||
inline LifetimeComponent::LifetimeComponent(Time lifetime) :
|
||||
m_remainingLifetime(lifetime)
|
||||
{
|
||||
}
|
||||
|
||||
inline void LifetimeComponent::DecreaseLifetime(float elapsedTime)
|
||||
inline void LifetimeComponent::DecreaseLifetime(Time elapsedTime)
|
||||
{
|
||||
m_remainingLifetime -= elapsedTime;
|
||||
}
|
||||
|
||||
inline float LifetimeComponent::GetRemainingLifeTime() const
|
||||
inline Time LifetimeComponent::GetRemainingLifeTime() const
|
||||
{
|
||||
return m_remainingLifetime;
|
||||
}
|
||||
|
||||
inline bool LifetimeComponent::IsAlive() const
|
||||
{
|
||||
return m_remainingLifetime >= 0.f;
|
||||
return m_remainingLifetime >= Time::Zero();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Utils/TypeList.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ namespace Nz
|
|||
LifetimeSystem(LifetimeSystem&&) = delete;
|
||||
~LifetimeSystem() = default;
|
||||
|
||||
void Update(float elapsedTime);
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
LifetimeSystem& operator=(const LifetimeSystem&) = delete;
|
||||
LifetimeSystem& operator=(LifetimeSystem&&) = delete;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace Nz
|
|||
template<typename T> T& GetSystem() const;
|
||||
|
||||
void Update();
|
||||
void Update(float elapsedTime);
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
SystemGraph& operator=(const SystemGraph&) = delete;
|
||||
SystemGraph& operator=(SystemGraph&&) = delete;
|
||||
|
|
@ -41,7 +41,7 @@ namespace Nz
|
|||
{
|
||||
virtual ~NodeBase();
|
||||
|
||||
virtual void Update(float elapsedTime) = 0;
|
||||
virtual void Update(Time elapsedTime) = 0;
|
||||
|
||||
Int64 executionOrder;
|
||||
};
|
||||
|
|
@ -51,7 +51,7 @@ namespace Nz
|
|||
{
|
||||
template<typename... Args> Node(Args&&... args);
|
||||
|
||||
void Update(float elapsedTime) override;
|
||||
void Update(Time elapsedTime) override;
|
||||
|
||||
T system;
|
||||
};
|
||||
|
|
@ -60,7 +60,7 @@ namespace Nz
|
|||
std::vector<NodeBase*> m_orderedNodes;
|
||||
std::vector<std::unique_ptr<NodeBase>> m_nodes;
|
||||
entt::registry& m_registry;
|
||||
Nz::Clock m_clock;
|
||||
Nz::HighPrecisionClock m_clock;
|
||||
bool m_systemOrderUpdated;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace Nz
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
void SystemGraph::Node<T>::Update(float elapsedTime)
|
||||
void SystemGraph::Node<T>::Update(Time elapsedTime)
|
||||
{
|
||||
system.Update(elapsedTime);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CORE_TIME_HPP
|
||||
#define NAZARA_CORE_TIME_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <chrono>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct SerializationContext;
|
||||
|
||||
class Time
|
||||
{
|
||||
public:
|
||||
Time() = default;
|
||||
Time(const Time&) = default;
|
||||
Time(Time&&) = default;
|
||||
~Time() = default;
|
||||
|
||||
template<typename T> constexpr T AsDuration() const;
|
||||
template<typename T = float> constexpr T AsSeconds() const;
|
||||
constexpr Int64 AsMicroseconds() const;
|
||||
constexpr Int64 AsMilliseconds() const;
|
||||
constexpr Int64 AsNanoseconds() const;
|
||||
|
||||
Time& operator=(const Time&) = default;
|
||||
Time& operator=(Time&&) = default;
|
||||
|
||||
constexpr Time& operator+=(Time time);
|
||||
constexpr Time& operator-=(Time time);
|
||||
constexpr Time& operator*=(Time time);
|
||||
constexpr Time& operator/=(Time time);
|
||||
constexpr Time& operator%=(Time time);
|
||||
|
||||
constexpr explicit operator Int64() const;
|
||||
|
||||
template<class Rep, class Period> static constexpr Time FromDuration(const std::chrono::duration<Rep, Period>& d);
|
||||
static constexpr Time Microsecond();
|
||||
static constexpr Time Microseconds(Int64 microseconds);
|
||||
static constexpr Time Millisecond();
|
||||
static constexpr Time Milliseconds(Int64 milliseconds);
|
||||
static constexpr Time Nanosecond();
|
||||
static constexpr Time Nanoseconds(Int64 nanoseconds);
|
||||
static constexpr Time Second();
|
||||
template<typename T> static constexpr Time Seconds(T seconds);
|
||||
static constexpr Time TickDuration(Int64 tickRate);
|
||||
static constexpr Time Zero();
|
||||
|
||||
// External part
|
||||
|
||||
friend constexpr Time operator+(Time time);
|
||||
friend constexpr Time operator-(Time time);
|
||||
|
||||
friend constexpr Time operator+(Time lhs, Time rhs);
|
||||
friend constexpr Time operator-(Time lhs, Time rhs);
|
||||
friend constexpr Time operator*(Time lhs, Time rhs);
|
||||
friend constexpr Time operator/(Time lhs, Time rhs);
|
||||
friend constexpr Time operator%(Time lhs, Time rhs);
|
||||
|
||||
friend constexpr bool operator==(Time lhs, Time rhs);
|
||||
friend constexpr bool operator!=(Time lhs, Time rhs);
|
||||
friend constexpr bool operator<(Time lhs, Time rhs);
|
||||
friend constexpr bool operator<=(Time lhs, Time rhs);
|
||||
friend constexpr bool operator>(Time lhs, Time rhs);
|
||||
friend constexpr bool operator>=(Time lhs, Time rhs);
|
||||
|
||||
friend inline std::ostream& operator<<(std::ostream& out, Time time);
|
||||
|
||||
friend inline bool Serialize(SerializationContext& context, Time time, TypeTag<Time>);
|
||||
friend inline bool Unserialize(SerializationContext& context, Time* time, TypeTag<Time>);
|
||||
|
||||
private:
|
||||
constexpr explicit Time(Int64 nanoseconds);
|
||||
|
||||
Int64 m_nanoseconds;
|
||||
};
|
||||
|
||||
namespace Literals
|
||||
{
|
||||
constexpr Time operator ""_ms(unsigned long long milliseconds);
|
||||
constexpr Time operator ""_ns(unsigned long long nanoseconds);
|
||||
constexpr Time operator ""_us(unsigned long long microseconds);
|
||||
constexpr Time operator ""_s(long double seconds);
|
||||
constexpr Time operator ""_s(unsigned long long seconds);
|
||||
}
|
||||
|
||||
using GetElapsedTimeFunction = Time(*)();
|
||||
|
||||
extern NAZARA_CORE_API GetElapsedTimeFunction GetElapsedMilliseconds;
|
||||
extern NAZARA_CORE_API GetElapsedTimeFunction GetElapsedNanoseconds;
|
||||
}
|
||||
|
||||
#include <Nazara/Core/Time.inl>
|
||||
|
||||
#endif // NAZARA_CORE_TIME_HPP
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
constexpr Time::Time(Int64 microseconds) :
|
||||
m_nanoseconds(microseconds)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr T Time::AsDuration() const
|
||||
{
|
||||
if constexpr (std::is_same_v<T, std::chrono::nanoseconds>)
|
||||
return std::chrono::nanoseconds(m_nanoseconds); //< make sure it's a no-op
|
||||
else
|
||||
return std::chrono::duration_cast<T>(std::chrono::nanoseconds(m_nanoseconds));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr T Time::AsSeconds() const
|
||||
{
|
||||
static_assert(std::is_floating_point_v<T>);
|
||||
// TODO: Improve precision
|
||||
return AsMicroseconds() / T(1'000'000.0) + (m_nanoseconds % 1000) / T(1'000'000'000);
|
||||
}
|
||||
|
||||
constexpr Int64 Time::AsMicroseconds() const
|
||||
{
|
||||
return m_nanoseconds / 1'000;
|
||||
}
|
||||
|
||||
constexpr Int64 Time::AsMilliseconds() const
|
||||
{
|
||||
return m_nanoseconds / 1'000'000;
|
||||
}
|
||||
|
||||
constexpr Int64 Time::AsNanoseconds() const
|
||||
{
|
||||
return m_nanoseconds;
|
||||
}
|
||||
|
||||
constexpr Time& Time::operator+=(Time time)
|
||||
{
|
||||
m_nanoseconds += time.m_nanoseconds;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Time& Time::operator-=(Time time)
|
||||
{
|
||||
m_nanoseconds -= time.m_nanoseconds;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Time& Time::operator*=(Time time)
|
||||
{
|
||||
m_nanoseconds *= time.m_nanoseconds;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Time& Time::operator/=(Time time)
|
||||
{
|
||||
m_nanoseconds /= time.m_nanoseconds;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Time& Time::operator%=(Time time)
|
||||
{
|
||||
m_nanoseconds %= time.m_nanoseconds;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Time::operator Int64() const
|
||||
{
|
||||
return m_nanoseconds;
|
||||
}
|
||||
|
||||
template<class Rep, class Period>
|
||||
constexpr Time Time::FromDuration(const std::chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
return Nanoseconds(std::chrono::duration_cast<std::chrono::nanoseconds>(d).count());
|
||||
}
|
||||
|
||||
constexpr Time Time::Microsecond()
|
||||
{
|
||||
return Time(1'000);
|
||||
}
|
||||
|
||||
constexpr Time Time::Microseconds(Int64 microseconds)
|
||||
{
|
||||
return Time(microseconds * 1'000);
|
||||
}
|
||||
|
||||
constexpr Time Time::Millisecond()
|
||||
{
|
||||
return Time(1'000'000);
|
||||
}
|
||||
|
||||
constexpr Time Time::Milliseconds(Int64 milliseconds)
|
||||
{
|
||||
return Time(milliseconds * 1'000'000);
|
||||
}
|
||||
|
||||
constexpr Time Time::Nanosecond()
|
||||
{
|
||||
return Time(1);
|
||||
}
|
||||
|
||||
constexpr Time Time::Nanoseconds(Int64 nanoseconds)
|
||||
{
|
||||
return Time(nanoseconds);
|
||||
}
|
||||
|
||||
constexpr Time Time::Second()
|
||||
{
|
||||
return Time(1'000'000'000ull);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Time Time::Seconds(T seconds)
|
||||
{
|
||||
if constexpr (std::is_floating_point_v<T>)
|
||||
return Nanoseconds(static_cast<UInt64>(seconds * T(1'000'000'000.0)));
|
||||
else if constexpr (std::is_integral_v<T>)
|
||||
return Nanoseconds(seconds * 1'000'000'000LL);
|
||||
else
|
||||
static_assert(AlwaysFalse<T>(), "not an arithmetic type");
|
||||
}
|
||||
|
||||
constexpr Time Time::TickDuration(Int64 tickRate)
|
||||
{
|
||||
return Second() / Nanoseconds(tickRate);
|
||||
}
|
||||
|
||||
constexpr Time Time::Zero()
|
||||
{
|
||||
return Time(0);
|
||||
}
|
||||
|
||||
constexpr Time operator+(Time time)
|
||||
{
|
||||
return time;
|
||||
}
|
||||
|
||||
constexpr Time operator-(Time time)
|
||||
{
|
||||
return Time(-time.m_nanoseconds);
|
||||
}
|
||||
|
||||
constexpr Time operator+(Time lhs, Time rhs)
|
||||
{
|
||||
return Time(lhs.m_nanoseconds + rhs.m_nanoseconds);
|
||||
}
|
||||
|
||||
constexpr Time operator-(Time lhs, Time rhs)
|
||||
{
|
||||
return Time(lhs.m_nanoseconds - rhs.m_nanoseconds);
|
||||
}
|
||||
|
||||
constexpr Time operator*(Time lhs, Time rhs)
|
||||
{
|
||||
return Time(lhs.m_nanoseconds * rhs.m_nanoseconds);
|
||||
}
|
||||
|
||||
constexpr Time operator/(Time lhs, Time rhs)
|
||||
{
|
||||
return Time(lhs.m_nanoseconds / rhs.m_nanoseconds);
|
||||
}
|
||||
|
||||
constexpr Time operator%(Time lhs, Time rhs)
|
||||
{
|
||||
return Time(lhs.m_nanoseconds % rhs.m_nanoseconds);
|
||||
}
|
||||
|
||||
constexpr bool operator==(Time lhs, Time rhs)
|
||||
{
|
||||
return lhs.m_nanoseconds == rhs.m_nanoseconds;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(Time lhs, Time rhs)
|
||||
{
|
||||
return lhs.m_nanoseconds != rhs.m_nanoseconds;
|
||||
}
|
||||
|
||||
constexpr bool operator<(Time lhs, Time rhs)
|
||||
{
|
||||
return lhs.m_nanoseconds < rhs.m_nanoseconds;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(Time lhs, Time rhs)
|
||||
{
|
||||
return lhs.m_nanoseconds <= rhs.m_nanoseconds;
|
||||
}
|
||||
|
||||
constexpr bool operator>(Time lhs, Time rhs)
|
||||
{
|
||||
return lhs.m_nanoseconds > rhs.m_nanoseconds;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(Time lhs, Time rhs)
|
||||
{
|
||||
return lhs.m_nanoseconds >= rhs.m_nanoseconds;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, Time time)
|
||||
{
|
||||
if (time > Time::Second())
|
||||
return out << time.AsSeconds<double>() << "s";
|
||||
else
|
||||
{
|
||||
Int64 ns = time.AsNanoseconds();
|
||||
if (time > Time::Millisecond())
|
||||
return out << ns / 1'000'000.0 << "ms";
|
||||
else if (time > Time::Microsecond())
|
||||
return out << ns / 1'000.0 << "us";
|
||||
else
|
||||
return out << ns << "ns";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Serialize(SerializationContext& context, Time time, TypeTag<Time>)
|
||||
{
|
||||
if (!Serialize(context, time.m_nanoseconds))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Unserialize(SerializationContext& context, Time* time, TypeTag<Time>)
|
||||
{
|
||||
if (!Unserialize(context, &time->m_nanoseconds))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace Literals
|
||||
{
|
||||
constexpr Time operator ""_ms(unsigned long long milliseconds)
|
||||
{
|
||||
return Time::Milliseconds(static_cast<Int64>(milliseconds));
|
||||
}
|
||||
|
||||
constexpr Time operator ""_ns(unsigned long long nanoseconds)
|
||||
{
|
||||
return Time::Nanoseconds(static_cast<Int64>(nanoseconds));
|
||||
}
|
||||
|
||||
constexpr Time operator ""_us(unsigned long long microseconds)
|
||||
{
|
||||
return Time::Microseconds(static_cast<Int64>(microseconds));
|
||||
}
|
||||
|
||||
constexpr Time operator ""_s(long double milliseconds)
|
||||
{
|
||||
return Time::Seconds(milliseconds);
|
||||
}
|
||||
|
||||
constexpr Time operator ""_s(unsigned long long milliseconds)
|
||||
{
|
||||
return Time::Seconds(milliseconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_GRAPHICS_SYSTEMS_RENDERSYSTEM_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||
|
|
@ -45,7 +46,7 @@ namespace Nz
|
|||
inline FramePipeline& GetFramePipeline();
|
||||
inline const FramePipeline& GetFramePipeline() const;
|
||||
|
||||
void Update(float elapsedTime);
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
RenderSystem& operator=(const RenderSystem&) = delete;
|
||||
RenderSystem& operator=(RenderSystem&&) = delete;
|
||||
|
|
|
|||
|
|
@ -111,8 +111,8 @@ namespace Nz
|
|||
|
||||
inline void ENetHost::UpdateServiceTime()
|
||||
{
|
||||
// Compute service time as microseconds for extra precision
|
||||
m_serviceTime = static_cast<UInt32>(GetElapsedMicroseconds() / 1000);
|
||||
// Use high precision clock for extra precision
|
||||
m_serviceTime = static_cast<UInt32>(GetElapsedNanoseconds().AsMilliseconds());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
|
|
@ -59,7 +60,7 @@ namespace Nz
|
|||
cpSpace* GetHandle() const;
|
||||
std::size_t GetIterationCount() const;
|
||||
std::size_t GetMaxStepCount() const;
|
||||
float GetStepSize() const;
|
||||
Time GetStepSize() const;
|
||||
|
||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
|
||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, Nz::UInt32 collisionGroup, Nz::UInt32 categoryMask, Nz::UInt32 collisionMask, NearestQueryResult* result);
|
||||
|
|
@ -78,10 +79,10 @@ namespace Nz
|
|||
void SetGravity(const Vector2f& gravity);
|
||||
void SetIterationCount(std::size_t iterationCount);
|
||||
void SetMaxStepCount(std::size_t maxStepCount);
|
||||
void SetSleepTime(float sleepTime);
|
||||
void SetStepSize(float stepSize);
|
||||
void SetSleepTime(Time sleepTime);
|
||||
void SetStepSize(Time stepSize);
|
||||
|
||||
void Step(float timestep);
|
||||
void Step(Time timestep);
|
||||
|
||||
void UseSpatialHash(float cellSize, std::size_t entityCount);
|
||||
|
||||
|
|
@ -156,8 +157,8 @@ namespace Nz
|
|||
std::unordered_map<cpCollisionHandler*, std::unique_ptr<Callback>> m_callbacks;
|
||||
std::unordered_map<RigidBody2D*, PostStepContainer> m_rigidPostSteps;
|
||||
cpSpace* m_handle;
|
||||
float m_stepSize;
|
||||
float m_timestepAccumulator;
|
||||
Time m_stepSize;
|
||||
Time m_timestepAccumulator;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Physics2D/PhysWorld2D.hpp>
|
||||
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||
#include <Nazara/Utils/TypeList.hpp>
|
||||
|
|
@ -31,7 +32,7 @@ namespace Nz
|
|||
inline PhysWorld2D& GetPhysWorld();
|
||||
inline const PhysWorld2D& GetPhysWorld() const;
|
||||
|
||||
void Update(float elapsedTime);
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
Physics2DSystem& operator=(const Physics2DSystem&) = delete;
|
||||
Physics2DSystem& operator=(Physics2DSystem&&) = delete;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_PHYSICS3D_PHYSWORLD3D_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Math/Box.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Physics3D/Config.hpp>
|
||||
|
|
@ -44,12 +45,12 @@ namespace Nz
|
|||
NewtonWorld* GetHandle() const;
|
||||
int GetMaterial(const std::string& name);
|
||||
std::size_t GetMaxStepCount() const;
|
||||
float GetStepSize() const;
|
||||
Time GetStepSize() const;
|
||||
unsigned int GetThreadCount() const;
|
||||
|
||||
void SetGravity(const Vector3f& gravity);
|
||||
void SetMaxStepCount(std::size_t maxStepCount);
|
||||
void SetStepSize(float stepSize);
|
||||
void SetStepSize(Time stepSize);
|
||||
void SetThreadCount(unsigned int threadCount);
|
||||
|
||||
void SetMaterialCollisionCallback(int firstMaterial, int secondMaterial, AABBOverlapCallback aabbOverlapCallback, CollisionCallback collisionCallback);
|
||||
|
|
@ -59,7 +60,7 @@ namespace Nz
|
|||
void SetMaterialDefaultSoftness(int firstMaterial, int secondMaterial, float softness);
|
||||
void SetMaterialSurfaceThickness(int firstMaterial, int secondMaterial, float thickness);
|
||||
|
||||
void Step(float timestep);
|
||||
void Step(Time timestep);
|
||||
|
||||
PhysWorld3D& operator=(const PhysWorld3D&) = delete;
|
||||
PhysWorld3D& operator=(PhysWorld3D&&) noexcept;
|
||||
|
|
@ -79,8 +80,8 @@ namespace Nz
|
|||
std::size_t m_maxStepCount;
|
||||
MovablePtr<NewtonWorld> m_world;
|
||||
Vector3f m_gravity;
|
||||
float m_stepSize;
|
||||
float m_timestepAccumulator;
|
||||
Time m_stepSize;
|
||||
Time m_timestepAccumulator;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_PHYSICS3D_SYSTEMS_PHYSICS3DSYSTEM_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Physics3D/PhysWorld3D.hpp>
|
||||
#include <Nazara/Physics3D/Components/RigidBody3DComponent.hpp>
|
||||
#include <Nazara/Utils/TypeList.hpp>
|
||||
|
|
@ -31,7 +32,7 @@ namespace Nz
|
|||
inline PhysWorld3D& GetPhysWorld();
|
||||
inline const PhysWorld3D& GetPhysWorld() const;
|
||||
|
||||
void Update(float elapsedTime);
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
Physics3DSystem& operator=(const Physics3DSystem&) = delete;
|
||||
Physics3DSystem& operator=(Physics3DSystem&&) = delete;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace Nz
|
|||
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||
std::unique_ptr<RenderSurface> m_surface;
|
||||
std::unique_ptr<RenderWindowImpl> m_impl;
|
||||
Clock m_clock;
|
||||
MillisecondClock m_clock;
|
||||
RenderWindowParameters m_parameters;
|
||||
unsigned int m_framerateLimit;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_UTILITY_SYSTEMS_SKELETONSYSTEM_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ namespace Nz
|
|||
SkeletonSystem(SkeletonSystem&&) = delete;
|
||||
~SkeletonSystem();
|
||||
|
||||
void Update(float elapsedTime);
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
SkeletonSystem& operator=(const SkeletonSystem&) = delete;
|
||||
SkeletonSystem& operator=(SkeletonSystem&&) = delete;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ namespace Nz
|
|||
Vk::QueueHandle m_presentQueue;
|
||||
Vk::QueueHandle m_transferQueue;
|
||||
Vk::Swapchain m_swapchain;
|
||||
Clock m_clock;
|
||||
RenderWindow& m_owner;
|
||||
Vector2ui m_swapchainSize;
|
||||
VkFormat m_depthStencilFormat;
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ namespace Nz
|
|||
return m_format;
|
||||
}
|
||||
|
||||
UInt32 DummyAudioBuffer::GetDuration() const
|
||||
Time DummyAudioBuffer::GetDuration() const
|
||||
{
|
||||
return SafeCast<UInt32>((1000ULL * m_sampleCount / (GetChannelCount(m_format) * m_sampleRate)));
|
||||
return Time::Microseconds((1'000'000LL * m_sampleCount / (GetChannelCount(m_format) * m_sampleRate)));
|
||||
}
|
||||
|
||||
UInt64 DummyAudioBuffer::GetSampleCount() const
|
||||
|
|
|
|||
|
|
@ -39,6 +39,27 @@ namespace Nz
|
|||
return m_pitch;
|
||||
}
|
||||
|
||||
Time DummyAudioSource::GetPlayingOffset() const
|
||||
{
|
||||
if (m_status == SoundStatus::Stopped)
|
||||
return Time::Zero(); //< Always return 0 when stopped, to mimic OpenAL behavior
|
||||
|
||||
Time bufferTime = UpdateTime();
|
||||
|
||||
Time playingOffset = Time::Zero();
|
||||
// All processed buffers count
|
||||
for (const auto& processedBuffer : m_processedBuffers)
|
||||
playingOffset += processedBuffer->GetDuration();
|
||||
|
||||
if (!m_queuedBuffers.empty())
|
||||
{
|
||||
auto& frontBuffer = m_queuedBuffers.front();
|
||||
playingOffset += std::min(bufferTime, frontBuffer->GetDuration());
|
||||
}
|
||||
|
||||
return playingOffset;
|
||||
}
|
||||
|
||||
Vector3f DummyAudioSource::GetPosition() const
|
||||
{
|
||||
return m_position;
|
||||
|
|
@ -49,7 +70,7 @@ namespace Nz
|
|||
if (m_status == SoundStatus::Stopped)
|
||||
return 0; //< Always return 0 when stopped, to mimic OpenAL behavior
|
||||
|
||||
UInt64 bufferTime = UpdateTime();
|
||||
Time bufferTime = UpdateTime();
|
||||
|
||||
UInt64 sampleOffset = 0;
|
||||
// All processed buffers count in sample offset
|
||||
|
|
@ -59,7 +80,7 @@ namespace Nz
|
|||
if (!m_queuedBuffers.empty())
|
||||
{
|
||||
auto& frontBuffer = m_queuedBuffers.front();
|
||||
UInt64 bufferOffset = bufferTime * frontBuffer->GetSampleRate() / 1000;
|
||||
UInt64 bufferOffset = bufferTime.AsMicroseconds() * frontBuffer->GetSampleRate() / 1'000'000ll;
|
||||
UInt64 bufferDuration = frontBuffer->GetSampleCount() / GetChannelCount(frontBuffer->GetAudioFormat());
|
||||
|
||||
sampleOffset += std::min(bufferOffset, bufferDuration);
|
||||
|
|
@ -72,7 +93,7 @@ namespace Nz
|
|||
{
|
||||
OffsetWithLatency info;
|
||||
info.sampleOffset = GetSampleOffset() * 1000;
|
||||
info.sourceLatency = 0;
|
||||
info.sourceLatency = Time::Zero();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
@ -120,19 +141,19 @@ namespace Nz
|
|||
|
||||
void DummyAudioSource::Play()
|
||||
{
|
||||
if (m_status == SoundStatus::Paused)
|
||||
m_playClock.Unpause();
|
||||
else
|
||||
if (m_status != SoundStatus::Paused)
|
||||
{
|
||||
// playing or stopped, restart
|
||||
RequeueBuffers();
|
||||
|
||||
// special case, we are stopped but SetSampleOffset has been called
|
||||
if (m_status == SoundStatus::Stopped && m_playClock.GetMilliseconds() != 0)
|
||||
if (m_status == SoundStatus::Stopped && m_playClock.GetElapsedTime() != Time::Zero())
|
||||
m_playClock.Unpause();
|
||||
else
|
||||
m_playClock.Restart(); //< already playing or stopped, restart from beginning
|
||||
}
|
||||
else
|
||||
m_playClock.Unpause();
|
||||
|
||||
m_status = SoundStatus::Playing;
|
||||
}
|
||||
|
|
@ -161,6 +182,13 @@ namespace Nz
|
|||
m_pitch = pitch;
|
||||
}
|
||||
|
||||
void DummyAudioSource::SetPlayingOffset(Time offset)
|
||||
{
|
||||
// Next UpdateTime call will handle this properly
|
||||
RequeueBuffers();
|
||||
m_playClock.Restart(offset, m_playClock.IsPaused());
|
||||
}
|
||||
|
||||
void DummyAudioSource::SetPosition(const Vector3f& position)
|
||||
{
|
||||
m_position = position;
|
||||
|
|
@ -187,7 +215,7 @@ namespace Nz
|
|||
|
||||
if (!m_queuedBuffers.empty())
|
||||
{
|
||||
UInt64 timeOffset = 1'000'000ULL * offset / m_queuedBuffers.front()->GetSampleRate();
|
||||
Time timeOffset = Time::Microseconds(1'000'000ll * offset / m_queuedBuffers.front()->GetSampleRate());
|
||||
m_playClock.Restart(timeOffset, m_playClock.IsPaused());
|
||||
}
|
||||
else
|
||||
|
|
@ -206,7 +234,7 @@ namespace Nz
|
|||
|
||||
void DummyAudioSource::Stop()
|
||||
{
|
||||
m_playClock.Restart(0, true);
|
||||
m_playClock.Restart(Time::Zero(), true);
|
||||
m_status = SoundStatus::Stopped;
|
||||
}
|
||||
|
||||
|
|
@ -246,9 +274,10 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
UInt64 DummyAudioSource::UpdateTime() const
|
||||
Time DummyAudioSource::UpdateTime() const
|
||||
{
|
||||
UInt64 currentTime = m_playClock.GetMilliseconds();
|
||||
Time currentTime = m_playClock.GetElapsedTime();
|
||||
bool isPaused = m_playClock.IsPaused();
|
||||
|
||||
while (!m_queuedBuffers.empty() && currentTime >= m_queuedBuffers.front()->GetDuration())
|
||||
{
|
||||
|
|
@ -278,10 +307,14 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = SoundStatus::Stopped;
|
||||
currentTime = Time::Zero();
|
||||
isPaused = m_playClock.IsPaused();
|
||||
}
|
||||
}
|
||||
|
||||
m_playClock.Restart(currentTime * 1000, m_playClock.IsPaused()); //< Adjust time
|
||||
m_playClock.Restart(currentTime, isPaused); //< Adjust time
|
||||
return currentTime;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ namespace Nz
|
|||
drwav_uninit(&m_decoder);
|
||||
}
|
||||
|
||||
UInt32 GetDuration() const override
|
||||
Time GetDuration() const override
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ namespace Nz
|
|||
|
||||
m_format = *formatOpt;
|
||||
|
||||
m_duration = static_cast<UInt32>(1000ULL * m_decoder.totalPCMFrameCount / m_decoder.sampleRate);
|
||||
m_duration = Time::Microseconds(1'000'000LL * m_decoder.totalPCMFrameCount / m_decoder.sampleRate);
|
||||
m_sampleCount = m_decoder.totalPCMFrameCount * m_decoder.channels;
|
||||
m_sampleRate = m_decoder.sampleRate;
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ namespace Nz
|
|||
std::vector<Int16> m_mixBuffer;
|
||||
AudioFormat m_format;
|
||||
drwav m_decoder;
|
||||
UInt32 m_duration;
|
||||
Time m_duration;
|
||||
UInt32 m_sampleRate;
|
||||
UInt64 m_readSampleCount;
|
||||
UInt64 m_sampleCount;
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
UInt32 GetDuration() const override
|
||||
Time GetDuration() const override
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
|
@ -333,7 +333,7 @@ namespace Nz
|
|||
m_sampleCount = frameCount * m_channelCount;
|
||||
m_sampleRate = meta->data.stream_info.sample_rate;
|
||||
|
||||
m_duration = UInt32(1000ULL * frameCount / m_sampleRate);
|
||||
m_duration = Time::Microseconds(1'000'000LL * frameCount / m_sampleRate);
|
||||
};
|
||||
|
||||
FLAC__StreamDecoderInitStatus status = FLAC__stream_decoder_init_stream(decoder, &FlacReadCallback, &FlacSeekCallback, &FlacTellCallback, &FlacLengthCallback, &FlacEofCallback, &WriteCallback, &MetadataCallback, &ErrorCallback, &m_userData);
|
||||
|
|
@ -477,8 +477,8 @@ namespace Nz
|
|||
FLAC__StreamDecoder* m_decoder;
|
||||
AudioFormat m_format;
|
||||
FlacUserdata m_userData;
|
||||
Time m_duration;
|
||||
UInt32 m_channelCount;
|
||||
UInt32 m_duration;
|
||||
UInt32 m_sampleRate;
|
||||
UInt64 m_readSampleCount;
|
||||
UInt64 m_sampleCount;
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ namespace Nz
|
|||
ov_clear(&m_decoder);
|
||||
}
|
||||
|
||||
UInt32 GetDuration() const override
|
||||
Time GetDuration() const override
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
|
@ -258,7 +258,7 @@ namespace Nz
|
|||
UInt64 frameCount = UInt64(ov_pcm_total(&m_decoder, -1));
|
||||
|
||||
m_channelCount = info->channels;
|
||||
m_duration = UInt32(1000ULL * frameCount / info->rate);
|
||||
m_duration = Time::Microseconds(1'000'000LL * frameCount / info->rate);
|
||||
m_sampleCount = UInt64(frameCount * info->channels);
|
||||
m_sampleRate = info->rate;
|
||||
|
||||
|
|
@ -319,8 +319,8 @@ namespace Nz
|
|||
std::vector<Int16> m_mixBuffer;
|
||||
AudioFormat m_format;
|
||||
OggVorbis_File m_decoder;
|
||||
Time m_duration;
|
||||
UInt32 m_channelCount;
|
||||
UInt32 m_duration;
|
||||
UInt32 m_sampleRate;
|
||||
UInt64 m_sampleCount;
|
||||
bool m_mixToMono;
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ namespace Nz
|
|||
mp3dec_ex_close(&m_decoder);
|
||||
}
|
||||
|
||||
UInt32 GetDuration() const override
|
||||
Time GetDuration() const override
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ namespace Nz
|
|||
|
||||
m_format = *formatOpt;
|
||||
|
||||
m_duration = static_cast<UInt32>(1000ULL * m_decoder.samples / (m_decoder.info.hz * m_decoder.info.channels));
|
||||
m_duration = Time::Microseconds(1'000'000LL * m_decoder.samples / (m_decoder.info.hz * m_decoder.info.channels));
|
||||
m_sampleCount = m_decoder.samples;
|
||||
m_sampleRate = m_decoder.info.hz;
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ namespace Nz
|
|||
AudioFormat m_format;
|
||||
mp3dec_ex_t m_decoder;
|
||||
mp3dec_io_t m_io;
|
||||
UInt32 m_duration;
|
||||
Time m_duration;
|
||||
UInt32 m_sampleRate;
|
||||
UInt64 m_readSampleCount;
|
||||
UInt64 m_sampleCount;
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace Nz
|
|||
m_chunkSamples.resize(GetChannelCount(format) * m_sampleRate); // One second of samples
|
||||
m_stream = std::move(soundStream);
|
||||
|
||||
SetPlayingOffset(0);
|
||||
SeekToSampleOffset(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ namespace Nz
|
|||
*
|
||||
* \remark Music must be valid when calling this function
|
||||
*/
|
||||
UInt32 Music::GetDuration() const
|
||||
Time Music::GetDuration() const
|
||||
{
|
||||
NazaraAssert(m_stream, "Music not created");
|
||||
|
||||
|
|
@ -123,30 +123,30 @@ namespace Nz
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current offset in the music
|
||||
* \return Offset in milliseconds (works with entire seconds)
|
||||
*
|
||||
* \remark Music must be valid when calling this function
|
||||
* \brief Gets the current playing offset of the music
|
||||
* \return Time offset
|
||||
*/
|
||||
UInt32 Music::GetPlayingOffset() const
|
||||
Time Music::GetPlayingOffset() const
|
||||
{
|
||||
NazaraAssert(m_stream, "Music not created");
|
||||
|
||||
if (!m_streaming)
|
||||
return 0;
|
||||
return Time::Zero();
|
||||
|
||||
// Prevent music thread from enqueuing new buffers while we're getting the count
|
||||
std::lock_guard<std::recursive_mutex> lock(m_sourceLock);
|
||||
|
||||
UInt32 sampleOffset = m_source->GetSampleOffset();
|
||||
UInt32 playingOffset = SafeCast<UInt32>((1000ULL * (sampleOffset + (m_processedSamples / GetChannelCount(m_stream->GetFormat())))) / m_sampleRate);
|
||||
UInt32 duration = m_stream->GetDuration();
|
||||
if (playingOffset > duration)
|
||||
Time playingOffset = m_source->GetPlayingOffset();
|
||||
Time processedTime = Time::Microseconds(1'000'000ll * m_processedSamples / (GetChannelCount(m_stream->GetFormat()) * m_sampleRate));
|
||||
playingOffset += processedTime;
|
||||
|
||||
Time sampleCount = m_stream->GetDuration();
|
||||
if (playingOffset > sampleCount)
|
||||
{
|
||||
if (m_looping)
|
||||
playingOffset %= duration;
|
||||
playingOffset %= sampleCount;
|
||||
else
|
||||
playingOffset = 0; //< stopped
|
||||
playingOffset = Time::Zero(); //< stopped
|
||||
}
|
||||
|
||||
return playingOffset;
|
||||
|
|
@ -165,6 +165,33 @@ namespace Nz
|
|||
return m_stream->GetSampleCount();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current offset in the music
|
||||
* \return Offset in samples
|
||||
*/
|
||||
UInt64 Music::GetSampleOffset() const
|
||||
{
|
||||
NazaraAssert(m_stream, "Music not created");
|
||||
|
||||
if (!m_streaming)
|
||||
return 0;
|
||||
|
||||
// Prevent music thread from enqueuing new buffers while we're getting the count
|
||||
std::lock_guard<std::recursive_mutex> lock(m_sourceLock);
|
||||
|
||||
UInt64 sampleOffset = m_processedSamples + m_source->GetSampleOffset();
|
||||
UInt64 sampleCount = m_stream->GetSampleCount();
|
||||
if (sampleOffset > sampleCount)
|
||||
{
|
||||
if (m_looping)
|
||||
sampleOffset %= sampleCount;
|
||||
else
|
||||
sampleOffset = 0; //< stopped
|
||||
}
|
||||
|
||||
return sampleOffset;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the rates of sample in the music
|
||||
* \return Rate of sample in Hertz (Hz)
|
||||
|
|
@ -296,7 +323,7 @@ namespace Nz
|
|||
switch (GetStatus())
|
||||
{
|
||||
case SoundStatus::Playing:
|
||||
SetPlayingOffset(0);
|
||||
SeekToSampleOffset(0);
|
||||
break;
|
||||
|
||||
case SoundStatus::Paused:
|
||||
|
|
@ -325,11 +352,11 @@ namespace Nz
|
|||
*
|
||||
* If the music is not playing, this sets the playing offset for the next Play call
|
||||
*
|
||||
* \param offset The offset in milliseconds
|
||||
* \param offset The offset in samples
|
||||
*
|
||||
* \remark Music must be valid when calling this function
|
||||
*/
|
||||
void Music::SetPlayingOffset(UInt32 offset)
|
||||
void Music::SeekToSampleOffset(UInt64 offset)
|
||||
{
|
||||
NazaraAssert(m_stream, "Music not created");
|
||||
|
||||
|
|
@ -339,7 +366,7 @@ namespace Nz
|
|||
if (isPlaying)
|
||||
StopThread();
|
||||
|
||||
UInt64 sampleOffset = UInt64(offset) * m_sampleRate * GetChannelCount(m_stream->GetFormat()) / 1000ULL;
|
||||
UInt64 sampleOffset = offset * GetChannelCount(m_stream->GetFormat());
|
||||
|
||||
m_processedSamples = sampleOffset;
|
||||
m_streamOffset = sampleOffset;
|
||||
|
|
@ -356,7 +383,7 @@ namespace Nz
|
|||
void Music::Stop()
|
||||
{
|
||||
StopThread();
|
||||
SetPlayingOffset(0);
|
||||
SeekToSampleOffset(0);
|
||||
}
|
||||
|
||||
bool Music::FillAndQueueBuffer(std::shared_ptr<AudioBuffer> buffer)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,29 @@ namespace Nz
|
|||
return pitch;
|
||||
}
|
||||
|
||||
Time OpenALSource::GetPlayingOffset() const
|
||||
{
|
||||
GetDevice().MakeContextCurrent();
|
||||
|
||||
#ifdef AL_SOFT_source_latency
|
||||
if (GetDevice().IsExtensionSupported(OpenALExtension::SourceLatency))
|
||||
{
|
||||
// alGetSourcedvSOFT has extra precision thanks to double
|
||||
ALdouble playingOffset;
|
||||
m_library.alGetSourcedvSOFT(m_sourceId, AL_SEC_OFFSET, &playingOffset);
|
||||
|
||||
return Time::Seconds(playingOffset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ALfloat playingOffset;
|
||||
m_library.alGetSourcefv(m_sourceId, AL_SEC_OFFSET, &playingOffset);
|
||||
|
||||
return Time::Seconds(playingOffset);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3f OpenALSource::GetPosition() const
|
||||
{
|
||||
GetDevice().MakeContextCurrent();
|
||||
|
|
@ -94,14 +117,14 @@ namespace Nz
|
|||
m_library.alGetSourcei64vSOFT(m_sourceId, AL_SAMPLE_OFFSET_LATENCY_SOFT, values.data());
|
||||
|
||||
offsetWithLatency.sampleOffset = ((values[0] & 0xFFFFFFFF00000000) >> 32) * 1'000;
|
||||
offsetWithLatency.sourceLatency = values[1] / 1'000;
|
||||
offsetWithLatency.sourceLatency = Time::Nanoseconds(values[1] / 1'000);
|
||||
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
offsetWithLatency.sampleOffset = GetSampleOffset() * 1'000;
|
||||
offsetWithLatency.sourceLatency = 0;
|
||||
offsetWithLatency.sourceLatency = Time::Zero();
|
||||
}
|
||||
|
||||
return offsetWithLatency;
|
||||
|
|
@ -239,6 +262,19 @@ namespace Nz
|
|||
m_library.alSourcef(m_sourceId, AL_PITCH, pitch);
|
||||
}
|
||||
|
||||
void OpenALSource::SetPlayingOffset(Time offset)
|
||||
{
|
||||
GetDevice().MakeContextCurrent();
|
||||
|
||||
#ifdef AL_SOFT_source_latency
|
||||
if (GetDevice().IsExtensionSupported(OpenALExtension::SourceLatency))
|
||||
// alGetSourcedvSOFT has extra precision thanks to double
|
||||
m_library.alSourcedSOFT(m_sourceId, AL_SEC_OFFSET, offset.AsSeconds<ALdouble>());
|
||||
else
|
||||
#endif
|
||||
m_library.alSourcef(m_sourceId, AL_SEC_OFFSET, offset.AsSeconds<ALfloat>());
|
||||
}
|
||||
|
||||
void OpenALSource::SetPosition(const Vector3f& position)
|
||||
{
|
||||
GetDevice().MakeContextCurrent();
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ namespace Nz
|
|||
*
|
||||
* \remark Produces a NazaraError if there is no buffer
|
||||
*/
|
||||
UInt32 Sound::GetDuration() const
|
||||
Time Sound::GetDuration() const
|
||||
{
|
||||
NazaraAssert(m_buffer, "Invalid sound buffer");
|
||||
|
||||
|
|
@ -80,13 +80,30 @@ namespace Nz
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current offset in the sound
|
||||
* \return Offset in milliseconds (works with entire seconds)
|
||||
* \brief Gets the current playing offset of the sound
|
||||
* \return Offset
|
||||
*/
|
||||
UInt32 Sound::GetPlayingOffset() const
|
||||
Time Sound::GetPlayingOffset() const
|
||||
{
|
||||
UInt32 sampleCount = m_source->GetSampleOffset();
|
||||
return SafeCast<UInt32>(1000ULL * sampleCount / m_buffer->GetSampleRate());
|
||||
return m_source->GetPlayingOffset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the current sample offset of the sound
|
||||
* \return Offset
|
||||
*/
|
||||
UInt64 Sound::GetSampleOffset() const
|
||||
{
|
||||
return m_source->GetSampleOffset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the sample rate of the sound
|
||||
* \return Offset
|
||||
*/
|
||||
UInt32 Sound::GetSampleRate() const
|
||||
{
|
||||
return m_buffer->GetSampleRate();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -220,19 +237,17 @@ namespace Nz
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the playing offset for the sound
|
||||
* \brief Sets the source to a sample offset
|
||||
*
|
||||
* \param offset Offset in the sound in milliseconds
|
||||
* \param offset Sample offset
|
||||
*/
|
||||
void Sound::SetPlayingOffset(UInt32 offset)
|
||||
void Sound::SeekToSampleOffset(UInt64 offset)
|
||||
{
|
||||
m_source->SetSampleOffset(SafeCast<UInt32>(UInt64(offset) * m_buffer->GetSampleRate() / 1000));
|
||||
m_source->SetSampleOffset(SafeCast<UInt32>(offset));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Stops the sound
|
||||
*
|
||||
* \remark This is one of the only function that can be called on a moved sound (and does nothing)
|
||||
*/
|
||||
void Sound::Stop()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Nz
|
|||
NazaraAssert(sampleRate > 0, "sample rate must be different from zero");
|
||||
NazaraAssert(samples, "invalid samples");
|
||||
|
||||
m_duration = SafeCast<UInt32>((1000ULL*sampleCount / (GetChannelCount(format) * sampleRate)));
|
||||
m_duration = Time::Microseconds((1'000'000LL * sampleCount / (GetChannelCount(format) * sampleRate)));
|
||||
m_format = format;
|
||||
m_sampleCount = sampleCount;
|
||||
m_sampleRate = sampleRate;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,17 @@ namespace Nz
|
|||
return m_source->IsSpatializationEnabled();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Seek the sound to a point in time
|
||||
*
|
||||
* \param offset Time offset to seek
|
||||
*/
|
||||
void SoundEmitter::SeekToPlayingOffset(Time offset)
|
||||
{
|
||||
UInt64 microseconds = static_cast<UInt64>(std::max(offset.AsMicroseconds(), Int64(0)));
|
||||
SeekToSampleOffset(SafeCast<UInt32>(microseconds * GetSampleRate() / 1'000'000));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the attenuation
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,162 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Core/Win32/ClockImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Core/Posix/ClockImpl.hpp>
|
||||
#else
|
||||
#error OS not handled
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
UInt64 GetMicrosecondsLowPrecision()
|
||||
{
|
||||
return ClockImplGetElapsedMilliseconds()*1000ULL;
|
||||
}
|
||||
|
||||
UInt64 GetElapsedMicrosecondsFirstRun()
|
||||
{
|
||||
if (ClockImplInitializeHighPrecision())
|
||||
GetElapsedMicroseconds = ClockImplGetElapsedMicroseconds;
|
||||
else
|
||||
GetElapsedMicroseconds = GetMicrosecondsLowPrecision;
|
||||
|
||||
return GetElapsedMicroseconds();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup core
|
||||
* \class Nz::Clock
|
||||
* \brief Utility class that measure the elapsed time
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a Clock object
|
||||
*
|
||||
* \param startingValue The starting time value, in microseconds
|
||||
* \param paused The clock pause state
|
||||
*/
|
||||
Clock::Clock(UInt64 startingValue, bool paused) :
|
||||
m_elapsedTime(startingValue),
|
||||
m_refTime(GetElapsedMicroseconds()),
|
||||
m_paused(paused)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the elapsed time in seconds
|
||||
* \return Seconds elapsed
|
||||
*
|
||||
* \see GetMicroseconds, GetMilliseconds
|
||||
*/
|
||||
float Clock::GetSeconds() const
|
||||
{
|
||||
return GetMicroseconds()/1'000'000.f;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the elapsed time in microseconds
|
||||
* \return Microseconds elapsed
|
||||
*
|
||||
* \see GetMilliseconds, GetSeconds
|
||||
*/
|
||||
UInt64 Clock::GetMicroseconds() const
|
||||
{
|
||||
UInt64 elapsedMicroseconds = m_elapsedTime;
|
||||
if (!m_paused)
|
||||
elapsedMicroseconds += (GetElapsedMicroseconds() - m_refTime);
|
||||
|
||||
return elapsedMicroseconds;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the elapsed time in milliseconds
|
||||
* \return Milliseconds elapsed
|
||||
*
|
||||
* \see GetMicroseconds, GetSeconds
|
||||
*/
|
||||
UInt64 Clock::GetMilliseconds() const
|
||||
{
|
||||
return GetMicroseconds()/1000;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the current pause state of the clock
|
||||
* \return Boolean indicating if the clock is currently paused
|
||||
*
|
||||
* \see Pause, Unpause
|
||||
*/
|
||||
bool Clock::IsPaused() const
|
||||
{
|
||||
return m_paused;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pause the clock
|
||||
*
|
||||
* Pauses the clock, making the time retrieving functions to always return the value at the time the clock was paused
|
||||
* This has no effect if the clock is already paused
|
||||
*
|
||||
* \see IsPaused, Unpause
|
||||
*/
|
||||
void Clock::Pause()
|
||||
{
|
||||
if (!m_paused)
|
||||
{
|
||||
m_elapsedTime += GetElapsedMicroseconds() - m_refTime;
|
||||
m_paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Restart the clock
|
||||
* \return Microseconds elapsed
|
||||
*
|
||||
* Restarts the clock, putting it's time counter back to zero (as if the clock got constructed).
|
||||
* It also compute the elapsed microseconds since the last Restart() call without any time loss (a problem that the combination of GetElapsedMicroseconds and Restart have).
|
||||
*/
|
||||
UInt64 Clock::Restart(UInt64 startingValue, bool paused)
|
||||
{
|
||||
Nz::UInt64 now = GetElapsedMicroseconds();
|
||||
|
||||
Nz::UInt64 elapsedTime = m_elapsedTime;
|
||||
if (!m_paused)
|
||||
elapsedTime += (now - m_refTime);
|
||||
|
||||
m_elapsedTime = startingValue;
|
||||
m_refTime = now;
|
||||
m_paused = paused;
|
||||
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Unpause the clock
|
||||
*
|
||||
* Unpauses the clock, making the clock continue to measure the time
|
||||
* This has no effect if the clock is already unpaused
|
||||
*
|
||||
* \see IsPaused, Unpause
|
||||
*/
|
||||
void Clock::Unpause()
|
||||
{
|
||||
if (m_paused)
|
||||
{
|
||||
m_refTime = GetElapsedMicroseconds();
|
||||
m_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
ClockFunction GetElapsedMicroseconds = Detail::GetElapsedMicrosecondsFirstRun;
|
||||
ClockFunction GetElapsedMilliseconds = ClockImplGetElapsedMilliseconds;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Darwin/TimeImpl.hpp>
|
||||
#include <time.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool InitializeHighPrecisionTimer()
|
||||
{
|
||||
return true; //< No initialization required
|
||||
}
|
||||
|
||||
Time GetElapsedNanosecondsImpl()
|
||||
{
|
||||
UInt64 nanoseconds = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW);
|
||||
return Time::Nanoseconds(static_cast<Int64>(nanoseconds));
|
||||
}
|
||||
|
||||
Time GetElapsedMillisecondsImpl()
|
||||
{
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
|
||||
return Time::Seconds(time.tv_sec) + Time::Nanoseconds(time.tv_nsec);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CORE_DARWIN_TIMEIMPL_HPP
|
||||
#define NAZARA_CORE_DARWIN_TIMEIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool InitializeHighPrecisionTimer();
|
||||
Time GetElapsedNanosecondsImpl();
|
||||
Time GetElapsedMillisecondsImpl();
|
||||
}
|
||||
|
||||
#endif // NAZARA_CORE_DARWIN_TIMEIMPL_HPP
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright (C) 2022 Alexandre Janniaux
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Posix/ClockImpl.hpp>
|
||||
#include <sys/time.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool ClockImplInitializeHighPrecision()
|
||||
{
|
||||
return true; // No initialization needed
|
||||
}
|
||||
|
||||
UInt64 ClockImplGetElapsedMicroseconds()
|
||||
{
|
||||
timeval clock;
|
||||
gettimeofday(&clock, nullptr);
|
||||
return static_cast<UInt64>(clock.tv_sec*1000000 + clock.tv_usec);
|
||||
}
|
||||
|
||||
UInt64 ClockImplGetElapsedMilliseconds()
|
||||
{
|
||||
timeval clock;
|
||||
gettimeofday(&clock, nullptr);
|
||||
return static_cast<UInt64>(clock.tv_sec*1000 + (clock.tv_usec/1000));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright (C) 2022 Alexandre Janniaux
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CORE_POSIX_CLOCKIMPL_HPP
|
||||
#define NAZARA_CORE_POSIX_CLOCKIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool ClockImplInitializeHighPrecision();
|
||||
UInt64 ClockImplGetElapsedMicroseconds();
|
||||
UInt64 ClockImplGetElapsedMilliseconds();
|
||||
}
|
||||
|
||||
#endif // NAZARA_CORE_POSIX_CLOCKIMPL_HPP
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Posix/TimeImpl.hpp>
|
||||
#include <time.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool InitializeHighPrecisionTimer()
|
||||
{
|
||||
return true; //< No initialization required
|
||||
}
|
||||
|
||||
Time GetElapsedNanosecondsImpl()
|
||||
{
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
|
||||
return Time::Seconds(time.tv_sec) + Time::Nanoseconds(time.tv_nsec);
|
||||
}
|
||||
|
||||
Time GetElapsedMillisecondsImpl()
|
||||
{
|
||||
timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
|
||||
return Time::Seconds(time.tv_sec) + Time::Nanoseconds(time.tv_nsec);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,16 +4,17 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CORE_WIN32_CLOCKIMPL_HPP
|
||||
#define NAZARA_CORE_WIN32_CLOCKIMPL_HPP
|
||||
#ifndef NAZARA_CORE_POSIX_TIMEIMPL_HPP
|
||||
#define NAZARA_CORE_POSIX_TIMEIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool ClockImplInitializeHighPrecision();
|
||||
UInt64 ClockImplGetElapsedMicroseconds();
|
||||
UInt64 ClockImplGetElapsedMilliseconds();
|
||||
bool InitializeHighPrecisionTimer();
|
||||
Time GetElapsedNanosecondsImpl();
|
||||
Time GetElapsedMillisecondsImpl();
|
||||
}
|
||||
|
||||
#endif // NAZARA_CORE_WIN32_CLOCKIMPL_HPP
|
||||
#endif // NAZARA_CORE_POSIX_TIMEIMPL_HPP
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
void LifetimeSystem::Update(float elapsedTime)
|
||||
void LifetimeSystem::Update(Time elapsedTime)
|
||||
{
|
||||
auto view = m_registry.view<LifetimeComponent>();
|
||||
for (auto [entity, lifetimeComponent] : view.each())
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ namespace Nz
|
|||
|
||||
void SystemGraph::Update()
|
||||
{
|
||||
return Update(m_clock.Restart() / 1'000'000.f);
|
||||
return Update(m_clock.Restart());
|
||||
}
|
||||
|
||||
void SystemGraph::Update(float elapsedTime)
|
||||
void SystemGraph::Update(Time elapsedTime)
|
||||
{
|
||||
if (!m_systemOrderUpdated)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Core/Win32/TimeImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_MACOS) || defined(NAZARA_PLATFORM_IOS)
|
||||
#include <Nazara/Core/Darwin/TimeImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <Nazara/Core/Posix/TimeImpl.hpp>
|
||||
#else
|
||||
#error OS not handled
|
||||
#endif
|
||||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace NAZARA_ANONYMOUS_NAMESPACE
|
||||
{
|
||||
Time GetElapsedNanosecondsFirstRun()
|
||||
{
|
||||
if (InitializeHighPrecisionTimer())
|
||||
GetElapsedNanoseconds = GetElapsedNanosecondsImpl;
|
||||
else
|
||||
GetElapsedNanoseconds = GetElapsedMillisecondsImpl;
|
||||
|
||||
return GetElapsedNanoseconds();
|
||||
}
|
||||
}
|
||||
|
||||
GetElapsedTimeFunction GetElapsedMilliseconds = GetElapsedMillisecondsImpl;
|
||||
GetElapsedTimeFunction GetElapsedNanoseconds = NAZARA_ANONYMOUS_NAMESPACE_PREFIX(GetElapsedNanosecondsFirstRun);
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/ClockImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace NAZARA_ANONYMOUS_NAMESPACE
|
||||
{
|
||||
LARGE_INTEGER s_frequency; // La fréquence ne varie pas pas au cours de l'exécution
|
||||
}
|
||||
|
||||
bool ClockImplInitializeHighPrecision()
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
return QueryPerformanceFrequency(&s_frequency) != 0;
|
||||
}
|
||||
|
||||
UInt64 ClockImplGetElapsedMicroseconds()
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
|
||||
//HANDLE thread = GetCurrentThread();
|
||||
//DWORD oldMask = SetThreadAffinityMask(thread, 1);
|
||||
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
|
||||
//SetThreadAffinityMask(thread, oldMask);
|
||||
|
||||
return time.QuadPart*1000000ULL / s_frequency.QuadPart;
|
||||
}
|
||||
|
||||
UInt64 ClockImplGetElapsedMilliseconds()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS_VISTA
|
||||
return GetTickCount64();
|
||||
#else
|
||||
return GetTickCount();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/AntiWindows.hpp>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
#include <Nazara/Core/Win32/FileImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <Nazara/Core/Win32/Time.hpp>
|
||||
#include <Nazara/Core/Win32/Utils.hpp>
|
||||
#include <Nazara/Utils/CallOnExit.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/TimeImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace NAZARA_ANONYMOUS_NAMESPACE
|
||||
{
|
||||
LARGE_INTEGER s_frequency; // The frequency of the performance counter is fixed at system boot and is consistent across all processors
|
||||
}
|
||||
|
||||
bool InitializeHighPrecisionTimer()
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
return QueryPerformanceFrequency(&s_frequency) != 0 && s_frequency.QuadPart != 0;
|
||||
}
|
||||
|
||||
Time GetElapsedNanosecondsImpl()
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
|
||||
if (s_frequency.QuadPart == 10'000'000) //< seems to be a common value
|
||||
return Time::Nanoseconds(100ll * time.QuadPart);
|
||||
else
|
||||
{
|
||||
// Compute using 128bits precisions
|
||||
// https://stackoverflow.com/questions/23378063/how-can-i-use-mach-absolute-time-without-overflowing
|
||||
|
||||
UInt64 num = 1'000'000'000ll;
|
||||
UInt64 denom = s_frequency.QuadPart;
|
||||
UInt64 value = time.QuadPart;
|
||||
|
||||
UInt64 high = (value >> 32) * num;
|
||||
UInt64 low = (value & 0xFFFFFFFFull) * num / denom;
|
||||
UInt64 highRem = ((high % denom) << 32) / denom;
|
||||
high /= denom;
|
||||
|
||||
return Time::Nanoseconds(SafeCast<Int64>((high << 32) + highRem + low));
|
||||
}
|
||||
}
|
||||
|
||||
Time GetElapsedMillisecondsImpl()
|
||||
{
|
||||
#ifdef NAZARA_UTILS_WINDOWS_NT6
|
||||
return Time::Milliseconds(GetTickCount64());
|
||||
#else
|
||||
return Time::Milliseconds(GetTickCount());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/AntiWindows.hpp>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CORE_WIN32_TIMEIMPL_HPP
|
||||
#define NAZARA_CORE_WIN32_TIMEIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool InitializeHighPrecisionTimer();
|
||||
Time GetElapsedNanosecondsImpl();
|
||||
Time GetElapsedMillisecondsImpl();
|
||||
}
|
||||
|
||||
#endif // NAZARA_CORE_WIN32_TIMEIMPL_HPP
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// This file is part of the "Nazara Engine - Core module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/Time.hpp>
|
||||
#include <Nazara/Core/Win32/Utils.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CORE_WIN32_TIME_HPP
|
||||
#define NAZARA_CORE_WIN32_TIME_HPP
|
||||
#ifndef NAZARA_CORE_WIN32_UTILS_HPP
|
||||
#define NAZARA_CORE_WIN32_UTILS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <ctime>
|
||||
|
|
@ -16,4 +16,4 @@ namespace Nz
|
|||
time_t FileTimeToTime(FILETIME* time);
|
||||
}
|
||||
|
||||
#endif // NAZARA_CORE_WIN32_TIME_HPP
|
||||
#endif // NAZARA_CORE_WIN32_UTILS_HPP
|
||||
|
|
@ -48,7 +48,7 @@ namespace Nz
|
|||
m_pipeline.reset();
|
||||
}
|
||||
|
||||
void RenderSystem::Update(float /*elapsedTime*/)
|
||||
void RenderSystem::Update(Time /*elapsedTime*/)
|
||||
{
|
||||
UpdateObservers();
|
||||
UpdateVisibility();
|
||||
|
|
|
|||
|
|
@ -1245,7 +1245,7 @@ namespace Nz
|
|||
|
||||
void ENetHost::ThrottleBandwidth()
|
||||
{
|
||||
UInt32 currentTime = UInt32(GetElapsedMilliseconds());
|
||||
UInt32 currentTime = UInt32(GetElapsedMilliseconds().AsMilliseconds());
|
||||
UInt32 elapsedTime = currentTime - m_bandwidthThrottleEpoch;
|
||||
|
||||
if (elapsedTime < ENetConstants::ENetHost_BandwidthThrottleInterval)
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ namespace Nz
|
|||
|
||||
PhysWorld2D::PhysWorld2D() :
|
||||
m_maxStepCount(50),
|
||||
m_stepSize(0.005f),
|
||||
m_timestepAccumulator(0.f)
|
||||
m_stepSize(Time::TickDuration(200)),
|
||||
m_timestepAccumulator(Time::Zero())
|
||||
{
|
||||
m_handle = cpSpaceNew();
|
||||
cpSpaceSetUserData(m_handle, this);
|
||||
|
|
@ -154,7 +154,7 @@ namespace Nz
|
|||
return m_maxStepCount;
|
||||
}
|
||||
|
||||
float PhysWorld2D::GetStepSize() const
|
||||
Time PhysWorld2D::GetStepSize() const
|
||||
{
|
||||
return m_stepSize;
|
||||
}
|
||||
|
|
@ -328,7 +328,7 @@ namespace Nz
|
|||
|
||||
void PhysWorld2D::SetIterationCount(std::size_t iterationCount)
|
||||
{
|
||||
cpSpaceSetIterations(m_handle, int(iterationCount));
|
||||
cpSpaceSetIterations(m_handle, SafeCast<int>(iterationCount));
|
||||
}
|
||||
|
||||
void PhysWorld2D::SetMaxStepCount(std::size_t maxStepCount)
|
||||
|
|
@ -336,30 +336,32 @@ namespace Nz
|
|||
m_maxStepCount = maxStepCount;
|
||||
}
|
||||
|
||||
void PhysWorld2D::SetSleepTime(float sleepTime)
|
||||
void PhysWorld2D::SetSleepTime(Time sleepTime)
|
||||
{
|
||||
if (sleepTime > 0)
|
||||
cpSpaceSetSleepTimeThreshold(m_handle, cpFloat(sleepTime));
|
||||
if (sleepTime > Time::Zero())
|
||||
cpSpaceSetSleepTimeThreshold(m_handle, sleepTime.AsSeconds<cpFloat>());
|
||||
else
|
||||
cpSpaceSetSleepTimeThreshold(m_handle, std::numeric_limits<cpFloat>::infinity());
|
||||
}
|
||||
|
||||
void PhysWorld2D::SetStepSize(float stepSize)
|
||||
void PhysWorld2D::SetStepSize(Time stepSize)
|
||||
{
|
||||
m_stepSize = stepSize;
|
||||
}
|
||||
|
||||
void PhysWorld2D::Step(float timestep)
|
||||
void PhysWorld2D::Step(Time timestep)
|
||||
{
|
||||
m_timestepAccumulator += timestep;
|
||||
|
||||
std::size_t stepCount = std::min(static_cast<std::size_t>(m_timestepAccumulator / m_stepSize), m_maxStepCount);
|
||||
std::size_t stepCount = std::min(static_cast<std::size_t>(static_cast<Int64>(m_timestepAccumulator / m_stepSize)), m_maxStepCount);
|
||||
float invStepCount = 1.f / stepCount;
|
||||
|
||||
cpFloat dt = m_stepSize.AsSeconds<float>(); //< FIXME: AsSeconds<cpFloat> is more precise but it fails unit tests on Linux
|
||||
for (std::size_t i = 0; i < stepCount; ++i)
|
||||
{
|
||||
OnPhysWorld2DPreStep(this, invStepCount);
|
||||
|
||||
cpSpaceStep(m_handle, m_stepSize);
|
||||
cpSpaceStep(m_handle, dt);
|
||||
|
||||
OnPhysWorld2DPostStep(this, invStepCount);
|
||||
if (!m_rigidPostSteps.empty())
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Nz
|
|||
rigidBodyComponent.Destroy();
|
||||
}
|
||||
|
||||
void Physics2DSystem::Update(float elapsedTime)
|
||||
void Physics2DSystem::Update(Time elapsedTime)
|
||||
{
|
||||
m_physWorld.Step(elapsedTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace Nz
|
|||
PhysWorld3D::PhysWorld3D() :
|
||||
m_maxStepCount(50),
|
||||
m_gravity(Vector3f::Zero()),
|
||||
m_stepSize(1.f / 120.f),
|
||||
m_timestepAccumulator(0.f)
|
||||
m_stepSize(Time::TickDuration(120)),
|
||||
m_timestepAccumulator(Time::Zero())
|
||||
{
|
||||
m_world = NewtonCreate();
|
||||
NewtonWorldSetUserData(m_world, this);
|
||||
|
|
@ -86,7 +86,7 @@ namespace Nz
|
|||
return m_maxStepCount;
|
||||
}
|
||||
|
||||
float PhysWorld3D::GetStepSize() const
|
||||
Time PhysWorld3D::GetStepSize() const
|
||||
{
|
||||
return m_stepSize;
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ namespace Nz
|
|||
m_maxStepCount = maxStepCount;
|
||||
}
|
||||
|
||||
void PhysWorld3D::SetStepSize(float stepSize)
|
||||
void PhysWorld3D::SetStepSize(Time stepSize)
|
||||
{
|
||||
m_stepSize = stepSize;
|
||||
}
|
||||
|
|
@ -159,14 +159,16 @@ namespace Nz
|
|||
NewtonMaterialSetSurfaceThickness(m_world, firstMaterial, secondMaterial, thickness);
|
||||
}
|
||||
|
||||
void PhysWorld3D::Step(float timestep)
|
||||
void PhysWorld3D::Step(Time timestep)
|
||||
{
|
||||
m_timestepAccumulator += timestep;
|
||||
|
||||
std::size_t stepCount = 0;
|
||||
float dt = m_stepSize.AsSeconds<float>();
|
||||
|
||||
while (m_timestepAccumulator >= m_stepSize && stepCount < m_maxStepCount)
|
||||
{
|
||||
NewtonUpdate(m_world, m_stepSize);
|
||||
NewtonUpdate(m_world, dt);
|
||||
m_timestepAccumulator -= m_stepSize;
|
||||
stepCount++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Nz
|
|||
rigidBodyComponent.Destroy();
|
||||
}
|
||||
|
||||
void Physics3DSystem::Update(float elapsedTime)
|
||||
void Physics3DSystem::Update(Time elapsedTime)
|
||||
{
|
||||
m_physWorld.Step(elapsedTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Nz
|
|||
|
||||
if (m_framerateLimit > 0)
|
||||
{
|
||||
int remainingTime = 1000 / static_cast<int>(m_framerateLimit) - static_cast<int>(m_clock.GetMilliseconds());
|
||||
int remainingTime = 1000 / static_cast<int>(m_framerateLimit) - static_cast<int>(m_clock.GetElapsedTime().AsMilliseconds());
|
||||
if (remainingTime > 0)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(remainingTime));
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Nz
|
|||
m_skeletonConstructObserver.disconnect();
|
||||
}
|
||||
|
||||
void SkeletonSystem::Update(float /*elapsedTime*/)
|
||||
void SkeletonSystem::Update(Time /*elapsedTime*/)
|
||||
{
|
||||
m_sharedSkeletonConstructObserver.each([&](entt::entity entity)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -277,8 +277,6 @@ namespace Nz
|
|||
return false;
|
||||
}
|
||||
|
||||
m_clock.Restart();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ int main()
|
|||
SpriteRenderData spriteRenderData1 = BuildSpriteData(*device, spriteRenderPipeline, Nz::Rectf(margin, windowSize.y - margin - textureSize, textureSize, textureSize), Nz::Vector2f(windowSize), *texture, *textureSampler);
|
||||
SpriteRenderData spriteRenderData2 = BuildSpriteData(*device, spriteRenderPipeline, Nz::Rectf(windowSize.x - textureSize - margin, windowSize.y - margin - textureSize, textureSize, textureSize), Nz::Vector2f(windowSize), *targetTexture, *textureSampler);
|
||||
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
while (window.IsOpen())
|
||||
|
|
@ -205,13 +205,10 @@ int main()
|
|||
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000)
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
||||
fps = 0;
|
||||
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock updateClock;
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
|
@ -181,10 +181,9 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
float cameraSpeed = 2.f * updateClock.GetSeconds();
|
||||
updateClock.Restart();
|
||||
float cameraSpeed = 2.f * deltaTime->AsSeconds();
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
|
||||
viewerPos += camQuat * Nz::Vector3f::Forward() * cameraSpeed;
|
||||
|
|
@ -231,23 +230,10 @@ int main()
|
|||
// On incrémente le compteur de FPS improvisé
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
// Et on insère ces données dans le titre de la fenêtre
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
||||
/*
|
||||
Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier,
|
||||
via quelque chose de similaire à u8"Cha\u00CEne de caract\u00E8res".
|
||||
Cependant, si le code source est encodé en UTF-8 (Comme c'est le cas dans ce fichier),
|
||||
cela fonctionnera aussi comme ceci : "Chaîne de caractères".
|
||||
*/
|
||||
|
||||
// Et on réinitialise le compteur de FPS
|
||||
fps = 0;
|
||||
|
||||
// Et on relance l'horloge pour refaire ça dans une seconde
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -253,8 +253,8 @@ int main()
|
|||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::Clock updateClock;
|
||||
Nz::Clock secondClock;
|
||||
Nz::MillisecondClock updateClock;
|
||||
Nz::MillisecondClock secondClock;
|
||||
unsigned int fps = 0;
|
||||
bool uboUpdate = true;
|
||||
|
||||
|
|
@ -304,10 +304,9 @@ int main()
|
|||
}
|
||||
}
|
||||
|
||||
if (updateClock.GetMilliseconds() > 1000 / 60)
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
float cameraSpeed = 2.f * updateClock.GetSeconds();
|
||||
updateClock.Restart();
|
||||
float cameraSpeed = 2.f * deltaTime->AsSeconds();
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
|
||||
viewerPos += camQuat * Nz::Vector3f::Forward() * cameraSpeed;
|
||||
|
|
@ -412,7 +411,7 @@ int main()
|
|||
// On incrémente le compteur de FPS improvisé
|
||||
fps++;
|
||||
|
||||
if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes
|
||||
if (secondClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
// Et on insère ces données dans le titre de la fenêtre
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||
|
|
@ -426,9 +425,6 @@ int main()
|
|||
|
||||
// Et on réinitialise le compteur de FPS
|
||||
fps = 0;
|
||||
|
||||
// Et on relance l'horloge pour refaire ça dans une seconde
|
||||
secondClock.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ std::filesystem::path GetAssetDir();
|
|||
|
||||
SCENARIO("Music", "[AUDIO][MUSIC]")
|
||||
{
|
||||
using namespace Nz::Literals;
|
||||
|
||||
GIVEN("A music")
|
||||
{
|
||||
Nz::Music music;
|
||||
|
|
@ -19,9 +21,9 @@ SCENARIO("Music", "[AUDIO][MUSIC]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(music.GetDuration() == 63059); // 1 min 03 = 63s = 63000ms
|
||||
CHECK(music.GetDuration() == 63'059'591_us); // 1 min 03 = 63s = 63000ms
|
||||
CHECK(music.GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(music.GetPlayingOffset() == 0);
|
||||
CHECK(music.GetPlayingOffset() == 0_ms);
|
||||
CHECK(music.GetSampleCount() <= 64 * 44100 * 2); // * 2 (stereo)
|
||||
CHECK(music.GetSampleCount() >= 63 * 44100 * 2); // * 2 (stereo)
|
||||
CHECK(music.GetSampleRate() == 44100 /* Hz */);
|
||||
|
|
@ -30,7 +32,7 @@ SCENARIO("Music", "[AUDIO][MUSIC]")
|
|||
CHECK(music.IsSpatializationEnabled());
|
||||
CHECK(music.GetMinDistance() == 1.f);
|
||||
CHECK(music.GetPitch() == 1.f);
|
||||
CHECK(music.GetPlayingOffset() == 0);
|
||||
CHECK(music.GetPlayingOffset() == 0_ms);
|
||||
CHECK(music.GetPosition() == Nz::Vector3f::Zero());
|
||||
CHECK(music.GetVelocity() == Nz::Vector3f::Zero());
|
||||
CHECK(music.GetVolume() == 1.f);
|
||||
|
|
@ -42,53 +44,54 @@ SCENARIO("Music", "[AUDIO][MUSIC]")
|
|||
|
||||
music.Play();
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(music.GetPlayingOffset() >= 950);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
Nz::Time t = music.GetPlayingOffset();
|
||||
CHECK(music.GetPlayingOffset() >= 950_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
CHECK(music.GetPlayingOffset() <= 1500);
|
||||
CHECK(music.GetPlayingOffset() <= 1500_ms);
|
||||
|
||||
music.SetPlayingOffset(4200);
|
||||
music.SeekToPlayingOffset(4200_ms);
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(music.GetPlayingOffset() >= 4150);
|
||||
CHECK(music.GetPlayingOffset() < 4500);
|
||||
CHECK(music.GetPlayingOffset() >= 4150_ms);
|
||||
CHECK(music.GetPlayingOffset() < 4500_ms);
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
|
||||
music.Pause();
|
||||
Nz::UInt32 playingOffset = music.GetPlayingOffset();
|
||||
Nz::Time playingOffset = music.GetPlayingOffset();
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Paused);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Paused);
|
||||
CHECK(music.GetPlayingOffset() == playingOffset);
|
||||
|
||||
music.SetPlayingOffset(3500);
|
||||
music.SeekToPlayingOffset(3500_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
CHECK(music.GetPlayingOffset() == 3500);
|
||||
CHECK(music.GetPlayingOffset() == 3500_ms);
|
||||
|
||||
music.Play();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(music.GetPlayingOffset() >= 3650);
|
||||
CHECK(music.GetPlayingOffset() >= 3650_ms);
|
||||
|
||||
AND_WHEN("We let the sound stop by itself")
|
||||
{
|
||||
REQUIRE(music.GetDuration() == 63059);
|
||||
REQUIRE(music.GetDuration() == 63'059'591_us);
|
||||
|
||||
music.SetPlayingOffset(62900);
|
||||
music.SeekToPlayingOffset(62900_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Stopped);
|
||||
CHECK(music.GetPlayingOffset() == 0);
|
||||
CHECK(music.GetPlayingOffset() == 0_ms);
|
||||
|
||||
music.SetPlayingOffset(64000);
|
||||
music.SeekToPlayingOffset(64000_ms);
|
||||
music.Play();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(music.GetPlayingOffset() < 100);
|
||||
CHECK(music.GetPlayingOffset() < 100_ms);
|
||||
|
||||
music.Stop();
|
||||
music.SetPlayingOffset(62900);
|
||||
music.SeekToPlayingOffset(62900_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Stopped);
|
||||
CHECK(music.GetPlayingOffset() == 0); //< playing offset has no effect until Play()
|
||||
CHECK(music.GetPlayingOffset() == 0_ms); //< playing offset has no effect until Play()
|
||||
|
||||
AND_WHEN("We enable looping")
|
||||
{
|
||||
|
|
@ -96,10 +99,10 @@ SCENARIO("Music", "[AUDIO][MUSIC]")
|
|||
CHECK(music.IsLooping());
|
||||
music.Play();
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(music.GetPlayingOffset() >= 62900);
|
||||
CHECK(music.GetPlayingOffset() >= 62900_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
CHECK(music.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(music.GetPlayingOffset() < 300);
|
||||
CHECK(music.GetPlayingOffset() < 300_ms);
|
||||
}
|
||||
}
|
||||
Nz::Audio::Instance()->GetDefaultDevice()->SetGlobalVolume(100.f);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ std::filesystem::path GetAssetDir();
|
|||
|
||||
SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]")
|
||||
{
|
||||
using namespace Nz::Literals;
|
||||
|
||||
GIVEN("A sound buffer")
|
||||
{
|
||||
WHEN("We load a .flac file")
|
||||
|
|
@ -15,7 +17,7 @@ SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundBuffer->GetDuration() == 8192);
|
||||
CHECK(soundBuffer->GetDuration() == 8192_ms);
|
||||
CHECK(soundBuffer->GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(soundBuffer->GetSampleRate() == 96000);
|
||||
}
|
||||
|
|
@ -28,7 +30,7 @@ SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundBuffer->GetDuration() == 27193);
|
||||
CHECK(soundBuffer->GetDuration() == 27'193'468_us);
|
||||
CHECK(soundBuffer->GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(soundBuffer->GetSampleRate() == 32000);
|
||||
}
|
||||
|
|
@ -41,7 +43,7 @@ SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundBuffer->GetDuration() == 63059);
|
||||
CHECK(soundBuffer->GetDuration() == 63'059'591_us);
|
||||
CHECK(soundBuffer->GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(soundBuffer->GetSampleRate() == 44100);
|
||||
}
|
||||
|
|
@ -54,7 +56,7 @@ SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundBuffer->GetDuration() == 2490);
|
||||
CHECK(soundBuffer->GetDuration() == 2'490'340_us);
|
||||
CHECK(soundBuffer->GetFormat() == Nz::AudioFormat::I16_Mono);
|
||||
CHECK(soundBuffer->GetSampleRate() == 44100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ std::filesystem::path GetAssetDir();
|
|||
|
||||
SCENARIO("SoundStream", "[AUDIO][SoundStream]")
|
||||
{
|
||||
using namespace Nz::Literals;
|
||||
|
||||
GIVEN("A sound buffer")
|
||||
{
|
||||
WHEN("We load a .flac file")
|
||||
|
|
@ -15,7 +17,7 @@ SCENARIO("SoundStream", "[AUDIO][SoundStream]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundStream->GetDuration() == 8192);
|
||||
CHECK(soundStream->GetDuration() == 8192_ms);
|
||||
CHECK(soundStream->GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(soundStream->GetSampleRate() == 96000);
|
||||
}
|
||||
|
|
@ -28,7 +30,7 @@ SCENARIO("SoundStream", "[AUDIO][SoundStream]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundStream->GetDuration() == 27193);
|
||||
CHECK(soundStream->GetDuration() == 27'193'468_us);
|
||||
CHECK(soundStream->GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(soundStream->GetSampleRate() == 32000);
|
||||
}
|
||||
|
|
@ -41,7 +43,7 @@ SCENARIO("SoundStream", "[AUDIO][SoundStream]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundStream->GetDuration() == 63059);
|
||||
CHECK(soundStream->GetDuration() == 63'059'591_us);
|
||||
CHECK(soundStream->GetFormat() == Nz::AudioFormat::I16_Stereo);
|
||||
CHECK(soundStream->GetSampleRate() == 44100);
|
||||
}
|
||||
|
|
@ -54,7 +56,7 @@ SCENARIO("SoundStream", "[AUDIO][SoundStream]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(soundStream->GetDuration() == 2490);
|
||||
CHECK(soundStream->GetDuration() == 2'490'340_us);
|
||||
CHECK(soundStream->GetFormat() == Nz::AudioFormat::I16_Mono);
|
||||
CHECK(soundStream->GetSampleRate() == 44100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,15 @@
|
|||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
std::filesystem::path GetAssetDir();
|
||||
|
||||
SCENARIO("Sound", "[AUDIO][SOUND]")
|
||||
{
|
||||
using namespace Nz::Literals;
|
||||
|
||||
GIVEN("A sound")
|
||||
{
|
||||
Nz::Sound sound;
|
||||
|
|
@ -19,14 +22,14 @@ SCENARIO("Sound", "[AUDIO][SOUND]")
|
|||
|
||||
THEN("We can ask the informations of the file")
|
||||
{
|
||||
CHECK(sound.GetDuration() == 8192);
|
||||
CHECK(sound.GetDuration() == 8192_ms);
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Stopped);
|
||||
CHECK_FALSE(sound.IsLooping());
|
||||
CHECK(sound.IsPlayable());
|
||||
CHECK(sound.IsSpatializationEnabled());
|
||||
CHECK(sound.GetMinDistance() == 1.f);
|
||||
CHECK(sound.GetPitch() == 1.f);
|
||||
CHECK(sound.GetPlayingOffset() == 0);
|
||||
CHECK(sound.GetPlayingOffset() == 0_ms);
|
||||
CHECK(sound.GetPosition() == Nz::Vector3f::Zero());
|
||||
CHECK(sound.GetVelocity() == Nz::Vector3f::Zero());
|
||||
CHECK(sound.GetVolume() == 1.f);
|
||||
|
|
@ -38,42 +41,45 @@ SCENARIO("Sound", "[AUDIO][SOUND]")
|
|||
|
||||
sound.Play();
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(sound.GetPlayingOffset() >= 950);
|
||||
|
||||
CHECK(sound.GetPlayingOffset() >= 950_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
CHECK(sound.GetPlayingOffset() <= 1500);
|
||||
CHECK(sound.GetPlayingOffset() <= 1500_ms);
|
||||
sound.Pause();
|
||||
Nz::UInt32 playingOffset = sound.GetPlayingOffset();
|
||||
Nz::Time playingOffset = sound.GetPlayingOffset();
|
||||
Nz::UInt64 sampleOffset = sound.GetSampleOffset();
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Paused);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Paused);
|
||||
CHECK(sound.GetPlayingOffset() == playingOffset);
|
||||
CHECK(sound.GetSampleOffset() == sampleOffset);
|
||||
|
||||
sound.SetPlayingOffset(3500);
|
||||
CHECK(sound.GetPlayingOffset() == 3500);
|
||||
sound.SeekToPlayingOffset(3500_ms);
|
||||
CHECK(sound.GetPlayingOffset() == 3500_ms);
|
||||
|
||||
sound.Play();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
CHECK(sound.GetPlayingOffset() >= 1650);
|
||||
CHECK(sound.GetPlayingOffset() >= 1650_ms);
|
||||
|
||||
AND_WHEN("We let the sound stop by itself")
|
||||
{
|
||||
REQUIRE(sound.GetDuration() == 8192);
|
||||
REQUIRE(sound.GetDuration() == 8192_ms);
|
||||
|
||||
sound.SetPlayingOffset(8000);
|
||||
sound.SeekToPlayingOffset(8000_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Stopped);
|
||||
CHECK(sound.GetPlayingOffset() == 0);
|
||||
CHECK(sound.GetPlayingOffset() == 0_ms);
|
||||
|
||||
sound.SetPlayingOffset(9000);
|
||||
sound.SeekToPlayingOffset(9000_ms);
|
||||
sound.Play();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Playing);
|
||||
|
||||
sound.Stop();
|
||||
sound.SetPlayingOffset(8000);
|
||||
sound.SeekToPlayingOffset(8000_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Stopped);
|
||||
CHECK(sound.GetPlayingOffset() == 0); //< playing offset has no effect until Play()
|
||||
CHECK(sound.GetPlayingOffset() == 0_ms); //< playing offset has no effect until Play()
|
||||
|
||||
AND_WHEN("We enable looping")
|
||||
{
|
||||
|
|
@ -81,10 +87,10 @@ SCENARIO("Sound", "[AUDIO][SOUND]")
|
|||
CHECK(sound.IsLooping());
|
||||
sound.Play();
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(sound.GetPlayingOffset() >= 8000);
|
||||
CHECK(sound.GetPlayingOffset() >= 8000_ms);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
||||
CHECK(sound.GetStatus() == Nz::SoundStatus::Playing);
|
||||
CHECK(sound.GetPlayingOffset() < 300);
|
||||
CHECK(sound.GetPlayingOffset() < 300_ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ SCENARIO("Clock", "[CORE][CLOCK]")
|
|||
{
|
||||
GIVEN("A clock paused")
|
||||
{
|
||||
Nz::UInt64 initialTime = 100;
|
||||
Nz::Clock clock(initialTime, true);
|
||||
Nz::Time initialTime = Nz::Time::Microseconds(100);
|
||||
Nz::HighPrecisionClock clock(initialTime, true);
|
||||
|
||||
WHEN("We get time since it is paused")
|
||||
{
|
||||
THEN("Time must be the initialTime")
|
||||
{
|
||||
CHECK(clock.GetMicroseconds() == initialTime);
|
||||
CHECK(clock.GetElapsedTime() == initialTime);
|
||||
CHECK(clock.IsPaused());
|
||||
}
|
||||
}
|
||||
|
|
@ -28,10 +28,11 @@ SCENARIO("Clock", "[CORE][CLOCK]")
|
|||
THEN("Time must not be the initialTime")
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
Nz::UInt64 microSeconds = clock.GetMicroseconds();
|
||||
CHECK(microSeconds != initialTime);
|
||||
CHECK(microSeconds / 1000 <= clock.GetMilliseconds());
|
||||
CHECK(microSeconds / (1000.f * 1000.f) <= clock.GetSeconds());
|
||||
Nz::Time elapsedTime = clock.GetElapsedTime();
|
||||
Nz::Int64 microseconds = elapsedTime.AsMicroseconds();
|
||||
CHECK(microseconds != initialTime.AsMicroseconds());
|
||||
CHECK(microseconds / 1000 <= elapsedTime.AsMilliseconds());
|
||||
CHECK(microseconds / (1000.f * 1000.f) <= elapsedTime.AsSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +45,7 @@ SCENARIO("Clock", "[CORE][CLOCK]")
|
|||
CHECK(!clock.IsPaused());
|
||||
clock.Pause();
|
||||
CHECK(clock.IsPaused());
|
||||
CHECK(clock.GetMicroseconds() != initialTime);
|
||||
CHECK(clock.GetElapsedTime() != initialTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
#include <Nazara/Core/Time.hpp>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
SCENARIO("Time", "[CORE][Time]")
|
||||
{
|
||||
auto ToString = [](Nz::Time time) -> std::string
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << time;
|
||||
return std::move(ss).str();
|
||||
};
|
||||
|
||||
GIVEN("One second")
|
||||
{
|
||||
Nz::Time time = Nz::Time::Second();
|
||||
CHECK(time.AsDuration<std::chrono::seconds>() == std::chrono::seconds(1));
|
||||
CHECK(time.AsDuration<std::chrono::milliseconds>() == std::chrono::milliseconds(1'000));
|
||||
CHECK(time.AsDuration<std::chrono::microseconds>() == std::chrono::microseconds(1'000'000));
|
||||
CHECK(time.AsMicroseconds() == 1'000'000);
|
||||
CHECK(time.AsMilliseconds() == 1'000);
|
||||
CHECK(time.AsSeconds() == 1.f);
|
||||
CHECK(time == Nz::Time::Second());
|
||||
CHECK(time == Nz::Time::Seconds(1.f));
|
||||
CHECK(time == Nz::Time::Milliseconds(1'000));
|
||||
CHECK(time == Nz::Time::Seconds(2) - Nz::Time::Milliseconds(1'000));
|
||||
|
||||
CHECK(ToString(time) == "1000ms");
|
||||
}
|
||||
|
||||
GIVEN("One arbitrary duration")
|
||||
{
|
||||
Nz::Time time = Nz::Time::FromDuration(std::chrono::nanoseconds(1'234'567'890ULL)) - Nz::Time::Nanoseconds(890);
|
||||
CHECK(time == Nz::Time::Microseconds(1'234'567));
|
||||
CHECK_FALSE(time == Nz::Time::Microseconds(1'234'568));
|
||||
CHECK(time != Nz::Time::Microseconds(1'234'566));
|
||||
CHECK_FALSE(time != Nz::Time::Microseconds(1'234'567));
|
||||
CHECK(time > Nz::Time::Microseconds(1'234'000));
|
||||
CHECK(time > Nz::Time::Zero());
|
||||
CHECK(time >= Nz::Time::Microseconds(1'234'567));
|
||||
CHECK(time >= Nz::Time::Microseconds(1'234'000));
|
||||
CHECK(time < Nz::Time::Milliseconds(1'235));
|
||||
CHECK(time <= Nz::Time::Microseconds(1'234'567));
|
||||
CHECK(time <= Nz::Time::Seconds(2));
|
||||
|
||||
CHECK(ToString(time) == "1.23457s");
|
||||
CHECK(ToString(time - Nz::Time::Second()) == "234.567ms");
|
||||
CHECK(ToString(time - Nz::Time::Seconds(1.234f)) == "567us");
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
|
|||
}
|
||||
}
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We ask for the nearest body")
|
||||
{
|
||||
|
|
@ -130,7 +130,7 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
|
|||
Nz::RigidBody2D trigger(&world, 0.f, triggerBox);
|
||||
trigger.SetPosition(Nz::Vector2f(2.f, 0.f));
|
||||
|
||||
world.Step(0.f);
|
||||
world.Step(Nz::Time::Zero());
|
||||
|
||||
Nz::PhysWorld2D::Callback characterTriggerCallback;
|
||||
characterTriggerCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::Arbiter2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool {
|
||||
|
|
@ -164,27 +164,29 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
|
|||
{
|
||||
character.SetVelocity(Nz::Vector2f(1.f, 0.f));
|
||||
for (int i = 0; i != 11; ++i)
|
||||
world.Step(0.1f);
|
||||
world.Step(Nz::Time::TickDuration(10));
|
||||
|
||||
THEN("It should trigger several collisions")
|
||||
{
|
||||
CHECK(statusTriggerCollision == 3);
|
||||
for (int i = 0; i != 20; ++i)
|
||||
world.Step(0.1f);
|
||||
world.Step(Nz::Time::TickDuration(10));
|
||||
CHECK(statusTriggerCollision == 11);
|
||||
|
||||
CHECK(character.GetPosition().x == Catch::Approx(3.1f).margin(0.01f));
|
||||
|
||||
for (int i = 0; i != 9; ++i)
|
||||
world.Step(0.1f);
|
||||
world.Step(Nz::Time::TickDuration(10));
|
||||
|
||||
CHECK(character.GetPosition().x == Catch::Approx(4.f).margin(0.01f));
|
||||
world.Step(0.1f);
|
||||
world.Step(Nz::Time::TickDuration(10));
|
||||
CHECK(character.GetPosition().x == Catch::Approx(4.f).margin(0.01f));
|
||||
CHECK(statusWallCollision == 1); // It should be close to the wall
|
||||
|
||||
character.SetVelocity(Nz::Vector2f(-2.f, 0.f));
|
||||
for (int i = 0; i != 10; ++i)
|
||||
world.Step(0.1f);
|
||||
world.Step(Nz::Time::TickDuration(10));
|
||||
|
||||
CHECK(statusWallCollision == 3);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
bool userdata = false;
|
||||
body.SetUserdata(&userdata);
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We copy construct the body")
|
||||
{
|
||||
body.AddForce(Nz::Vector2f(3.f, 5.f));
|
||||
Nz::RigidBody2D copiedBody(body);
|
||||
EQUALITY(copiedBody, body);
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
EQUALITY(copiedBody, body);
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
float radius = 5.f;
|
||||
body.SetGeom(std::make_shared<Nz::CircleCollider2D>(radius));
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
THEN("The aabb should be updated")
|
||||
{
|
||||
|
|
@ -96,7 +96,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
tmp.push_back(CreateBody(world));
|
||||
tmp.push_back(CreateBody(world));
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
THEN("They should be valid")
|
||||
{
|
||||
|
|
@ -124,7 +124,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::Vector2f position = Nz::Vector2f::Zero();
|
||||
body.SetPosition(position);
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We retrieve standard information")
|
||||
{
|
||||
|
|
@ -150,7 +150,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::Vector2f velocity(Nz::Vector2f::Unit());
|
||||
body.SetVelocity(velocity);
|
||||
position += velocity;
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
THEN("We expect those to be true")
|
||||
{
|
||||
|
|
@ -164,7 +164,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
AND_THEN("We apply an impulse in the opposite direction")
|
||||
{
|
||||
body.AddImpulse(-velocity);
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
REQUIRE(body.GetVelocity() == Nz::Vector2f::Zero());
|
||||
}
|
||||
|
|
@ -174,23 +174,24 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
{
|
||||
Nz::RadianAnglef angularSpeed = Nz::RadianAnglef::FromDegrees(90.f);
|
||||
body.SetAngularVelocity(angularSpeed);
|
||||
world.Step(1.f);
|
||||
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
THEN("We expect those to be true")
|
||||
{
|
||||
CHECK(body.GetAngularVelocity() == angularSpeed);
|
||||
CHECK(body.GetRotation() == angularSpeed);
|
||||
CHECK(body.GetAABB() == Nz::Rectf(-6.f, 3.f, 2.f, 1.f));
|
||||
CHECK(body.GetAABB().ApproxEquals(Nz::Rectf(-6.f, 3.f, 2.f, 1.f), 0.00001f));
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
CHECK(body.GetRotation() == 2.f * angularSpeed);
|
||||
CHECK(body.GetAABB() == Nz::Rectf(-4.f, -6.f, 1.f, 2.f));
|
||||
CHECK(body.GetAABB().ApproxEquals(Nz::Rectf(-4.f, -6.f, 1.f, 2.f), 0.00001f));
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
CHECK(body.GetRotation() == 3.f * angularSpeed);
|
||||
CHECK(body.GetAABB() == Nz::Rectf(4.f, -4.f, 2.f, 1.f));
|
||||
CHECK(body.GetAABB().ApproxEquals(Nz::Rectf(4.f, -4.f, 2.f, 1.f), 0.00001f));
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
CHECK(body.GetRotation() == 4.f * angularSpeed);
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +199,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
WHEN("We apply a torque")
|
||||
{
|
||||
body.AddTorque(Nz::DegreeAnglef(90.f));
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
THEN("It is also counter-clockwise")
|
||||
{
|
||||
|
|
@ -220,7 +221,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(circle, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We ask for the aabb of the circle")
|
||||
{
|
||||
|
|
@ -251,7 +252,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(compound, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We ask for the aabb of the compound")
|
||||
{
|
||||
|
|
@ -280,7 +281,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(convex, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We ask for the aabb of the convex")
|
||||
{
|
||||
|
|
@ -304,7 +305,7 @@ SCENARIO("RigidBody2D", "[PHYSICS2D][RIGIDBODY2D]")
|
|||
Nz::RigidBody2D body(&world, mass);
|
||||
body.SetGeom(segment, true, false);
|
||||
|
||||
world.Step(1.f);
|
||||
world.Step(Nz::Time::Second());
|
||||
|
||||
WHEN("We ask for the aabb of the segment")
|
||||
{
|
||||
|
|
|
|||
40
xmake.lua
40
xmake.lua
|
|
@ -69,6 +69,14 @@ local modules = {
|
|||
add_packages("libuuid")
|
||||
add_syslinks("dl", "pthread")
|
||||
end
|
||||
|
||||
if is_plat("macosx", "iphoneos") then
|
||||
add_headerfiles("src/Nazara/Core/Darwin/TimeImpl.hpp", { prefixdir = "private", install = false })
|
||||
add_files("src/Nazara/Core/Darwin/TimeImpl.cpp")
|
||||
|
||||
remove_headerfiles("src/Nazara/Core/Posix/TimeImpl.hpp")
|
||||
remove_files("src/Nazara/Core/Posix/TimeImpl.cpp")
|
||||
end
|
||||
end,
|
||||
Packages = { "entt", "frozen" },
|
||||
PublicPackages = { "nazarautils" }
|
||||
|
|
@ -277,26 +285,24 @@ function ModuleTargetConfig(name, module)
|
|||
end
|
||||
|
||||
-- Remove platform-specific files
|
||||
if is_plat("windows", "mingw") then
|
||||
for _, ext in ipairs(headerExts) do
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Posix/**" .. ext)
|
||||
end
|
||||
|
||||
remove_files("src/Nazara/" .. name .. "/Posix/**.cpp")
|
||||
else
|
||||
for _, ext in ipairs(headerExts) do
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Posix/**" .. ext)
|
||||
end
|
||||
|
||||
remove_files("src/Nazara/" .. name .. "/Win32/**.cpp")
|
||||
if not is_plat("windows", "mingw") then
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Win32/**")
|
||||
remove_files("src/Nazara/" .. name .. "/Win32/**")
|
||||
end
|
||||
|
||||
if not is_plat("linux") then
|
||||
for _, ext in ipairs(headerExts) do
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Linux/**" .. ext)
|
||||
end
|
||||
if not is_plat("linux", "android", "cross") then
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Linux/**")
|
||||
remove_files("src/Nazara/" .. name .. "/Linux/**")
|
||||
end
|
||||
|
||||
remove_files("src/Nazara/" .. name .. "/Linux/**.cpp")
|
||||
if not is_plat("macosx", "iphoneos") then
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Darwin/**")
|
||||
remove_files("src/Nazara/" .. name .. "/Darwin/**")
|
||||
end
|
||||
|
||||
if not is_plat("linux", "macosx", "iphoneos", "android", "wasm", "cross") then
|
||||
remove_headerfiles("src/Nazara/" .. name .. "/Posix/**")
|
||||
remove_files("src/Nazara/" .. name .. "/Posix/**")
|
||||
end
|
||||
|
||||
if module.Custom then
|
||||
|
|
|
|||
Loading…
Reference in New Issue