Basic mutability framework

This commit is contained in:
Dynamitos
2022-01-12 14:40:26 +01:00
parent b2718dde70
commit 6d48267ec2
72 changed files with 1781 additions and 1341 deletions
+29 -1
View File
@@ -12,8 +12,36 @@ Actor::~Actor()
{
}
void Actor::tick(float)
void Actor::launchStart()
{
rootComponent->launchStart();
for(auto child : children)
{
child->launchStart();
}
start();
}
Array<Job> Actor::launchTick(float deltaTime) const
{
Array<Job> result = rootComponent->launchTick(deltaTime);
for(auto child : children)
{
result.addAll(child->launchTick(deltaTime));
}
result.add(tick(deltaTime));
return result;
}
Array<Job> Actor::launchUpdate()
{
Array<Job> result = rootComponent->launchUpdate();
for(auto child : children)
{
result.addAll(child->launchUpdate());
}
result.add(update());
return result;
}
void Actor::notifySceneAttach(PScene scene)
{
+7 -2
View File
@@ -1,6 +1,7 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Transform.h"
#include "ThreadPool.h"
namespace Seele
{
@@ -12,8 +13,12 @@ class Actor
public:
Actor();
virtual ~Actor();
void tick(float deltaTime);
virtual void launchStart();
virtual void start() {}
Array<Job> launchTick(float deltaTime) const;
virtual Job tick(float deltaTime) const { co_return; }
Array<Job> launchUpdate();
virtual Job update() { co_return; }
void notifySceneAttach(PScene scene);
PScene getScene();
+1
View File
@@ -1,5 +1,6 @@
target_sources(SeeleEngine
PRIVATE
Util.h
Scene.cpp
Scene.h)
@@ -4,6 +4,10 @@ target_sources(SeeleEngine
CameraComponent.cpp
Component.h
Component.cpp
MyComponent.h
MyComponent.cpp
MyOtherComponent.h
MyOtherComponent.cpp
PrimitiveComponent.cpp
PrimitiveComponent.h
PrimitiveUniformBufferLayout.h)
@@ -5,11 +5,16 @@
using namespace Seele;
CameraComponent::CameraComponent()
: bNeedsViewBuild(true)
CameraComponent::CameraComponent()
: aspectRatio(0)
, fieldOfView(0)
, bNeedsViewBuild(true)
, bNeedsProjectionBuild(true)
, originPoint(0, 0, 0)
, cameraPosition(0, 0, 50)
, eye(Vector())
, projectionMatrix(Matrix4())
, viewMatrix(Matrix4())
{
distance = 50;
rotationX = 0;
+49 -11
View File
@@ -13,9 +13,38 @@ Component::Component()
Component::~Component()
{
}
void Component::tick(float)
void Component::launchStart()
{
for(auto child : children)
{
child->launchStart();
}
start();
}
Array<Job> Component::launchTick(float deltaTime) const
{
Array<Job> result;
for(auto child : children)
{
result.addAll(child->launchTick(deltaTime));
}
result.add(tick(deltaTime));
return result;
}
Array<Job> Component::launchUpdate()
{
Array<Job> result;
for(auto child : children)
{
result.addAll(child->launchUpdate());
}
result.add(update());
return result;
}
PComponent Component::getParent()
{
return parent;
@@ -32,6 +61,25 @@ PActor Component::getOwner()
}
return nullptr;
}
const Array<PComponent>& Component::getChildComponents()
{
return children;
}
void Component::setParent(PComponent newParent)
{
parent = newParent;
}
void Component::setOwner(PActor newOwner)
{
owner = newOwner;
}
void Component::addChildComponent(PComponent component)
{
children.add(component);
}
void Component::notifySceneAttach(PScene scene)
{
@@ -118,16 +166,6 @@ Transform Component::getTransform() const
return transform;
}
void Component::setParent(PComponent newParent)
{
parent = newParent;
}
void Component::setOwner(PActor newOwner)
{
owner = newOwner;
}
void Component::internalSetTransform(Vector newLocation, Quaternion newRotation)
{
if (parent != nullptr)
+33 -1
View File
@@ -1,6 +1,8 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Transform.h"
#include "Scene/Util.h"
#include "ThreadPool.h"
namespace Seele
{
@@ -12,11 +14,18 @@ class Component
public:
Component();
virtual ~Component();
void tick(float deltaTime);
void launchStart();
virtual void start() {};
Array<Job> launchTick(float deltaTime) const;
virtual Job tick(float deltaTime) const { co_return; }
Array<Job> launchUpdate();
virtual Job update() { co_return; }
PComponent getParent();
PActor getOwner();
const Array<PComponent>& getChildComponents();
void setParent(PComponent parent);
void setOwner(PActor owner);
void addChildComponent(PComponent component);
virtual void notifySceneAttach(PScene scene);
void setWorldLocation(Vector location);
@@ -35,7 +44,30 @@ public:
Transform getTransform() const;
template<typename ComponentType>
RefPtr<ComponentType> getComponent()
{
return tryFindComponent<ComponentType>();
}
private:
template<typename ComponentType>
RefPtr<ComponentType> tryFindComponent()
{
for(auto child : children)
{
RefPtr<ComponentType> result = child.cast<ComponentType>();
if(result != nullptr)
{
return result;
}
result = parent->tryFindComponent<ComponentType>();
if(result != nullptr)
{
return result;
}
}
return nullptr;
}
void internalSetTransform(Vector newLocation, Quaternion newRotation);
void propagateTransformUpdate();
void updateComponentTransform(Quaternion relativeRotationQuat);
@@ -0,0 +1,26 @@
#include "MyComponent.h"
using namespace Seele;
MyComponent::MyComponent()
{
}
void MyComponent::start()
{
otherComp = getComponent<MyOtherComponent>();
otherComp.update();
}
Job MyComponent::tick(float deltatime) const
{
writable++;
otherComp->data = *writable;
co_return;
}
Job MyComponent::update()
{
writable.update();
co_return;
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "Component.h"
#include "MyOtherComponent.h"
namespace Seele
{
class MyComponent : public Component
{
public:
MyComponent();
virtual void start();
virtual Job tick(float deltatime) const;
virtual Job update();
private:
Writable<PMyOtherComponent> otherComp;
Writable<uint32> writable = Writable<uint32>(0);
uint32 notWritable = 10;
};
DECLARE_REF(MyComponent);
} // namespace Seele
@@ -0,0 +1,15 @@
#include "MyOtherComponent.h"
using namespace Seele;
Job MyOtherComponent::tick(float deltaTime) const
{
std::cout << *data << std::endl;
co_return;
}
Job MyOtherComponent::update()
{
data.update();
co_return;
}
@@ -0,0 +1,15 @@
#pragma once
#include "Component.h"
namespace Seele
{
class MyOtherComponent : public Component
{
public:
virtual Job tick(float deltaTime) const;
virtual Job update();
Writable<uint32> data = Writable<uint32>(0);
private:
};
DEFINE_REF(MyOtherComponent);
} // namespace Seele
@@ -26,7 +26,7 @@ PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
batch.useReverseCulling = false;
batch.useWireframe = false;
batch.vertexInput = assetMeshes[i]->vertexInput;
auto& batchElement = batch.elements.add();
MeshBatchElement batchElement;
batchElement.baseVertexIndex = 0;
batchElement.firstIndex = 0;
batchElement.indexBuffer = assetMeshes[i]->indexBuffer;
@@ -35,6 +35,7 @@ PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
batchElement.isInstanced = false;
batchElement.numInstances = 1;
batchElement.numPrimitives = assetMeshes[i]->indexBuffer->getNumIndices() / 3; //TODO: hardcoded
batch.elements.push_back(batchElement);
}
}
@@ -16,14 +16,14 @@ public:
~PrimitiveComponent();
virtual void notifySceneAttach(PScene scene) override;
Matrix4 getRenderMatrix();
const Array<StaticMeshBatch>& getStaticMeshes()
std::vector<StaticMeshBatch>& getStaticMeshes()
{
return staticMeshes;
}
private:
Array<PMaterialAsset> materials;
std::vector<PMaterialAsset> materials;
Gfx::PUniformBuffer uniformBuffer;
Array<StaticMeshBatch> staticMeshes;
std::vector<StaticMeshBatch> staticMeshes;
friend class Scene;
};
DEFINE_REF(PrimitiveComponent)
+24 -4
View File
@@ -33,19 +33,39 @@ Scene::~Scene()
{
}
void Scene::tick(double)
void Scene::start()
{
for(auto actor : rootActors)
{
actor->launchStart();
}
}
Job Scene::beginUpdate(double deltaTime)
{
for(auto actor : rootActors)
{
co_await Job::all(actor->launchTick(static_cast<float>(deltaTime)));
}
}
Job Scene::commitUpdate()
{
for(auto actor : rootActors)
{
co_await Job::all(actor->launchUpdate());
}
}
void Scene::addActor(PActor actor)
{
rootActors.add(actor);
rootActors.push_back(actor);
actor->notifySceneAttach(this);
}
void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
{
primitives.add(comp);
primitives.push_back(comp);
for(auto& batch : comp->getStaticMeshes())
{
PrimitiveUniformBuffer data;
@@ -62,6 +82,6 @@ void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
{
element.uniformBuffer = uniformBuffer;
}
staticMeshes.add(batch);
staticMeshes.push_back(batch);
}
}
+8 -6
View File
@@ -38,17 +38,19 @@ class Scene
public:
Scene(Gfx::PGraphics graphics);
~Scene();
void tick(double deltaTime);
void start();
Job beginUpdate(double deltaTime);
Job commitUpdate();
void addActor(PActor actor);
void addPrimitiveComponent(PPrimitiveComponent comp);
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
const Array<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
const std::vector<PPrimitiveComponent>& getPrimitives() const { return primitives; }
const std::vector<StaticMeshBatch>& getStaticMeshes() const { return staticMeshes; }
const LightEnv& getLightBuffer() const { return lightEnv; }
private:
Array<StaticMeshBatch> staticMeshes;
Array<PActor> rootActors;
Array<PPrimitiveComponent> primitives;
std::vector<StaticMeshBatch> staticMeshes;
std::vector<PActor> rootActors;
std::vector<PPrimitiveComponent> primitives;
LightEnv lightEnv;
Gfx::PGraphics graphics;
};
+7 -7
View File
@@ -26,25 +26,25 @@ SceneUpdater::~SceneUpdater()
void SceneUpdater::registerComponentUpdate(PComponent component)
{
std::unique_lock lck(pendingUpdatesLock);
std::scoped_lock lck(pendingUpdatesLock);
updatesRan.add([component](float delta) mutable { component->tick(delta); });
}
void SceneUpdater::registerActorUpdate(PActor actor)
{
std::unique_lock lck(pendingUpdatesLock);
std::scoped_lock lck(pendingUpdatesLock);
updatesRan.add([actor](float delta) mutable { actor->tick(delta); });
}
void SceneUpdater::runUpdates(float delta)
{
std::unique_lock pendingLock(pendingUpdatesLock);
std::scoped_lock pendingLock(pendingUpdatesLock);
frameDelta = delta;
pendingUpdates = std::move(updatesRan);
updatesRan = List<std::function<void(float)>>();
std::unique_lock lck(frameFinishedLock);
std::scoped_lock lck(frameFinishedLock);
pendingLock.unlock();
pendingUpdatesSem.release(pendingUpdates.size());
frameFinishedCV.wait(lck);
@@ -57,18 +57,18 @@ void SceneUpdater::work()
pendingUpdatesSem.acquire();
std::function<void(float)> function;
{
std::unique_lock lck(pendingUpdatesLock);
std::scoped_lock lck(pendingUpdatesLock);
function = std::move(pendingUpdates.front());
pendingUpdates.popFront();
if(pendingUpdates.empty())
{
std::unique_lock lck(frameFinishedLock);
std::scoped_lock lck(frameFinishedLock);
frameFinishedCV.notify_all();
}
}
function(frameDelta);
{
std::unique_lock lck(pendingUpdatesLock);
std::scoped_lock lck(pendingUpdatesLock);
updatesRan.add(std::move(function));
}
}
+149
View File
@@ -0,0 +1,149 @@
#pragma once
#include "MinimalEngine.h"
namespace Seele
{
template<typename T>
class Writable
{
public:
Writable()
{}
explicit Writable(T initialData)
: data(initialData)
, toBeWritten(initialData)
{}
Writable(const Writable& other) = delete;
Writable(Writable&& other) = default;
~Writable() = default;
Writable& operator=(const Writable& other) = delete;
Writable& operator=(Writable&& other) = default;
const Writable& operator=(const T& other) const
{
deferWrite(other);
return *this;
}
const Writable& operator=(T&& other) const
{
deferWrite(std::move(other));
return *this;
}
template<typename Other>
const Writable& operator+(Other&& other) const
{
deferWrite(data + std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator-(Other&& other) const
{
deferWrite(data - std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator*(Other&& other) const
{
deferWrite(data * std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator/(Other&& other) const
{
deferWrite(data / std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator%(Other&& other) const
{
deferWrite(data % std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator^(Other&& other) const
{
deferWrite(data ^ std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator&(Other&& other) const
{
deferWrite(data & std::forward<Other>(other));
return *this;
}
template<typename Other>
const Writable& operator|(Other&& other) const
{
deferWrite(data | std::forward<Other>(other));
return *this;
}
template<typename Type>
bool operator==(Type other) const
{
return data == other.data;
}
template<typename Type>
bool operator<=>(Type other) const
{
return data <=> other.data;
}
const Writable& operator++() const
{
deferWrite(data+1);
return *this;
}
const Writable& operator--() const
{
deferWrite(data-1);
return *this;
}
Writable&& operator++(int) const
{
Writable tmp(data);
++*this;
return std::move(tmp);
}
Writable&& operator--(int) const
{
Writable tmp(data);
--*this;
return std::move(tmp);
}
const T& operator*() const
{
return data;
}
const T& get() const
{
return data;
}
const T& operator->() const
{
return data;
}
void update()
{
// lock should not be necessary, but lets keep it for now
std::scoped_lock lock(dataLock);
data = toBeWritten;
dirty = false;
}
private:
template<typename Type>
void deferWrite(Type&& newValue) const
{
std::scoped_lock lock(dataLock);
assert(!dirty);
toBeWritten = std::forward<Type>(newValue);
dirty = true;
}
mutable bool dirty = false;
mutable std::mutex dataLock;
mutable T toBeWritten;
T data;
};
template<typename A>
concept writable = requires(A&& a)
{
a.update();
};
} // namespace Seele