Compare commits
6 Commits
392eaeab83
...
632a23c084
| Author | SHA1 | Date | |
|---|---|---|---|
| 632a23c084 | |||
| 5a16af2696 | |||
| acbc00c6c6 | |||
| d5d459b658 | |||
| ff73cd348e | |||
| 89d5ad5f54 |
@@ -1,9 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <Nazara/Core/EnttWorld.hpp>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
struct AtomicEnttWorld {
|
||||
Nz::EnttWorld& m_World;
|
||||
std::lock_guard<std::mutex> m_LockGuard;
|
||||
|
||||
Nz::EnttWorld* operator->() {
|
||||
return &m_World;
|
||||
}
|
||||
};
|
||||
|
||||
struct EnttWorld {
|
||||
Nz::EnttWorld& m_World;
|
||||
std::mutex m_Mutex;
|
||||
|
||||
/**
|
||||
* \return an AtomicEnttWorld structure which will lock the associated mutex until destruction
|
||||
* \warning Do not hold more than one instance or the current thread will self lock
|
||||
*/
|
||||
operator AtomicEnttWorld() {
|
||||
return {m_World, std::lock_guard<std::mutex>(m_Mutex)};
|
||||
}
|
||||
};
|
||||
|
||||
using EntityID = std::uint32_t;
|
||||
|
||||
} // namespace blitz
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
#include <blitz/network/EnetConnection.h>
|
||||
|
||||
namespace blitz {
|
||||
|
||||
using EnttWorld = std::atomic<std::shared_ptr<Nz::EnttWorld>>;
|
||||
|
||||
namespace protocol {
|
||||
|
||||
class PacketHandler : private NonCopyable {
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace client {
|
||||
|
||||
class Client : private NonCopyable {
|
||||
public:
|
||||
Client(std::shared_ptr<Nz::EnttWorld> a_World);
|
||||
Client(Nz::EnttWorld& a_World);
|
||||
~Client();
|
||||
|
||||
void Connect(const Nz::IpAddress& a_Ip);
|
||||
|
||||
@@ -12,13 +12,15 @@ class Server {
|
||||
* \brief Construct a server
|
||||
* \pre Two instances of Server should not share the same world
|
||||
*/
|
||||
Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World);
|
||||
Server(std::uint16_t a_Port, Nz::EnttWorld& a_World);
|
||||
~Server();
|
||||
|
||||
network::EnetConnection* GetConnection(std::uint16_t a_PeerId);
|
||||
|
||||
void CloseConnection(std::uint16_t a_PeerId);
|
||||
|
||||
void CloseServer();
|
||||
|
||||
private:
|
||||
void HandleConnect(network::EnetConnection&);
|
||||
void HandleDisconnect(network::EnetConnection&);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include <blitz/common/Types.h>
|
||||
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
@@ -10,12 +11,12 @@ class Server;
|
||||
|
||||
class DisconectSystem {
|
||||
public:
|
||||
DisconectSystem(entt::registry& a_Registry, Server& a_Server);
|
||||
DisconectSystem(entt::registry&, EnttWorld& a_World, Server& a_Server);
|
||||
|
||||
void Update(Nz::Time elapsedTime);
|
||||
|
||||
private:
|
||||
entt::registry& m_Registry;
|
||||
EnttWorld& m_World;
|
||||
Server& m_Server;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include <blitz/common/Types.h>
|
||||
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
|
||||
class KeepAliveSystem {
|
||||
public:
|
||||
KeepAliveSystem(entt::registry& a_Registry);
|
||||
KeepAliveSystem(entt::registry&, EnttWorld& a_World);
|
||||
|
||||
void Update(Nz::Time elapsedTime);
|
||||
|
||||
private:
|
||||
entt::registry& m_Registry;
|
||||
EnttWorld& m_World;
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Network.h"
|
||||
|
||||
#include <Nazara/Core.hpp>
|
||||
#include <Nazara/Graphics.hpp>
|
||||
#include <Nazara/Renderer.hpp>
|
||||
#include <Nazara/Platform.hpp>
|
||||
#include <Nazara/Physics3D.hpp>
|
||||
#include <Nazara/Platform.hpp>
|
||||
#include <Nazara/Renderer.hpp>
|
||||
#include <Nazara/Widgets.hpp>
|
||||
#include <random>
|
||||
|
||||
static Nz::Vector3f Get2DDirectionVectorFromRotation(float yaw)
|
||||
{
|
||||
constexpr Nz::UInt32 RenderMaskUI = 0x00010000;
|
||||
constexpr Nz::UInt32 RenderMask3D = 0x0000FFFF;
|
||||
|
||||
static Nz::Vector3f Get2DDirectionVectorFromRotation(float yaw) {
|
||||
return {
|
||||
-std::sin(yaw),
|
||||
0,
|
||||
@@ -18,15 +19,14 @@ static Nz::Vector3f Get2DDirectionVectorFromRotation(float yaw)
|
||||
};
|
||||
}
|
||||
|
||||
static void CreateLight(Nz::EnttWorld &world)
|
||||
{
|
||||
static void CreateLight(Nz::EnttWorld& world) {
|
||||
entt::handle lightEntity = world.CreateEntity();
|
||||
{
|
||||
auto &lightNode = lightEntity.emplace<Nz::NodeComponent>();
|
||||
auto& lightNode = lightEntity.emplace<Nz::NodeComponent>();
|
||||
lightNode.SetPosition({0, 5, 0});
|
||||
|
||||
auto &entityLight = lightEntity.emplace<Nz::LightComponent>();
|
||||
auto &spotLight = entityLight.AddLight<Nz::PointLight>(1);
|
||||
auto& entityLight = lightEntity.emplace<Nz::LightComponent>();
|
||||
auto& spotLight = entityLight.AddLight<Nz::PointLight>(RenderMask3D);
|
||||
spotLight.EnableShadowCasting(true);
|
||||
spotLight.UpdateShadowMapSize(1024);
|
||||
spotLight.UpdateRadius(10.0f);
|
||||
@@ -34,8 +34,7 @@ static void CreateLight(Nz::EnttWorld &world)
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateBoxes(Nz::EnttWorld &world)
|
||||
{
|
||||
static void CreateBoxes(Nz::EnttWorld& world) {
|
||||
constexpr float BoxDims = 1.f;
|
||||
|
||||
std::mt19937 rd(42);
|
||||
@@ -46,8 +45,7 @@ static void CreateBoxes(Nz::EnttWorld &world)
|
||||
std::shared_ptr<Nz::GraphicalMesh> boxMesh = Nz::GraphicalMesh::Build(Nz::Primitive::Box(Nz::Vector3f(1.f)));
|
||||
|
||||
constexpr std::size_t BoxCount = 100;
|
||||
for (std::size_t i = 0; i < BoxCount; ++i)
|
||||
{
|
||||
for (std::size_t i = 0; i < BoxCount; ++i) {
|
||||
float width = lengthDis(rd);
|
||||
float height = lengthDis(rd);
|
||||
float depth = lengthDis(rd);
|
||||
@@ -64,9 +62,9 @@ static void CreateBoxes(Nz::EnttWorld &world)
|
||||
std::shared_ptr<Nz::Model> sphereModel = std::make_shared<Nz::Model>(boxMesh);
|
||||
sphereModel->SetMaterial(0, std::move(boxMaterial));
|
||||
|
||||
boxEntity.emplace<Nz::GraphicsComponent>(std::move(sphereModel));
|
||||
boxEntity.emplace<Nz::GraphicsComponent>(std::move(sphereModel), RenderMask3D);
|
||||
|
||||
auto &ballNode = boxEntity.emplace<Nz::NodeComponent>();
|
||||
auto& ballNode = boxEntity.emplace<Nz::NodeComponent>();
|
||||
ballNode.SetPosition({xRandom(rd), yRandom(rd) + 20.0f, zRandom(rd)});
|
||||
ballNode.SetScale({width, height, depth});
|
||||
|
||||
@@ -80,8 +78,7 @@ static void CreateBoxes(Nz::EnttWorld &world)
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateModel(Nz::EnttWorld &world)
|
||||
{
|
||||
static void CreateModel(Nz::EnttWorld& world) {
|
||||
std::filesystem::path resourceDir = "assets/models";
|
||||
|
||||
Nz::MeshParams meshParams;
|
||||
@@ -91,8 +88,7 @@ static void CreateModel(Nz::EnttWorld &world)
|
||||
meshParams.vertexDeclaration = Nz::VertexDeclaration::Get(Nz::VertexLayout::XYZ_Normal_UV_Tangent);
|
||||
|
||||
std::shared_ptr<Nz::Mesh> deambuMesh = Nz::Mesh::LoadFromFile(resourceDir / "sol.obj", meshParams);
|
||||
if (!deambuMesh)
|
||||
{
|
||||
if (!deambuMesh) {
|
||||
NazaraError("failed to load model");
|
||||
return;
|
||||
}
|
||||
@@ -102,22 +98,21 @@ static void CreateModel(Nz::EnttWorld &world)
|
||||
|
||||
entt::handle deambEntity = world.CreateEntity();
|
||||
{
|
||||
auto &entityGfx = deambEntity.emplace<Nz::GraphicsComponent>();
|
||||
entityGfx.AttachRenderable(deambModel);
|
||||
auto& entityGfx = deambEntity.emplace<Nz::GraphicsComponent>(deambModel, RenderMask3D);
|
||||
// entityGfx.AttachRenderable(deambModel);
|
||||
|
||||
auto &entityNode = deambEntity.emplace<Nz::NodeComponent>();
|
||||
auto& entityNode = deambEntity.emplace<Nz::NodeComponent>();
|
||||
entityNode.SetPosition(Nz::Vector3f(0.f, 0.f, 0.f));
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Graphics::Instance()->GetRenderDevice();
|
||||
|
||||
std::shared_ptr<Nz::MaterialInstance> material = Nz::MaterialInstance::Instantiate(Nz::MaterialType::Phong);
|
||||
for (std::string_view passName : {"DepthPass", "ForwardPass"})
|
||||
{
|
||||
material->UpdatePassStates(passName, [](Nz::RenderStates &states)
|
||||
{
|
||||
for (std::string_view passName : {"DepthPass", "ForwardPass"}) {
|
||||
material->UpdatePassStates(passName, [](Nz::RenderStates& states) {
|
||||
states.depthClamp = true;
|
||||
return true; });
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
std::mt19937 rd(42);
|
||||
@@ -141,46 +136,41 @@ static void CreateModel(Nz::EnttWorld &world)
|
||||
static Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f);
|
||||
static Nz::MillisecondClock updateClock;
|
||||
|
||||
static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window, Nz::Application<Nz::Graphics, Nz::Physics3D> &app)
|
||||
{
|
||||
Nz::RenderSystem &renderSystem = world.AddSystem<Nz::RenderSystem>();
|
||||
|
||||
Nz::SwapchainParameters params;
|
||||
params.presentMode.clear();
|
||||
params.presentMode.push_back(Nz::PresentMode::VerticalSync);
|
||||
|
||||
Nz::WindowSwapchain &windowSwapchain = renderSystem.CreateSwapchain(window, params);
|
||||
|
||||
static void CreateCamera(Nz::EnttWorld& world, Nz::Window& window, Nz::Application<Nz::Graphics, Nz::Physics3D, Nz::Widgets>& app,
|
||||
std::shared_ptr<Nz::RenderWindow>& renderTarget) {
|
||||
// Création de la caméra
|
||||
entt::handle cameraEntity = world.CreateEntity();
|
||||
|
||||
auto &cameraNode = cameraEntity.emplace<Nz::NodeComponent>();
|
||||
auto& cameraNode = cameraEntity.emplace<Nz::NodeComponent>();
|
||||
cameraNode.SetPosition({0, 2.5, 0});
|
||||
|
||||
auto &cameraComponent = cameraEntity.emplace<Nz::CameraComponent>(std::make_shared<Nz::RenderWindow>(windowSwapchain), Nz::ProjectionType::Perspective);
|
||||
auto& cameraComponent = cameraEntity.emplace<Nz::CameraComponent>(renderTarget, Nz::ProjectionType::Perspective);
|
||||
|
||||
cameraComponent.UpdateClearColor(Nz::Color(0.3f, 0.8f, 1.0f));
|
||||
cameraComponent.UpdateZNear(0.1f);
|
||||
cameraComponent.UpdateZFar(100.0f);
|
||||
cameraComponent.UpdateRenderMask(RenderMask3D);
|
||||
cameraComponent.UpdateRenderOrder(-1);
|
||||
|
||||
entt::handle playerEntity = world.CreateEntity();
|
||||
|
||||
auto &playerNode = playerEntity.emplace<Nz::NodeComponent>();
|
||||
auto& playerNode = playerEntity.emplace<Nz::NodeComponent>();
|
||||
playerNode.SetPosition({0, 5, 0});
|
||||
cameraNode.SetParent(playerEntity);
|
||||
|
||||
window.GetEventHandler().OnMouseMoved.Connect([&](const Nz::WindowEventHandler * /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent &event)
|
||||
{
|
||||
constexpr float sensitivity = 0.3f;
|
||||
window.GetEventHandler().OnMouseMoved.Connect(
|
||||
[&](const Nz::WindowEventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event) {
|
||||
constexpr float sensitivity = 0.3f;
|
||||
|
||||
camAngles.yaw -= event.deltaX * sensitivity;
|
||||
camAngles.yaw.Normalize();
|
||||
camAngles.yaw -= event.deltaX * sensitivity;
|
||||
camAngles.yaw.Normalize();
|
||||
|
||||
camAngles.pitch = Nz::Clamp(camAngles.pitch - event.deltaY * sensitivity, -89.f, 89.f);
|
||||
camAngles.pitch = Nz::Clamp(camAngles.pitch - event.deltaY * sensitivity, -89.f, 89.f);
|
||||
|
||||
camAngles.roll = 0.0f;
|
||||
camAngles.roll = 0.0f;
|
||||
|
||||
cameraNode.SetRotation(camAngles);
|
||||
});
|
||||
cameraNode.SetRotation(camAngles);
|
||||
});
|
||||
|
||||
Nz::Vector3f playerSize{0.5, 2, 0.5};
|
||||
|
||||
@@ -193,7 +183,7 @@ static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window, Nz::Applicati
|
||||
|
||||
std::shared_ptr<Nz::Model> sphereModel = std::make_shared<Nz::Model>(boxMesh);
|
||||
sphereModel->SetMaterial(0, std::move(boxMaterial));
|
||||
playerEntity.emplace<Nz::GraphicsComponent>(std::move(sphereModel));
|
||||
playerEntity.emplace<Nz::GraphicsComponent>(std::move(sphereModel), RenderMask3D);
|
||||
}
|
||||
|
||||
std::shared_ptr<Nz::BoxCollider3D> boxCollider = std::make_shared<Nz::BoxCollider3D>(playerSize);
|
||||
@@ -206,18 +196,16 @@ static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window, Nz::Applicati
|
||||
|
||||
playerEntity.emplace<Nz::RigidBody3DComponent>(settings);
|
||||
|
||||
app.AddUpdaterFunc([playerEntity]()
|
||||
{
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::Milliseconds(30)))
|
||||
{
|
||||
app.AddUpdaterFunc([playerEntity]() {
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::Milliseconds(30))) {
|
||||
Nz::Vector3f front = Get2DDirectionVectorFromRotation(camAngles.yaw.ToRadians());
|
||||
Nz::Vector3f left = Get2DDirectionVectorFromRotation(camAngles.yaw.ToRadians() + 3.1415926535/2.0);
|
||||
Nz::Vector3f left = Get2DDirectionVectorFromRotation(camAngles.yaw.ToRadians() + 3.1415926535 / 2.0);
|
||||
|
||||
auto& playerBody = playerEntity.get<Nz::RigidBody3DComponent>();
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z)){
|
||||
std::cout << front << "\n";
|
||||
std::cout << "Pos : " << playerBody.GetPosition() << " \n";
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z)) {
|
||||
// std::cout << front << "\n";
|
||||
// std::cout << "Pos : " << playerBody.GetPosition() << " \n";
|
||||
playerBody.AddForce(front * 10.f * playerMass, Nz::CoordSys::Global);
|
||||
}
|
||||
|
||||
@@ -230,8 +218,8 @@ static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window, Nz::Applicati
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::D))
|
||||
playerBody.AddForce(-left * 10.f * playerMass, Nz::CoordSys::Local);
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Space)){
|
||||
playerBody.AddForce(Nz::Vector3f::Up() * 15.f * playerMass, Nz::CoordSys::Global);
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Space)) {
|
||||
playerBody.AddForce(Nz::Vector3f::Up() * 15.f * playerMass, Nz::CoordSys::Global);
|
||||
}
|
||||
|
||||
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::R)) {
|
||||
@@ -240,28 +228,100 @@ static void CreateCamera(Nz::EnttWorld &world, Nz::Window &window, Nz::Applicati
|
||||
playerBody.SetPosition({0, 10, 0});
|
||||
}
|
||||
|
||||
//playerBody.SetRotation({});
|
||||
} });
|
||||
// playerBody.SetRotation({});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int Video(int argc, char **argv) {
|
||||
Nz::Application<Nz::Graphics, Nz::Physics3D> app(argc, argv);
|
||||
static void SetupWidgets(Nz::EnttWorld& world, std::shared_ptr<Nz::RenderWindow> renderTarget, Nz::Window& window) {
|
||||
entt::handle cameraEntity = world.CreateEntity();
|
||||
{
|
||||
cameraEntity.emplace<Nz::NodeComponent>();
|
||||
|
||||
auto &windowing = app.AddComponent<Nz::WindowingAppComponent>();
|
||||
auto& cameraComponent = cameraEntity.emplace<Nz::CameraComponent>(renderTarget, Nz::ProjectionType::Orthographic);
|
||||
|
||||
cameraComponent.UpdateClearColor(Nz::Color(0.3f, 0.8f, 1.0f, 0.0f));
|
||||
cameraComponent.UpdateRenderMask(RenderMaskUI);
|
||||
cameraComponent.UpdateRenderOrder(1);
|
||||
// cameraComponent.UpdateSize({100, 100});
|
||||
}
|
||||
|
||||
Nz::Canvas canvas(world.GetRegistry(), window.GetEventHandler(), window.GetCursorController().CreateHandle(), RenderMaskUI);
|
||||
canvas.Resize({static_cast<float>(window.GetSize().x), static_cast<float>(window.GetSize().y)});
|
||||
canvas.EnableBackground(false);
|
||||
auto widget = canvas.Add<Nz::RichTextAreaWidget>();
|
||||
widget->EnableBackground(false);
|
||||
widget->EnableLineWrap(true);
|
||||
widget->SetBackgroundColor(Nz::Color(0, 0, 0, 50));
|
||||
widget->SetCharacterSize(22);
|
||||
widget->SetTextColor(Nz::Color::White());
|
||||
widget->SetTextOutlineThickness(1.f);
|
||||
widget->SetReadOnly(true);
|
||||
|
||||
auto m_chatEnteringBox = canvas.Add<Nz::TextAreaWidget>();
|
||||
m_chatEnteringBox->EnableBackground(false);
|
||||
m_chatEnteringBox->SetBackgroundColor(Nz::Color(255, 255, 255, 150));
|
||||
m_chatEnteringBox->SetTextColor(Nz::Color::Black());
|
||||
m_chatEnteringBox->SetText("ceci est un test incroyable");
|
||||
// m_chatEnteringBox->SetMaximumWidth(m_chatEnteringBox->GetPreferredWidth());
|
||||
|
||||
auto versionLabel = canvas.Add<Nz::LabelWidget>();
|
||||
versionLabel->UpdateText(
|
||||
Nz::SimpleTextDrawer::Draw(std::to_string(100000000) + "." + std::to_string(0) + "." + std::to_string(0), 14));
|
||||
versionLabel->Resize({500, 500});
|
||||
versionLabel->SetPosition({1000, 800});
|
||||
versionLabel->SetPosition({canvas.GetWidth() - versionLabel->GetWidth(), canvas.GetHeight() - versionLabel->GetHeight()});
|
||||
|
||||
|
||||
// Création d'un texte
|
||||
Nz::SimpleTextDrawer textDrawer;
|
||||
textDrawer.SetText("Hello world !");
|
||||
textDrawer.SetCharacterSize(72);
|
||||
textDrawer.SetTextOutlineThickness(4.f);
|
||||
|
||||
std::shared_ptr<Nz::TextSprite> textSprite = std::make_shared<Nz::TextSprite>();
|
||||
textSprite->Update(textDrawer);
|
||||
|
||||
entt::handle textEntity = world.CreateEntity();
|
||||
{
|
||||
auto& nodeComponent = textEntity.emplace<Nz::NodeComponent>();
|
||||
|
||||
auto& gfxComponent = textEntity.emplace<Nz::GraphicsComponent>(textSprite, RenderMaskUI);
|
||||
|
||||
Nz::Boxf textBox = textSprite->GetAABB();
|
||||
Nz::Vector2ui windowSize = window.GetSize();
|
||||
nodeComponent.SetPosition({windowSize.x / 2 - textBox.width / 2, windowSize.y / 2 - textBox.height / 2});
|
||||
}
|
||||
}
|
||||
|
||||
int Video(int argc, char** argv) {
|
||||
Nz::Application<Nz::Graphics, Nz::Physics3D, Nz::Widgets> app(argc, argv);
|
||||
|
||||
auto& windowing = app.AddComponent<Nz::WindowingAppComponent>();
|
||||
|
||||
std::string windowTitle = "Blitz 2";
|
||||
Nz::Window &window = windowing.CreateWindow(Nz::VideoMode(1920, 1080, 32), windowTitle);
|
||||
Nz::Window& window = windowing.CreateWindow(Nz::VideoMode(1920, 1080, 32), windowTitle);
|
||||
|
||||
auto &ecs = app.AddComponent<Nz::EntitySystemAppComponent>();
|
||||
auto& ecs = app.AddComponent<Nz::EntitySystemAppComponent>();
|
||||
|
||||
auto &world = ecs.AddWorld<Nz::EnttWorld>();
|
||||
auto& world = ecs.AddWorld<Nz::EnttWorld>();
|
||||
|
||||
auto &physSystem = world.AddSystem<Nz::Physics3DSystem>();
|
||||
auto& physSystem = world.AddSystem<Nz::Physics3DSystem>();
|
||||
physSystem.GetPhysWorld().SetMaxStepCount(1);
|
||||
physSystem.GetPhysWorld().SetStepSize(Nz::Time::Milliseconds(20));
|
||||
physSystem.GetPhysWorld().SetGravity(Nz::Vector3f::Down() * 9.81f);
|
||||
|
||||
CreateCamera(world, window, app);
|
||||
Nz::RenderSystem& renderSystem = world.AddSystem<Nz::RenderSystem>();
|
||||
|
||||
Nz::SwapchainParameters params;
|
||||
params.presentMode.clear();
|
||||
params.presentMode.push_back(Nz::PresentMode::VerticalSync);
|
||||
|
||||
Nz::WindowSwapchain& windowSwapchain = renderSystem.CreateSwapchain(window, params);
|
||||
|
||||
auto renderTarget = std::make_shared<Nz::RenderWindow>(windowSwapchain);
|
||||
|
||||
CreateCamera(world, window, app, renderTarget);
|
||||
CreateBoxes(world);
|
||||
CreateModel(world);
|
||||
CreateLight(world);
|
||||
@@ -271,20 +331,19 @@ int Video(int argc, char **argv) {
|
||||
Nz::MillisecondClock fpsClock;
|
||||
unsigned int fps = 0;
|
||||
|
||||
app.AddUpdaterFunc([&]()
|
||||
{
|
||||
fps++;
|
||||
app.AddUpdaterFunc([&]() {
|
||||
fps++;
|
||||
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||
{
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " + Nz::NumberToString(world.GetAliveEntityCount()) + " entities");
|
||||
if (fpsClock.RestartIfOver(Nz::Time::Second())) {
|
||||
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS" + " - " +
|
||||
Nz::NumberToString(world.GetAliveEntityCount()) + " entities");
|
||||
fps = 0;
|
||||
} });
|
||||
}
|
||||
});
|
||||
|
||||
return app.Run();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
TestNetwork();
|
||||
int main(int argc, char** argv) {
|
||||
return Video(argc, argv);
|
||||
}
|
||||
56
src/ServerMain.cpp
Normal file
56
src/ServerMain.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <server/Server.h>
|
||||
|
||||
#include <Nazara/Core/Application.hpp>
|
||||
#include <Nazara/Core/EntitySystemAppComponent.hpp>
|
||||
#include <Nazara/Network/Network.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void ConsoleLoop(Nz::Application<Nz::Network>& app, blitz::server::Server& server) {
|
||||
std::string line;
|
||||
while (true) {
|
||||
getline(std::cin, line);
|
||||
if (line == "stop") {
|
||||
std::cout << "Exiting ...\n";
|
||||
server.CloseServer();
|
||||
app.Quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::uint16_t DefaultPort = 25565;
|
||||
|
||||
int main(int argc, char* args[]) {
|
||||
Nz::Application<Nz::Network> app(argc, args);
|
||||
|
||||
const auto& params = app.GetCommandLineParameters();
|
||||
|
||||
std::string_view portString;
|
||||
std::uint16_t port = DefaultPort;
|
||||
|
||||
if (params.GetParameter("port", &portString)) {
|
||||
std::cout << "Selected port : " << portString << "\n";
|
||||
bool ok;
|
||||
port = Nz::StringToNumber(portString, 10, &ok);
|
||||
if (!ok) {
|
||||
std::cerr << "Failed to parse port !\n";
|
||||
port = DefaultPort;
|
||||
}
|
||||
}
|
||||
|
||||
auto& ecs = app.AddComponent<Nz::EntitySystemAppComponent>();
|
||||
|
||||
auto& serverWorld = ecs.AddWorld<Nz::EnttWorld>();
|
||||
|
||||
blitz::server::Server server(port, serverWorld);
|
||||
|
||||
std::cout << "Server running on port " << port << " ...\n";
|
||||
|
||||
std::jthread consoleThread([&app, &server]() { ConsoleLoop(app, server); });
|
||||
|
||||
// tick 20 times per seconds
|
||||
app.AddUpdaterFunc([]() { std::this_thread::sleep_for(std::chrono::milliseconds(50)); });
|
||||
|
||||
return app.Run();
|
||||
}
|
||||
@@ -11,9 +11,7 @@
|
||||
namespace blitz {
|
||||
namespace client {
|
||||
|
||||
Client::Client(std::shared_ptr<Nz::EnttWorld> a_World) {
|
||||
m_World.store(a_World);
|
||||
}
|
||||
Client::Client(Nz::EnttWorld& a_World) : m_World({a_World}) {}
|
||||
|
||||
Client::~Client() {
|
||||
Disconnect();
|
||||
|
||||
@@ -11,7 +11,7 @@ LoggingSuccessHandler::LoggingSuccessHandler(network::EnetConnection& a_Connecti
|
||||
}
|
||||
|
||||
void LoggingSuccessHandler::Handle(const blitz::protocol::data::LoggingSuccess& a_LoggingSuccess) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
auto player = world->CreateEntity();
|
||||
player.emplace<LocalPlayerComponent>(a_LoggingSuccess.m_PlayerId);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ PlayerJoinHandler::PlayerJoinHandler(network::EnetConnection& a_Connection, Entt
|
||||
}
|
||||
|
||||
void PlayerJoinHandler::Handle(const protocol::data::PlayerJoin& a_PlayerJoin) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
assert(world->GetRegistry().view<LocalPlayerComponent>().size() == 1 && "There should be only one local player !");
|
||||
|
||||
auto localPlayer = world->GetRegistry().view<LocalPlayerComponent>().front();
|
||||
|
||||
@@ -9,7 +9,7 @@ PlayerLeaveHandler::PlayerLeaveHandler(network::EnetConnection& a_Connection, En
|
||||
}
|
||||
|
||||
void PlayerLeaveHandler::Handle(const protocol::data::PlayerLeave& a_PlayerLeave) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
|
||||
entt::entity playerLeft;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ PlayerListHandler::PlayerListHandler(network::EnetConnection& a_Connection, Entt
|
||||
}
|
||||
|
||||
void PlayerListHandler::Handle(const protocol::data::PlayerList& a_PlayerList) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
for (auto playerInfo : a_PlayerList.m_Players) {
|
||||
auto player = world->CreateEntity();
|
||||
player.emplace<PlayerInfoComponent>(playerInfo);
|
||||
|
||||
@@ -14,8 +14,7 @@ namespace server {
|
||||
|
||||
#define RegisterHandler(Handler) session.m_Handlers.push_back(std::make_unique<Handler>(*session.m_Connection, m_World))
|
||||
|
||||
Server::Server(std::uint16_t a_Port, std::shared_ptr<Nz::EnttWorld> a_World) : m_NetworkServer(a_Port) {
|
||||
m_World.store(a_World);
|
||||
Server::Server(std::uint16_t a_Port, Nz::EnttWorld& a_World) : m_World({a_World}), m_NetworkServer(a_Port) {
|
||||
RegisterSystems();
|
||||
m_NetworkServer.OnClientConnect.Connect(this, &Server::HandleConnect);
|
||||
m_NetworkServer.OnClientDisconnect.Connect(this, &Server::HandleDisconnect);
|
||||
@@ -40,7 +39,7 @@ void Server::HandleDisconnect(network::EnetConnection& a_Connection) {
|
||||
}
|
||||
|
||||
void Server::CreateEntity(network::EnetConnection& a_Connection) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
|
||||
auto entity = world->CreateEntity();
|
||||
|
||||
@@ -48,9 +47,9 @@ void Server::CreateEntity(network::EnetConnection& a_Connection) {
|
||||
}
|
||||
|
||||
void Server::RegisterSystems() {
|
||||
auto world = m_World.load();
|
||||
world->AddSystem<KeepAliveSystem>();
|
||||
world->AddSystem<DisconectSystem>(*this);
|
||||
AtomicEnttWorld world = m_World;
|
||||
world->AddSystem<KeepAliveSystem>(m_World);
|
||||
world->AddSystem<DisconectSystem>(m_World, *this);
|
||||
|
||||
auto counter = world->CreateEntity();
|
||||
counter.emplace<ServerIdCounterComponent>(0);
|
||||
@@ -74,5 +73,11 @@ void Server::CloseConnection(std::uint16_t a_PeerId) {
|
||||
m_NetworkServer.CloseConnection(a_PeerId);
|
||||
}
|
||||
|
||||
void Server::CloseServer() {
|
||||
for (auto& [peerId, session] : m_Sessions) {
|
||||
CloseConnection(peerId);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace server
|
||||
} // namespace blitz
|
||||
|
||||
@@ -16,7 +16,7 @@ KeepAliveHandler::KeepAliveHandler(network::EnetConnection& a_Connection, EnttWo
|
||||
KeepAliveHandler::~KeepAliveHandler() {}
|
||||
|
||||
void KeepAliveHandler::Handle(std::uint16_t a_PeerId, const protocol::data::KeepAlive& a_KeepAlive) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
world->GetRegistry().view<KeepAliveSessionComponent>().each([a_PeerId, &a_KeepAlive](auto& keepAliveSession) {
|
||||
if (keepAliveSession.m_PeerId == a_PeerId && keepAliveSession.m_LastKeepAliveId == a_KeepAlive.m_KeepAliveId) {
|
||||
keepAliveSession.m_LastTime = Nz::GetElapsedMilliseconds();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <server/handlers/PlayerLoginHandler.h>
|
||||
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <blitz/common/Format.h>
|
||||
#include <blitz/common/Log.h>
|
||||
#include <blitz/components/PlayerInfo.h>
|
||||
#include <server/components/EnetConnection.h>
|
||||
#include <server/components/KeepAliveSession.h>
|
||||
@@ -18,7 +20,7 @@ PlayerLoginHandler::PlayerLoginHandler(network::EnetConnection& a_Connection, En
|
||||
PlayerLoginHandler::~PlayerLoginHandler() {}
|
||||
|
||||
void PlayerLoginHandler::Handle(std::uint16_t a_PeerId, const protocol::data::PlayerLogin& a_PlayerLogin) {
|
||||
auto world = m_World.load();
|
||||
AtomicEnttWorld world = m_World;
|
||||
|
||||
std::vector<PlayerInfoComponent> players;
|
||||
|
||||
@@ -62,6 +64,8 @@ void PlayerLoginHandler::Handle(std::uint16_t a_PeerId, const protocol::data::Pl
|
||||
for (auto [entity, connection] : world->GetRegistry().view<EnetConnectionComponent>().each()) {
|
||||
connection.m_Connection->SendPlayerJoin({newPlayer});
|
||||
}
|
||||
|
||||
LogD(Format("[Server] %s joined !", a_PlayerLogin.m_PlayerName.c_str()));
|
||||
}
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -5,32 +5,40 @@
|
||||
|
||||
#include <server/Server.h>
|
||||
|
||||
#include <blitz/common/Format.h>
|
||||
#include <blitz/common/Log.h>
|
||||
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
|
||||
DisconectSystem::DisconectSystem(entt::registry& a_Registry, Server& a_Server) : m_Registry(a_Registry), m_Server(a_Server) {}
|
||||
DisconectSystem::DisconectSystem(entt::registry&, EnttWorld& a_World, Server& a_Server) : m_World(a_World), m_Server(a_Server) {}
|
||||
|
||||
void DisconectSystem::Update(Nz::Time elapsedTime) {
|
||||
auto disconnects = m_Registry.view<DisconnectComponent>();
|
||||
AtomicEnttWorld world = m_World;
|
||||
|
||||
entt::registry& registry = world->GetRegistry();
|
||||
|
||||
auto disconnects = registry.view<DisconnectComponent>();
|
||||
|
||||
// broadcast player leave
|
||||
for (auto entity : disconnects) {
|
||||
auto* player = m_Registry.try_get<PlayerInfoComponent>(entity);
|
||||
auto* player = registry.try_get<PlayerInfoComponent>(entity);
|
||||
if (player) {
|
||||
for (auto [entity, connection] : m_Registry.view<EnetConnectionComponent>().each()) {
|
||||
for (auto [entity, connection] : registry.view<EnetConnectionComponent>().each()) {
|
||||
connection.m_Connection->SendPlayerLeave({player->m_PlayerId});
|
||||
}
|
||||
LogD(Format("[Server] %s left !", player->m_Pseudo.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// close connections
|
||||
m_Registry.view<EnetConnectionComponent, DisconnectComponent>().each(
|
||||
registry.view<EnetConnectionComponent, DisconnectComponent>().each(
|
||||
[this](auto entity, EnetConnectionComponent& connection, DisconnectComponent disconnect) {
|
||||
m_Server.CloseConnection(connection.m_Connection->GetPeerId());
|
||||
});
|
||||
|
||||
// remove the entities
|
||||
m_Registry.destroy(disconnects.begin(), disconnects.end());
|
||||
registry.destroy(disconnects.begin(), disconnects.end());
|
||||
}
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
namespace blitz {
|
||||
namespace server {
|
||||
|
||||
KeepAliveSystem::KeepAliveSystem(entt::registry& a_Registry) : m_Registry(a_Registry) {}
|
||||
KeepAliveSystem::KeepAliveSystem(entt::registry&, EnttWorld& a_World) : m_World(a_World) {}
|
||||
|
||||
void KeepAliveSystem::Update(Nz::Time elapsedTime) {
|
||||
m_Registry.view<KeepAliveSessionComponent, EnetConnectionComponent>().each(
|
||||
[this](auto entity, auto& keepAliveSession, auto& connection) {
|
||||
AtomicEnttWorld world = m_World;
|
||||
|
||||
entt::registry& registry = world->GetRegistry();
|
||||
|
||||
registry.view<KeepAliveSessionComponent, EnetConnectionComponent>().each(
|
||||
[®istry](auto entity, auto& keepAliveSession, auto& connection) {
|
||||
auto duration = Nz::GetElapsedMilliseconds() - keepAliveSession.m_LastTime;
|
||||
if (duration > Nz::Time::Seconds(10)) {
|
||||
if (keepAliveSession.m_RecievedResponse) {
|
||||
@@ -28,7 +32,7 @@ void KeepAliveSystem::Update(Nz::Time elapsedTime) {
|
||||
connection.m_Connection->SendKeepAlive({keepAliveId});
|
||||
} else {
|
||||
// We kick the player because he's not responding anymore
|
||||
m_Registry.emplace<DisconnectComponent>(entity);
|
||||
registry.emplace<DisconnectComponent>(entity);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
31
xmake.lua
31
xmake.lua
@@ -10,20 +10,25 @@ if is_mode("release") then
|
||||
set_warnings("all", "error")
|
||||
end
|
||||
|
||||
target("BlitzLib")
|
||||
set_kind("static")
|
||||
add_files("src/blitz/**.cpp", "src/client/**.cpp", "src/server/**.cpp")
|
||||
add_includedirs("include")
|
||||
add_packages("nazaraengine")
|
||||
add_includedirs("include")
|
||||
|
||||
target("Blitz2")
|
||||
set_kind("binary")
|
||||
add_files("src/*.cpp")
|
||||
add_packages("nazaraengine")
|
||||
add_includedirs("include")
|
||||
add_deps("BlitzLib")
|
||||
set_rundir(".")
|
||||
set_kind("static")
|
||||
add_files("src/blitz/**.cpp", "src/server/**.cpp")
|
||||
add_packages("nazaraengine", {public = true})
|
||||
|
||||
target("Blitz2Server")
|
||||
set_kind("binary")
|
||||
add_deps("Blitz2")
|
||||
set_default(false)
|
||||
add_files("src/ServerMain.cpp")
|
||||
|
||||
|
||||
target("Blitz2Client")
|
||||
set_kind("binary")
|
||||
add_files("src/ClientMain.cpp", "src/client/**.cpp")
|
||||
add_deps("Blitz2")
|
||||
set_rundir(".")
|
||||
|
||||
|
||||
-- Tests were introduced in that version
|
||||
@@ -35,13 +40,11 @@ for _, file in ipairs(os.files("test/**.cpp")) do
|
||||
target(name)
|
||||
set_kind("binary")
|
||||
|
||||
add_includedirs("include", "test")
|
||||
add_files(file)
|
||||
|
||||
set_default(false)
|
||||
|
||||
add_deps("BlitzLib")
|
||||
add_packages("nazaraengine")
|
||||
add_deps("Blitz2")
|
||||
|
||||
add_tests("compile_and_run")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user