feat(service): added JointsService
This commit is contained in:
parent
0da4d6d67f
commit
86c6890ca1
8 changed files with 102 additions and 24 deletions
|
@ -42,7 +42,7 @@ public:
|
|||
bool isSuccess() { return std::holds_alternative<success_state>(value); }
|
||||
bool isError() { return std::holds_alternative<error_state>(value); }
|
||||
|
||||
std::optional<T_Result> success() { return isSuccess() ? std::get<success_state>(value).success : std::nullopt; }
|
||||
std::optional<T_Result> success() { return isSuccess() ? std::make_optional(std::get<success_state>(value).success) : std::nullopt; }
|
||||
std::optional<std::variant<T_Errors...>> error() { return isError() ? std::make_optional(std::get<error_state>(value).error) : std::nullopt; }
|
||||
|
||||
void logError(Logger::LogLevel logLevel = Logger::LogLevel::ERROR) {
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
template <typename T>
|
||||
result<std::shared_ptr<T>, NoSuchService> GetService(std::string name) {
|
||||
if (services.count(name) != 0)
|
||||
return services[name];
|
||||
return std::dynamic_pointer_cast<T>(services[name]);
|
||||
|
||||
// TODO: Replace this with a result return type
|
||||
if (!INSTANCE_MAP[name] || (INSTANCE_MAP[name]->flags ^ (INSTANCE_NOTCREATABLE | INSTANCE_SERVICE)) != 0) {
|
||||
|
@ -59,13 +59,13 @@ public:
|
|||
services[name] = std::dynamic_pointer_cast<Service>(INSTANCE_MAP[name]->constructor());
|
||||
AddChild(std::dynamic_pointer_cast<Instance>(services[name]));
|
||||
|
||||
return services[name];
|
||||
return std::dynamic_pointer_cast<T>(services[name]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<std::shared_ptr<T>> FindService() {
|
||||
if (services.count(name) != 0)
|
||||
return services[name];
|
||||
return std::dynamic_pointer_cast<T>(services[name]);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
|
23
core/src/objects/jointsservice.cpp
Normal file
23
core/src/objects/jointsservice.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "jointsservice.h"
|
||||
|
||||
const InstanceType JointsService::TYPE = {
|
||||
.super = &Instance::TYPE,
|
||||
.className = "JointsService",
|
||||
.constructor = &JointsService::Create,
|
||||
.flags = INSTANCE_NOTCREATABLE | INSTANCE_SERVICE,
|
||||
};
|
||||
|
||||
const InstanceType* JointsService::GetClass() {
|
||||
return &TYPE;
|
||||
}
|
||||
|
||||
|
||||
JointsService::JointsService(): Service(&TYPE) {
|
||||
}
|
||||
|
||||
JointsService::~JointsService() = default;
|
||||
|
||||
void JointsService::InitService() {
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
}
|
18
core/src/objects/jointsservice.h
Normal file
18
core/src/objects/jointsservice.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "objects/base/service.h"
|
||||
|
||||
class JointsService : public Service {
|
||||
protected:
|
||||
void InitService() override;
|
||||
bool initialized = false;
|
||||
|
||||
public:
|
||||
const static InstanceType TYPE;
|
||||
|
||||
JointsService();
|
||||
~JointsService();
|
||||
|
||||
static inline std::shared_ptr<Instance> Create() { return std::make_shared<JointsService>(); };
|
||||
virtual const InstanceType* GetClass() override;
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
#include "meta.h"
|
||||
#include "objects/jointsservice.h"
|
||||
#include "objects/part.h"
|
||||
#include "objects/snap.h"
|
||||
#include "objects/workspace.h"
|
||||
|
@ -9,4 +10,5 @@ std::map<std::string, const InstanceType*> INSTANCE_MAP = {
|
|||
{ "Workspace", &Workspace::TYPE },
|
||||
{ "DataModel", &DataModel::TYPE },
|
||||
{ "Snap", &Snap::TYPE },
|
||||
{ "JointsService", &JointsService::TYPE },
|
||||
};
|
|
@ -3,6 +3,8 @@
|
|||
#include "datatypes/cframe.h"
|
||||
#include "datatypes/ref.h"
|
||||
#include "datatypes/vector.h"
|
||||
#include "objects/datamodel.h"
|
||||
#include "objects/jointsservice.h"
|
||||
#include "workspace.h"
|
||||
#include "part.h"
|
||||
#include <memory>
|
||||
|
@ -50,43 +52,67 @@ Snap::Snap(): Instance(&TYPE) {
|
|||
Snap::~Snap() {
|
||||
}
|
||||
|
||||
void Snap::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
|
||||
// Remove the existing joint if it does
|
||||
if (this->joint && oldWorkspace) {
|
||||
oldWorkspace.value()->physicsWorld->destroyJoint(this->joint);
|
||||
void Snap::OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) {
|
||||
// If the old workspace existed, and the new one differs, delete the current joint
|
||||
if (this->joint && !this->oldWorkspace.expired() && (!workspace() || workspace().value() != this->oldWorkspace.lock())) {
|
||||
// printf("Broke joint - Removed from workspace\n");
|
||||
oldJointWorkspace.lock()->physicsWorld->destroyJoint(this->joint);
|
||||
this->joint = nullptr;
|
||||
}
|
||||
|
||||
buildJoint();
|
||||
}
|
||||
|
||||
void Snap::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
|
||||
if (!this->joint) return;
|
||||
|
||||
oldWorkspace->physicsWorld->destroyJoint(this->joint);
|
||||
// If the previous parent was JointsService, and now it isn't, delete the joint
|
||||
if (this->joint && !oldParent.expired() && oldParent.lock()->GetClass() == &JointsService::TYPE && (!GetParent() || GetParent() != oldParent.lock())) {
|
||||
// printf("Broke joint - Removed from JointsService\n");
|
||||
oldJointWorkspace.lock()->physicsWorld->destroyJoint(this->joint);
|
||||
this->joint = nullptr;
|
||||
}
|
||||
|
||||
// If the new workspace exists, and the old one differs, create the joint
|
||||
if (!this->joint && workspace() && (oldWorkspace.expired() || oldWorkspace.lock() != workspace().value())) {
|
||||
// printf("Made joint - Added to workspace\n");
|
||||
buildJoint();
|
||||
}
|
||||
|
||||
// If the new parent is JointsService and the previous wasn't, then create the joint
|
||||
if (!this->joint && GetParent() && GetParent().value()->GetClass() == &JointsService::TYPE && (oldParent.expired() || GetParent() != oldParent.lock())) {
|
||||
// printf("Made joint - Added to JointsService\n");
|
||||
buildJoint();
|
||||
}
|
||||
|
||||
this->oldParent = !GetParent() ? std::weak_ptr<Instance>() : GetParent().value();
|
||||
this->oldWorkspace = !workspace() ? std::weak_ptr<Workspace>() : workspace().value();
|
||||
this->oldJointWorkspace = !jointWorkspace() ? std::weak_ptr<Workspace>() : jointWorkspace().value();
|
||||
}
|
||||
|
||||
void Snap::onUpdated(std::string property) {
|
||||
// We are not in the workspace, so we don't really care what values are currently set
|
||||
if (!workspace()) return;
|
||||
if (!jointWorkspace()) return;
|
||||
|
||||
// Workspace cannot have changed, so if the joint currently exists, it is in the present one
|
||||
if (this->joint)
|
||||
workspace().value()->physicsWorld->destroyJoint(this->joint);
|
||||
jointWorkspace().value()->physicsWorld->destroyJoint(this->joint);
|
||||
|
||||
buildJoint();
|
||||
}
|
||||
|
||||
void Snap::buildJoint() {
|
||||
if (part0.expired() || part1.expired() || !workspace()) return;
|
||||
if (part0.expired() || part1.expired() || !jointWorkspace()) return;
|
||||
|
||||
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
||||
// used to be rather than specifying an anchor rotation, so whatever.
|
||||
Data::CFrame newFrame = part0.lock()->cframe * (c1.Inverse() * c0);
|
||||
part1.lock()->cframe = newFrame;
|
||||
workspace().value()->SyncPartPhysics(part1.lock());
|
||||
jointWorkspace().value()->SyncPartPhysics(part1.lock());
|
||||
|
||||
rp::FixedJointInfo jointInfo(part0.lock()->rigidBody, part1.lock()->rigidBody, (c0.Inverse() * c1).Position());
|
||||
this->joint = dynamic_cast<rp::FixedJoint*>(workspace().value()->physicsWorld->createJoint(jointInfo));
|
||||
this->joint = dynamic_cast<rp::FixedJoint*>(jointWorkspace().value()->physicsWorld->createJoint(jointInfo));
|
||||
}
|
||||
|
||||
std::optional<std::shared_ptr<Workspace>> Snap::jointWorkspace() {
|
||||
if (workspace()) return workspace();
|
||||
|
||||
if (GetParent() && GetParent().value()->GetClass() == &JointsService::TYPE)
|
||||
return std::dynamic_pointer_cast<DataModel>(GetParent().value()->GetParent().value())->GetService<Workspace>("Workspace");
|
||||
|
||||
return {};
|
||||
}
|
|
@ -5,13 +5,20 @@
|
|||
#include <optional>
|
||||
|
||||
class Part;
|
||||
class Workspace;
|
||||
|
||||
class Snap : public Instance {
|
||||
rp::FixedJoint* joint = nullptr;
|
||||
protected:
|
||||
void OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) override;
|
||||
void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override;
|
||||
|
||||
std::weak_ptr<Instance> oldParent;
|
||||
// The actual workspace the joint is a part of
|
||||
std::weak_ptr<Workspace> oldWorkspace;
|
||||
// The pseudo-workspace the joint is a part of (including if parented to JointsService)
|
||||
std::weak_ptr<Workspace> oldJointWorkspace;
|
||||
protected:
|
||||
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) override;
|
||||
|
||||
std::optional<std::shared_ptr<Workspace>> jointWorkspace();
|
||||
void onUpdated(std::string property);
|
||||
void buildJoint();
|
||||
void breakJoint();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "./ui_mainwindow.h"
|
||||
#include "common.h"
|
||||
#include "logger.h"
|
||||
#include "objects/jointsservice.h"
|
||||
#include "objects/snap.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
@ -169,7 +170,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
snap->c0 = part1->cframe;
|
||||
snap->c1 = part0->cframe;
|
||||
|
||||
gWorkspace()->AddChild(snap);
|
||||
// gWorkspace()->AddChild(snap);
|
||||
gDataModel->GetService<JointsService>("JointsService").expect()->AddChild(snap);
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* evt) {
|
||||
|
|
Loading…
Add table
Reference in a new issue