refactor(misc): replaced instances of optional<shared_ptr> with nullable shared_ptr
This commit is contained in:
parent
bb81aff4fd
commit
7352b53a94
29 changed files with 139 additions and 146 deletions
|
@ -8,9 +8,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class Instance;
|
class Instance;
|
||||||
// typedef std::function<void(std::shared_ptr<Instance> element, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyUpdateHandler;
|
typedef std::function<void(std::shared_ptr<Instance> object, nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent)> HierarchyPreUpdateHandler;
|
||||||
typedef std::function<void(std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyPreUpdateHandler;
|
typedef std::function<void(std::shared_ptr<Instance> object, nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent)> HierarchyPostUpdateHandler;
|
||||||
typedef std::function<void(std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent)> HierarchyPostUpdateHandler;
|
|
||||||
typedef std::function<void(std::shared_ptr<Instance> instance, std::string property, Variant newValue)> PropertyUpdateHandler;
|
typedef std::function<void(std::shared_ptr<Instance> instance, std::string property, Variant newValue)> PropertyUpdateHandler;
|
||||||
|
|
||||||
// TEMPORARY COMMON DATA FOR VARIOUS INTERNAL COMPONENTS
|
// TEMPORARY COMMON DATA FOR VARIOUS INTERNAL COMPONENTS
|
||||||
|
|
|
@ -151,9 +151,9 @@ static int inst_index(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for child
|
// Look for child
|
||||||
std::optional<std::shared_ptr<Instance>> child = inst->FindFirstChild(key);
|
nullable std::shared_ptr<Instance> child = inst->FindFirstChild(key);
|
||||||
if (child) {
|
if (child) {
|
||||||
InstanceRef(child.value()).PushLuaValue(L);
|
InstanceRef(child).PushLuaValue(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ static int inst_newindex(lua_State* L) {
|
||||||
if (meta->flags & PROP_READONLY)
|
if (meta->flags & PROP_READONLY)
|
||||||
return luaL_error(L, "'%s' of %s is read-only", key.c_str(), inst->GetClass()->className.c_str());
|
return luaL_error(L, "'%s' of %s is read-only", key.c_str(), inst->GetClass()->className.c_str());
|
||||||
if (key == "Parent" && inst->IsParentLocked())
|
if (key == "Parent" && inst->IsParentLocked())
|
||||||
return luaL_error(L, "Cannot set property Parent (%s) of %s, parent is locked", inst->GetParent() ? inst->GetParent().value()->name.c_str() : "NULL", inst->GetClass()->className.c_str());
|
return luaL_error(L, "Cannot set property Parent (%s) of %s, parent is locked", inst->GetParent() ? inst->GetParent()->name.c_str() : "NULL", inst->GetClass()->className.c_str());
|
||||||
|
|
||||||
// TODO: Make this work for enums, this is not a solution!!
|
// TODO: Make this work for enums, this is not a solution!!
|
||||||
result<Variant, LuaCastError> value = meta->type.descriptor->fromLuaValue(L, -1);
|
result<Variant, LuaCastError> value = meta->type.descriptor->fromLuaValue(L, -1);
|
||||||
|
|
|
@ -44,21 +44,16 @@ Instance::Instance(const InstanceType* type) {
|
||||||
Instance::~Instance () {
|
Instance::~Instance () {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::weak_ptr<T> optional_to_weak(std::optional<std::shared_ptr<T>> a) {
|
|
||||||
return a ? a.value() : std::weak_ptr<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Test this
|
// TODO: Test this
|
||||||
bool Instance::ancestryContinuityCheck(std::optional<std::shared_ptr<Instance>> newParent) {
|
bool Instance::ancestryContinuityCheck(nullable std::shared_ptr<Instance> newParent) {
|
||||||
for (std::optional<std::shared_ptr<Instance>> currentParent = newParent; currentParent.has_value(); currentParent = currentParent.value()->GetParent()) {
|
for (std::shared_ptr<Instance> currentParent = newParent; currentParent != nullptr; currentParent = currentParent->GetParent()) {
|
||||||
if (currentParent.value() == this->shared_from_this())
|
if (currentParent == this->shared_from_this())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
|
bool Instance::SetParent(nullable std::shared_ptr<Instance> newParent) {
|
||||||
if (this->parentLocked || !ancestryContinuityCheck(newParent))
|
if (this->parentLocked || !ancestryContinuityCheck(newParent))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -70,10 +65,10 @@ bool Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
|
||||||
oldParent->children.erase(std::find(oldParent->children.begin(), oldParent->children.end(), this->shared_from_this()));
|
oldParent->children.erase(std::find(oldParent->children.begin(), oldParent->children.end(), this->shared_from_this()));
|
||||||
}
|
}
|
||||||
// Add ourselves to the new parent
|
// Add ourselves to the new parent
|
||||||
if (newParent.has_value()) {
|
if (newParent != nullptr) {
|
||||||
newParent.value()->children.push_back(this->shared_from_this());
|
newParent->children.push_back(this->shared_from_this());
|
||||||
}
|
}
|
||||||
this->parent = optional_to_weak(newParent);
|
this->parent = newParent;
|
||||||
// TODO: Add code for sending signals for parent updates
|
// TODO: Add code for sending signals for parent updates
|
||||||
// TODO: Yeahhh maybe this isn't the best way of doing this?
|
// TODO: Yeahhh maybe this isn't the best way of doing this?
|
||||||
if (hierarchyPostUpdateHandler.has_value()) hierarchyPostUpdateHandler.value()(this->shared_from_this(), lastParent, newParent);
|
if (hierarchyPostUpdateHandler.has_value()) hierarchyPostUpdateHandler.value()(this->shared_from_this(), lastParent, newParent);
|
||||||
|
@ -85,21 +80,21 @@ bool Instance::SetParent(std::optional<std::shared_ptr<Instance>> newParent) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::updateAncestry(std::optional<std::shared_ptr<Instance>> updatedChild, std::optional<std::shared_ptr<Instance>> newParent) {
|
void Instance::updateAncestry(nullable std::shared_ptr<Instance> updatedChild, nullable std::shared_ptr<Instance> newParent) {
|
||||||
auto oldDataModel = _dataModel;
|
auto oldDataModel = _dataModel;
|
||||||
auto oldWorkspace = _workspace;
|
auto oldWorkspace = _workspace;
|
||||||
|
|
||||||
// Update parent data model and workspace, if applicable
|
// Update parent data model and workspace, if applicable
|
||||||
if (GetParent()) {
|
if (GetParent() != nullptr) {
|
||||||
this->_dataModel = GetParent().value()->GetClass() == &DataModel::TYPE ? std::dynamic_pointer_cast<DataModel>(GetParent().value()) : GetParent().value()->_dataModel;
|
this->_dataModel = GetParent()->GetClass() == &DataModel::TYPE ? std::dynamic_pointer_cast<DataModel>(GetParent()) : GetParent()->_dataModel;
|
||||||
this->_workspace = GetParent().value()->GetClass() == &Workspace::TYPE ? std::dynamic_pointer_cast<Workspace>(GetParent().value()) : GetParent().value()->_workspace;
|
this->_workspace = GetParent()->GetClass() == &Workspace::TYPE ? std::dynamic_pointer_cast<Workspace>(GetParent()) : GetParent()->_workspace;
|
||||||
} else {
|
} else {
|
||||||
this->_dataModel = {};
|
this->_dataModel = {};
|
||||||
this->_workspace = {};
|
this->_workspace = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
OnAncestryChanged(updatedChild, newParent);
|
OnAncestryChanged(updatedChild, newParent);
|
||||||
AncestryChanged->Fire({updatedChild.has_value() ? InstanceRef(updatedChild.value()) : InstanceRef(), newParent.has_value() ? InstanceRef(newParent.value()) : InstanceRef()});
|
AncestryChanged->Fire({updatedChild != nullptr ? InstanceRef(updatedChild) : InstanceRef(), newParent != nullptr ? InstanceRef(newParent) : InstanceRef()});
|
||||||
|
|
||||||
// Old workspace used to exist, and workspaces differ
|
// Old workspace used to exist, and workspaces differ
|
||||||
if (!oldWorkspace.expired() && oldWorkspace != _workspace) {
|
if (!oldWorkspace.expired() && oldWorkspace != _workspace) {
|
||||||
|
@ -108,7 +103,7 @@ void Instance::updateAncestry(std::optional<std::shared_ptr<Instance>> updatedCh
|
||||||
|
|
||||||
// New workspace exists, and workspaces differ
|
// New workspace exists, and workspaces differ
|
||||||
if (!_workspace.expired() && (_workspace != oldWorkspace)) {
|
if (!_workspace.expired() && (_workspace != oldWorkspace)) {
|
||||||
OnWorkspaceAdded(!oldWorkspace.expired() ? std::make_optional(oldWorkspace.lock()) : std::nullopt, _workspace.lock());
|
OnWorkspaceAdded(oldWorkspace.expired() ? nullptr : oldWorkspace.lock(), _workspace.lock());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update ancestry in descendants
|
// Update ancestry in descendants
|
||||||
|
@ -117,23 +112,22 @@ void Instance::updateAncestry(std::optional<std::shared_ptr<Instance>> updatedCh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<DataModel>> Instance::dataModel() {
|
nullable std::shared_ptr<DataModel> Instance::dataModel() {
|
||||||
return (_dataModel.expired()) ? std::nullopt : std::make_optional(_dataModel.lock());
|
return _dataModel.expired() ? nullptr : _dataModel.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Workspace>> Instance::workspace() {
|
nullable std::shared_ptr<Workspace> Instance::workspace() {
|
||||||
return (_workspace.expired()) ? std::nullopt : std::make_optional(_workspace.lock());
|
return _workspace.expired() ? nullptr : _workspace.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Instance>> Instance::GetParent() {
|
nullable std::shared_ptr<Instance> Instance::GetParent() {
|
||||||
if (parent.expired()) return std::nullopt;
|
return parent.expired() ? nullptr : parent.lock();
|
||||||
return parent.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::Destroy() {
|
void Instance::Destroy() {
|
||||||
if (parentLocked) return;
|
if (parentLocked) return;
|
||||||
// TODO: Implement proper distruction stuff
|
// TODO: Implement proper distruction stuff
|
||||||
SetParent(std::nullopt);
|
SetParent(nullptr);
|
||||||
parentLocked = true;
|
parentLocked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,12 +137,12 @@ bool Instance::IsA(std::string className) {
|
||||||
return cur != nullptr;
|
return cur != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Instance>> Instance::FindFirstChild(std::string name) {
|
nullable std::shared_ptr<Instance> Instance::FindFirstChild(std::string name) {
|
||||||
for (auto child : children) {
|
for (auto child : children) {
|
||||||
if (child->name == name)
|
if (child->name == name)
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<Instance> DUMMY_INSTANCE;
|
static std::shared_ptr<Instance> DUMMY_INSTANCE;
|
||||||
|
@ -164,15 +158,15 @@ bool Instance::IsParentLocked() {
|
||||||
return this->parentLocked;
|
return this->parentLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) {
|
void Instance::OnParentUpdated(nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent) {
|
||||||
// Empty stub
|
// Empty stub
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) {
|
void Instance::OnAncestryChanged(nullable std::shared_ptr<Instance> child, nullable std::shared_ptr<Instance> newParent) {
|
||||||
// Empty stub
|
// Empty stub
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
|
void Instance::OnWorkspaceAdded(nullable std::shared_ptr<Workspace> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
|
||||||
// Empty stub
|
// Empty stub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +224,7 @@ fallible<MemberNotFound, AssignToReadOnlyMember> Instance::InternalSetPropertyVa
|
||||||
this->name = (std::string)value.get<std::string>();
|
this->name = (std::string)value.get<std::string>();
|
||||||
} else if (name == "Parent") {
|
} else if (name == "Parent") {
|
||||||
std::weak_ptr<Instance> ref = value.get<InstanceRef>();
|
std::weak_ptr<Instance> ref = value.get<InstanceRef>();
|
||||||
SetParent(ref.expired() ? std::nullopt : std::make_optional(ref.lock()));
|
SetParent(ref.expired() ? nullptr : ref.lock());
|
||||||
} else if (name == "ClassName") {
|
} else if (name == "ClassName") {
|
||||||
return AssignToReadOnlyMember(GetClass()->className, name);
|
return AssignToReadOnlyMember(GetClass()->className, name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -430,9 +424,9 @@ DescendantsIterator::self_type DescendantsIterator::operator++(int _) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've hit the end of this item's children, move one up
|
// If we've hit the end of this item's children, move one up
|
||||||
while (current->GetParent() && current->GetParent().value()->GetChildren().size() <= size_t(siblingIndex.back() + 1)) {
|
while (current->GetParent() != nullptr && current->GetParent()->GetChildren().size() <= size_t(siblingIndex.back() + 1)) {
|
||||||
siblingIndex.pop_back();
|
siblingIndex.pop_back();
|
||||||
current = current->GetParent().value();
|
current = current->GetParent();
|
||||||
|
|
||||||
// But not if one up is null or the root element
|
// But not if one up is null or the root element
|
||||||
if (!current->GetParent() || current == root) {
|
if (!current->GetParent() || current == root) {
|
||||||
|
@ -443,12 +437,12 @@ DescendantsIterator::self_type DescendantsIterator::operator++(int _) {
|
||||||
|
|
||||||
// Now move to the next sibling
|
// Now move to the next sibling
|
||||||
siblingIndex.back()++;
|
siblingIndex.back()++;
|
||||||
current = current->GetParent().value()->GetChildren()[siblingIndex.back()];
|
current = current->GetParent()->GetChildren()[siblingIndex.back()];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Instance>> Instance::Clone(RefStateClone state) {
|
nullable std::shared_ptr<Instance> Instance::Clone(RefStateClone state) {
|
||||||
if (state == nullptr) state = std::make_shared<__RefStateClone>();
|
if (state == nullptr) state = std::make_shared<__RefStateClone>();
|
||||||
std::shared_ptr<Instance> newInstance = GetClass()->constructor();
|
std::shared_ptr<Instance> newInstance = GetClass()->constructor();
|
||||||
|
|
||||||
|
@ -494,9 +488,9 @@ std::optional<std::shared_ptr<Instance>> Instance::Clone(RefStateClone state) {
|
||||||
|
|
||||||
// Clone children
|
// Clone children
|
||||||
for (std::shared_ptr<Instance> child : GetChildren()) {
|
for (std::shared_ptr<Instance> child : GetChildren()) {
|
||||||
std::optional<std::shared_ptr<Instance>> clonedChild = child->Clone(state);
|
nullable std::shared_ptr<Instance> clonedChild = child->Clone(state);
|
||||||
if (clonedChild)
|
if (clonedChild)
|
||||||
newInstance->AddChild(clonedChild.value());
|
newInstance->AddChild(clonedChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newInstance;
|
return newInstance;
|
||||||
|
@ -521,12 +515,12 @@ std::vector<std::pair<std::string, std::shared_ptr<Instance>>> Instance::GetRefe
|
||||||
|
|
||||||
std::string Instance::GetFullName() {
|
std::string Instance::GetFullName() {
|
||||||
std::string currentName = name;
|
std::string currentName = name;
|
||||||
std::optional<std::shared_ptr<Instance>> currentParent = GetParent();
|
nullable std::shared_ptr<Instance> currentParent = GetParent();
|
||||||
|
|
||||||
while (currentParent.has_value() && !currentParent.value()->IsA("DataModel")) {
|
while (currentParent && !currentParent->IsA("DataModel")) {
|
||||||
currentName = currentParent.value()->name + "." + currentName;
|
currentName = currentParent->name + "." + currentName;
|
||||||
|
|
||||||
currentParent = currentParent.value()->GetParent();
|
currentParent = currentParent->GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentName;
|
return currentName;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "error/result.h"
|
#include "error/result.h"
|
||||||
#include "member.h"
|
#include "member.h"
|
||||||
#include "objects/base/refstate.h"
|
#include "objects/base/refstate.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
class Instance;
|
class Instance;
|
||||||
typedef std::shared_ptr<Instance>(*InstanceConstructor)();
|
typedef std::shared_ptr<Instance>(*InstanceConstructor)();
|
||||||
|
@ -59,8 +60,8 @@ private:
|
||||||
std::weak_ptr<DataModel> _dataModel;
|
std::weak_ptr<DataModel> _dataModel;
|
||||||
std::weak_ptr<Workspace> _workspace;
|
std::weak_ptr<Workspace> _workspace;
|
||||||
|
|
||||||
bool ancestryContinuityCheck(std::optional<std::shared_ptr<Instance>> newParent);
|
bool ancestryContinuityCheck(nullable std::shared_ptr<Instance> newParent);
|
||||||
void updateAncestry(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent);
|
void updateAncestry(nullable std::shared_ptr<Instance> child, nullable std::shared_ptr<Instance> newParent);
|
||||||
|
|
||||||
friend JointInstance; // This isn't ideal, but oh well
|
friend JointInstance; // This isn't ideal, but oh well
|
||||||
protected:
|
protected:
|
||||||
|
@ -75,17 +76,17 @@ protected:
|
||||||
virtual void InternalUpdateProperty(std::string name);
|
virtual void InternalUpdateProperty(std::string name);
|
||||||
virtual std::vector<std::string> InternalGetProperties();
|
virtual std::vector<std::string> InternalGetProperties();
|
||||||
|
|
||||||
virtual void OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent);
|
virtual void OnParentUpdated(nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent);
|
||||||
virtual void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent);
|
virtual void OnAncestryChanged(nullable std::shared_ptr<Instance> child, nullable std::shared_ptr<Instance> newParent);
|
||||||
virtual void OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace);
|
virtual void OnWorkspaceAdded(nullable std::shared_ptr<Workspace> oldWorkspace, std::shared_ptr<Workspace> newWorkspace);
|
||||||
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace);
|
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace);
|
||||||
|
|
||||||
// The root data model this object is a descendant of
|
// The root data model this object is a descendant of
|
||||||
std::optional<std::shared_ptr<DataModel>> dataModel();
|
nullable std::shared_ptr<DataModel> dataModel();
|
||||||
// The root workspace this object is a descendant of
|
// The root workspace this object is a descendant of
|
||||||
// NOTE: This value is not necessarily present if dataModel is present
|
// NOTE: This value is not necessarily present if dataModel is present
|
||||||
// Objects under services other than workspace will NOT have this field set
|
// Objects under services other than workspace will NOT have this field set
|
||||||
std::optional<std::shared_ptr<Workspace>> workspace();
|
nullable std::shared_ptr<Workspace> workspace();
|
||||||
public:
|
public:
|
||||||
const static InstanceType TYPE;
|
const static InstanceType TYPE;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -96,8 +97,8 @@ public:
|
||||||
// Instance is abstract, so it should not implement GetClass directly
|
// Instance is abstract, so it should not implement GetClass directly
|
||||||
virtual const InstanceType* GetClass() = 0;
|
virtual const InstanceType* GetClass() = 0;
|
||||||
static void PushLuaLibrary(lua_State*); // Defined in lua/instancelib.cpp
|
static void PushLuaLibrary(lua_State*); // Defined in lua/instancelib.cpp
|
||||||
bool SetParent(std::optional<std::shared_ptr<Instance>> newParent);
|
bool SetParent(nullable std::shared_ptr<Instance> newParent);
|
||||||
std::optional<std::shared_ptr<Instance>> GetParent();
|
nullable std::shared_ptr<Instance> GetParent();
|
||||||
bool IsParentLocked();
|
bool IsParentLocked();
|
||||||
inline const std::vector<std::shared_ptr<Instance>> GetChildren() { return children; }
|
inline const std::vector<std::shared_ptr<Instance>> GetChildren() { return children; }
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
@ -111,7 +112,7 @@ public:
|
||||||
DescendantsIterator GetDescendantsEnd();
|
DescendantsIterator GetDescendantsEnd();
|
||||||
// Utility functions
|
// Utility functions
|
||||||
inline void AddChild(std::shared_ptr<Instance> object) { object->SetParent(this->shared_from_this()); }
|
inline void AddChild(std::shared_ptr<Instance> object) { object->SetParent(this->shared_from_this()); }
|
||||||
std::optional<std::shared_ptr<Instance>> FindFirstChild(std::string);
|
nullable std::shared_ptr<Instance> FindFirstChild(std::string);
|
||||||
std::string GetFullName();
|
std::string GetFullName();
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
@ -136,7 +137,7 @@ public:
|
||||||
// Serialization
|
// Serialization
|
||||||
void Serialize(pugi::xml_node parent, RefStateSerialize state = {});
|
void Serialize(pugi::xml_node parent, RefStateSerialize state = {});
|
||||||
static result<std::shared_ptr<Instance>, NoSuchInstance> Deserialize(pugi::xml_node node, RefStateDeserialize state = {});
|
static result<std::shared_ptr<Instance>, NoSuchInstance> Deserialize(pugi::xml_node node, RefStateDeserialize state = {});
|
||||||
std::optional<std::shared_ptr<Instance>> Clone(RefStateClone state = {});
|
nullable std::shared_ptr<Instance> Clone(RefStateClone state = {});
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://gist.github.com/jeetsukumaran/307264
|
// https://gist.github.com/jeetsukumaran/307264
|
||||||
|
@ -158,7 +159,7 @@ public:
|
||||||
|
|
||||||
self_type operator++(int _);
|
self_type operator++(int _);
|
||||||
private:
|
private:
|
||||||
std::optional<std::shared_ptr<Instance>> root;
|
nullable std::shared_ptr<Instance> root;
|
||||||
std::shared_ptr<Instance> current;
|
std::shared_ptr<Instance> current;
|
||||||
std::vector<int> siblingIndex;
|
std::vector<int> siblingIndex;
|
||||||
};
|
};
|
|
@ -7,9 +7,9 @@
|
||||||
Service::Service(const InstanceType* type) : Instance(type) {}
|
Service::Service(const InstanceType* type) : Instance(type) {}
|
||||||
|
|
||||||
// Fail if parented to non-datamodel, otherwise lock parent
|
// Fail if parented to non-datamodel, otherwise lock parent
|
||||||
void Service::OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) {
|
void Service::OnParentUpdated(nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent) {
|
||||||
if (!newParent || newParent.value()->GetClass() != &DataModel::TYPE) {
|
if (!newParent || newParent->GetClass() != &DataModel::TYPE) {
|
||||||
Logger::fatalErrorf("Service %s was parented to object of type %s", GetClass()->className.c_str(), newParent ? newParent.value()->GetClass()->className.c_str() : "NULL");
|
Logger::fatalErrorf("Service %s was parented to object of type %s", GetClass()->className.c_str(), newParent ? newParent->GetClass()->className.c_str() : "NULL");
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ protected:
|
||||||
virtual void InitService();
|
virtual void InitService();
|
||||||
virtual void OnRun();
|
virtual void OnRun();
|
||||||
|
|
||||||
void OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) override;
|
void OnParentUpdated(nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent) override;
|
||||||
|
|
||||||
friend class DataModel;
|
friend class DataModel;
|
||||||
};
|
};
|
|
@ -107,14 +107,14 @@ result<std::shared_ptr<Service>, NoSuchService> DataModel::GetService(std::strin
|
||||||
return std::dynamic_pointer_cast<Service>(services[className]);
|
return std::dynamic_pointer_cast<Service>(services[className]);
|
||||||
}
|
}
|
||||||
|
|
||||||
result<std::optional<std::shared_ptr<Service>>, NoSuchService> DataModel::FindService(std::string className) {
|
result<nullable std::shared_ptr<Service>, NoSuchService> DataModel::FindService(std::string className) {
|
||||||
if (!INSTANCE_MAP[className] || (INSTANCE_MAP[className]->flags ^ (INSTANCE_NOTCREATABLE | INSTANCE_SERVICE)) != 0) {
|
if (!INSTANCE_MAP[className] || (INSTANCE_MAP[className]->flags ^ (INSTANCE_NOTCREATABLE | INSTANCE_SERVICE)) != 0) {
|
||||||
return NoSuchService(className);
|
return NoSuchService(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (services.count(className) != 0)
|
if (services.count(className) != 0)
|
||||||
return std::make_optional(std::dynamic_pointer_cast<Service>(services[className]));
|
return std::dynamic_pointer_cast<Service>(services[className]);
|
||||||
return (std::optional<std::shared_ptr<Service>>)std::nullopt;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<DataModel> DataModel::CloneModel() {
|
std::shared_ptr<DataModel> DataModel::CloneModel() {
|
||||||
|
@ -166,11 +166,11 @@ std::shared_ptr<DataModel> DataModel::CloneModel() {
|
||||||
if (!result)
|
if (!result)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
newModel->AddChild(result.value());
|
newModel->AddChild(result);
|
||||||
|
|
||||||
// Special case: Ignore instances parented to DataModel which are not services
|
// Special case: Ignore instances parented to DataModel which are not services
|
||||||
if (child->GetClass()->flags & INSTANCE_SERVICE) {
|
if (child->GetClass()->flags & INSTANCE_SERVICE) {
|
||||||
newModel->services[child->GetClass()->className] = std::dynamic_pointer_cast<Service>(result.value());
|
newModel->services[child->GetClass()->className] = std::dynamic_pointer_cast<Service>(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
static inline std::shared_ptr<DataModel> New() { return std::make_shared<DataModel>(); };
|
static inline std::shared_ptr<DataModel> New() { return std::make_shared<DataModel>(); };
|
||||||
|
|
||||||
result<std::shared_ptr<Service>, NoSuchService> GetService(std::string className);
|
result<std::shared_ptr<Service>, NoSuchService> GetService(std::string className);
|
||||||
result<std::optional<std::shared_ptr<Service>>, NoSuchService> FindService(std::string className);
|
result<nullable std::shared_ptr<Service>, NoSuchService> FindService(std::string className);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::shared_ptr<T> GetService() {
|
std::shared_ptr<T> GetService() {
|
||||||
|
@ -38,10 +38,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::optional<std::shared_ptr<T>> FindService() {
|
nullable std::shared_ptr<T> FindService() {
|
||||||
auto result = FindService(T::TYPE.className).expect("FindService<T>() was called with a non-service instance type");
|
auto result = FindService(T::TYPE.className).expect("FindService<T>() was called with a non-service instance type");
|
||||||
if (!result) return std::nullopt;
|
if (!result) return nullptr;
|
||||||
return std::dynamic_pointer_cast<T>(result.value());
|
return std::dynamic_pointer_cast<T>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saving/loading
|
// Saving/loading
|
||||||
|
|
|
@ -17,7 +17,7 @@ JointInstance::JointInstance(const InstanceType* type): Instance(type) {
|
||||||
JointInstance::~JointInstance() {
|
JointInstance::~JointInstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void JointInstance::OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) {
|
void JointInstance::OnAncestryChanged(nullable std::shared_ptr<Instance>, nullable std::shared_ptr<Instance>) {
|
||||||
// Destroy and rebuild the joint, it's the simplest solution that actually works
|
// Destroy and rebuild the joint, it's the simplest solution that actually works
|
||||||
|
|
||||||
breakJoint();
|
breakJoint();
|
||||||
|
@ -54,6 +54,6 @@ void JointInstance::onUpdated(std::string property) {
|
||||||
oldPart1 = part1;
|
oldPart1 = part1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Workspace>> JointInstance::workspaceOfPart(std::shared_ptr<BasePart> part) {
|
nullable std::shared_ptr<Workspace> JointInstance::workspaceOfPart(std::shared_ptr<BasePart> part) {
|
||||||
return part->workspace();
|
return part->workspace();
|
||||||
}
|
}
|
|
@ -23,9 +23,9 @@ protected:
|
||||||
// The workspace the joint was created in, if it exists
|
// The workspace the joint was created in, if it exists
|
||||||
std::weak_ptr<Workspace> jointWorkspace;
|
std::weak_ptr<Workspace> jointWorkspace;
|
||||||
|
|
||||||
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) override;
|
void OnAncestryChanged(nullable std::shared_ptr<Instance>, nullable std::shared_ptr<Instance>) override;
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Workspace>> workspaceOfPart(std::shared_ptr<BasePart>);
|
nullable std::shared_ptr<Workspace> workspaceOfPart(std::shared_ptr<BasePart>);
|
||||||
void onUpdated(std::string property);
|
void onUpdated(std::string property);
|
||||||
virtual void buildJoint() = 0;
|
virtual void buildJoint() = 0;
|
||||||
virtual void breakJoint() = 0;
|
virtual void breakJoint() = 0;
|
||||||
|
|
|
@ -17,9 +17,9 @@ void Rotate::buildJoint() {
|
||||||
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
||||||
|
|
||||||
// Don't build the joint if we're not part of either a workspace or JointsService
|
// Don't build the joint if we're not part of either a workspace or JointsService
|
||||||
if ((!GetParent() || GetParent().value()->GetClass() != &JointsService::TYPE) && !workspace()) return;
|
if ((!GetParent() || GetParent()->GetClass() != &JointsService::TYPE) && workspace() != nullptr) return;
|
||||||
|
|
||||||
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock()).value();
|
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock());
|
||||||
|
|
||||||
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
// 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.
|
// used to be rather than specifying an anchor rotation, so whatever.
|
||||||
|
|
|
@ -19,9 +19,9 @@ void RotateV::buildJoint() {
|
||||||
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
||||||
|
|
||||||
// Don't build the joint if we're not part of either a workspace or JointsService
|
// Don't build the joint if we're not part of either a workspace or JointsService
|
||||||
if ((!GetParent() || GetParent().value()->GetClass() != &JointsService::TYPE) && !workspace()) return;
|
if ((!GetParent() || GetParent()->GetClass() != &JointsService::TYPE) && workspace() != nullptr) return;
|
||||||
|
|
||||||
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock()).value();
|
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock());
|
||||||
|
|
||||||
|
|
||||||
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
||||||
|
|
|
@ -21,9 +21,9 @@ void Snap::buildJoint() {
|
||||||
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
||||||
|
|
||||||
// Don't build the joint if we're not part of either a workspace or JointsService
|
// Don't build the joint if we're not part of either a workspace or JointsService
|
||||||
if ((!GetParent() || GetParent().value()->GetClass() != &JointsService::TYPE) && !workspace()) return;
|
if ((!GetParent() || GetParent()->GetClass() != &JointsService::TYPE) && !workspace()) return;
|
||||||
|
|
||||||
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock()).value();
|
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock());
|
||||||
|
|
||||||
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
// 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.
|
// used to be rather than specifying an anchor rotation, so whatever.
|
||||||
|
|
|
@ -21,9 +21,9 @@ void Weld::buildJoint() {
|
||||||
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
if (part0.expired() || part1.expired() || part0.lock() == part1.lock() || !workspaceOfPart(part0.lock()) || workspaceOfPart(part0.lock()) != workspaceOfPart(part1.lock())) return;
|
||||||
|
|
||||||
// Don't build the joint if we're not part of either a workspace or JointsService
|
// Don't build the joint if we're not part of either a workspace or JointsService
|
||||||
if ((!GetParent() || GetParent().value()->GetClass() != &JointsService::TYPE) && !workspace()) return;
|
if ((!GetParent() || GetParent()->GetClass() != &JointsService::TYPE) && workspace() != nullptr) return;
|
||||||
|
|
||||||
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock()).value();
|
std::shared_ptr<Workspace> workspace = workspaceOfPart(part0.lock());
|
||||||
|
|
||||||
// Update Part1's rotation and cframe prior to creating the joint as reactphysics3d locks rotation based on how it
|
// 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.
|
// used to be rather than specifying an anchor rotation, so whatever.
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "objects/joint/snap.h"
|
#include "objects/joint/snap.h"
|
||||||
#include "rendering/renderer.h"
|
#include "rendering/renderer.h"
|
||||||
#include "enum/surface.h"
|
#include "enum/surface.h"
|
||||||
#include <cstdio>
|
|
||||||
#include <glm/common.hpp>
|
#include <glm/common.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -28,18 +27,18 @@ BasePart::BasePart(const InstanceType* type, PartConstructParams params): PVInst
|
||||||
|
|
||||||
BasePart::~BasePart() {
|
BasePart::~BasePart() {
|
||||||
// This relies on physicsCommon still existing. Be very careful.
|
// This relies on physicsCommon still existing. Be very careful.
|
||||||
if (this->rigidBody && workspace()) {
|
if (this->rigidBody && workspace() != nullptr) {
|
||||||
workspace().value()->RemoveBody(shared<BasePart>());
|
workspace()->RemoveBody(shared<BasePart>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BasePart::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) {
|
void BasePart::OnAncestryChanged(nullable std::shared_ptr<Instance> child, nullable std::shared_ptr<Instance> newParent) {
|
||||||
if (this->rigidBody)
|
if (this->rigidBody)
|
||||||
this->rigidBody->setIsActive(workspace().has_value());
|
this->rigidBody->setIsActive(workspace() != nullptr);
|
||||||
|
|
||||||
if (workspace())
|
if (workspace() != nullptr)
|
||||||
workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
|
workspace()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
|
||||||
|
|
||||||
// Destroy joints
|
// Destroy joints
|
||||||
if (!workspace()) BreakJoints();
|
if (!workspace()) BreakJoints();
|
||||||
|
@ -47,7 +46,7 @@ void BasePart::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child,
|
||||||
// TODO: Sleeping bodies that touch this one also need to be updated
|
// TODO: Sleeping bodies that touch this one also need to be updated
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePart::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
|
void BasePart::OnWorkspaceAdded(nullable std::shared_ptr<Workspace> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
|
||||||
newWorkspace->AddBody(shared<BasePart>());
|
newWorkspace->AddBody(shared<BasePart>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +57,8 @@ void BasePart::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
|
||||||
void BasePart::onUpdated(std::string property) {
|
void BasePart::onUpdated(std::string property) {
|
||||||
bool reset = property == "Position" || property == "Rotation" || property == "CFrame" || property == "Size" || property == "Shape";
|
bool reset = property == "Position" || property == "Rotation" || property == "CFrame" || property == "Size" || property == "Shape";
|
||||||
|
|
||||||
if (workspace())
|
if (workspace() != nullptr)
|
||||||
workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
|
workspace()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
|
||||||
|
|
||||||
// When position/rotation/size is manually edited, break all joints, they don't apply anymore
|
// When position/rotation/size is manually edited, break all joints, they don't apply anymore
|
||||||
if (reset)
|
if (reset)
|
||||||
|
@ -204,7 +203,7 @@ bool BasePart::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3
|
||||||
return horizOverlap && vertOverlap;
|
return horizOverlap && vertOverlap;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<JointInstance>> makeJointFromSurfaces(SurfaceType a, SurfaceType b) {
|
nullable std::shared_ptr<JointInstance> makeJointFromSurfaces(SurfaceType a, SurfaceType b) {
|
||||||
if (a == SurfaceType::Weld || b == SurfaceType::Weld || a == SurfaceType::Glue || b == SurfaceType::Glue) return Weld::New();
|
if (a == SurfaceType::Weld || b == SurfaceType::Weld || a == SurfaceType::Glue || b == SurfaceType::Glue) return Weld::New();
|
||||||
if ((a == SurfaceType::Studs && (b == SurfaceType::Inlet || b == SurfaceType::Universal))
|
if ((a == SurfaceType::Studs && (b == SurfaceType::Inlet || b == SurfaceType::Universal))
|
||||||
|| (a == SurfaceType::Inlet && (b == SurfaceType::Studs || b == SurfaceType::Universal))
|
|| (a == SurfaceType::Inlet && (b == SurfaceType::Studs || b == SurfaceType::Universal))
|
||||||
|
@ -214,7 +213,7 @@ std::optional<std::shared_ptr<JointInstance>> makeJointFromSurfaces(SurfaceType
|
||||||
return Rotate::New();
|
return Rotate::New();
|
||||||
if (a == SurfaceType::Motor)
|
if (a == SurfaceType::Motor)
|
||||||
return RotateV::New();
|
return RotateV::New();
|
||||||
return std::nullopt;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasePart::MakeJoints() {
|
void BasePart::MakeJoints() {
|
||||||
|
@ -229,7 +228,7 @@ void BasePart::MakeJoints() {
|
||||||
|
|
||||||
// TEMPORARY
|
// TEMPORARY
|
||||||
// TODO: Use more efficient algorithm to *actually* find nearby parts)
|
// TODO: Use more efficient algorithm to *actually* find nearby parts)
|
||||||
for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) {
|
for (auto it = workspace()->GetDescendantsStart(); it != workspace()->GetDescendantsEnd(); it++) {
|
||||||
std::shared_ptr<Instance> obj = *it;
|
std::shared_ptr<Instance> obj = *it;
|
||||||
if (obj == shared_from_this()) continue; // Skip ourselves
|
if (obj == shared_from_this()) continue; // Skip ourselves
|
||||||
if (!obj->IsA<BasePart>()) continue;
|
if (!obj->IsA<BasePart>()) continue;
|
||||||
|
@ -276,12 +275,12 @@ void BasePart::MakeJoints() {
|
||||||
|
|
||||||
auto joint_ = makeJointFromSurfaces(mySurface, otherSurface);
|
auto joint_ = makeJointFromSurfaces(mySurface, otherSurface);
|
||||||
if (!joint_) continue;
|
if (!joint_) continue;
|
||||||
std::shared_ptr<JointInstance> joint = joint_.value();
|
std::shared_ptr<JointInstance> joint = joint_;
|
||||||
joint->part0 = shared<BasePart>();
|
joint->part0 = shared<BasePart>();
|
||||||
joint->part1 = otherPart->shared<BasePart>();
|
joint->part1 = otherPart->shared<BasePart>();
|
||||||
joint->c0 = contact0;
|
joint->c0 = contact0;
|
||||||
joint->c1 = contact1;
|
joint->c1 = contact1;
|
||||||
dataModel().value()->GetService<JointsService>()->AddChild(joint);
|
dataModel()->GetService<JointsService>()->AddChild(joint);
|
||||||
joint->UpdateProperty("Part0");
|
joint->UpdateProperty("Part0");
|
||||||
|
|
||||||
Logger::debugf("Made joint between %s and %s!\n", name.c_str(), otherPart->name.c_str());
|
Logger::debugf("Made joint between %s and %s!\n", name.c_str(), otherPart->name.c_str());
|
||||||
|
|
|
@ -54,9 +54,9 @@ protected:
|
||||||
friend JointInstance;
|
friend JointInstance;
|
||||||
friend PhysWorld;
|
friend PhysWorld;
|
||||||
|
|
||||||
virtual void OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) override;
|
virtual void OnWorkspaceAdded(nullable std::shared_ptr<Workspace> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) override;
|
||||||
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override;
|
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override;
|
||||||
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) override;
|
void OnAncestryChanged(nullable std::shared_ptr<Instance> child, nullable std::shared_ptr<Instance> newParent) override;
|
||||||
void onUpdated(std::string);
|
void onUpdated(std::string);
|
||||||
|
|
||||||
virtual void updateCollider(rp::PhysicsCommon* common) = 0;
|
virtual void updateCollider(rp::PhysicsCommon* common) = 0;
|
||||||
|
|
|
@ -23,7 +23,7 @@ Script::~Script() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::Run() {
|
void Script::Run() {
|
||||||
std::shared_ptr<ScriptContext> scriptContext = dataModel().value()->GetService<ScriptContext>();
|
std::shared_ptr<ScriptContext> scriptContext = dataModel()->GetService<ScriptContext>();
|
||||||
|
|
||||||
lua_State* L = scriptContext->state;
|
lua_State* L = scriptContext->state;
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
|
|
|
@ -18,8 +18,8 @@ void JointsService::InitService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::shared_ptr<Workspace>> JointsService::jointWorkspace() {
|
nullable std::shared_ptr<Workspace> JointsService::jointWorkspace() {
|
||||||
if (!dataModel()) return std::nullopt;
|
if (!dataModel()) return nullptr;
|
||||||
|
|
||||||
return dataModel().value()->FindService<Workspace>();
|
return dataModel()->FindService<Workspace>();
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
class DEF_INST_SERVICE_(hidden) JointsService : public Service {
|
class DEF_INST_SERVICE_(hidden) JointsService : public Service {
|
||||||
AUTOGEN_PREAMBLE
|
AUTOGEN_PREAMBLE
|
||||||
private:
|
private:
|
||||||
std::optional<std::shared_ptr<Workspace>> jointWorkspace();
|
nullable std::shared_ptr<Workspace> jointWorkspace();
|
||||||
protected:
|
protected:
|
||||||
void InitService() override;
|
void InitService() override;
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
|
|
|
@ -59,10 +59,10 @@ void ScriptContext::InitService() {
|
||||||
// Add other globals
|
// Add other globals
|
||||||
lua_getglobal(state, "_G");
|
lua_getglobal(state, "_G");
|
||||||
|
|
||||||
InstanceRef(dataModel().value()).PushLuaValue(state);
|
InstanceRef(dataModel()).PushLuaValue(state);
|
||||||
lua_setfield(state, -2, "game");
|
lua_setfield(state, -2, "game");
|
||||||
|
|
||||||
InstanceRef(dataModel().value()->GetService<Workspace>()).PushLuaValue(state);
|
InstanceRef(dataModel()->GetService<Workspace>()).PushLuaValue(state);
|
||||||
lua_setfield(state, -2, "workspace");
|
lua_setfield(state, -2, "workspace");
|
||||||
|
|
||||||
lua_pushlightuserdata(state, this);
|
lua_pushlightuserdata(state, this);
|
||||||
|
|
|
@ -14,7 +14,7 @@ void ServerScriptService::InitService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerScriptService::OnRun() {
|
void ServerScriptService::OnRun() {
|
||||||
auto workspace = dataModel().value()->GetService<Workspace>();
|
auto workspace = dataModel()->GetService<Workspace>();
|
||||||
for (auto it = workspace->GetDescendantsStart(); it != workspace->GetDescendantsEnd(); it++) {
|
for (auto it = workspace->GetDescendantsStart(); it != workspace->GetDescendantsEnd(); it++) {
|
||||||
if (!it->IsA<Script>()) continue;
|
if (!it->IsA<Script>()) continue;
|
||||||
it->CastTo<Script>().expect()->Run();
|
it->CastTo<Script>().expect()->Run();
|
||||||
|
|
|
@ -42,7 +42,7 @@ void Workspace::OnRun() {
|
||||||
joint->UpdateProperty("Part0");
|
joint->UpdateProperty("Part0");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto obj : dataModel().value()->GetService<JointsService>()->GetChildren()) {
|
for (auto obj : dataModel()->GetService<JointsService>()->GetChildren()) {
|
||||||
if (!obj->IsA<JointInstance>()) continue;
|
if (!obj->IsA<JointInstance>()) continue;
|
||||||
std::shared_ptr<JointInstance> joint = obj->CastTo<JointInstance>().expect();
|
std::shared_ptr<JointInstance> joint = obj->CastTo<JointInstance>().expect();
|
||||||
joint->UpdateProperty("Part0");
|
joint->UpdateProperty("Part0");
|
||||||
|
@ -63,8 +63,8 @@ void Workspace::PhysicsStep(float deltaTime) {
|
||||||
part->Destroy();
|
part->Destroy();
|
||||||
|
|
||||||
// If the parent of the part is a Model, destroy it too
|
// If the parent of the part is a Model, destroy it too
|
||||||
if (parent.has_value() && parent.value()->IsA("Model"))
|
if (parent != nullptr && parent->IsA("Model"))
|
||||||
parent.value()->Destroy();
|
parent->Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -412,9 +412,9 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
|
||||||
|
|
||||||
// Traverse to the root model
|
// Traverse to the root model
|
||||||
if (~evt->modifiers() & Qt::AltModifier) {
|
if (~evt->modifiers() & Qt::AltModifier) {
|
||||||
std::optional<std::shared_ptr<Instance>> nextParent = selObject->GetParent();
|
nullable std::shared_ptr<Instance> nextParent = selObject->GetParent();
|
||||||
while (nextParent.value() && nextParent.value()->IsA("Model")) {
|
while (nextParent && nextParent->IsA("Model")) {
|
||||||
selObject = std::dynamic_pointer_cast<PVInstance>(nextParent.value()); nextParent = selObject->GetParent();
|
selObject = std::dynamic_pointer_cast<PVInstance>(nextParent); nextParent = selObject->GetParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -403,8 +403,8 @@ void MainWindow::connectActionHandlers() {
|
||||||
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
|
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
|
||||||
for (std::weak_ptr<Instance> inst : selection->Get()) {
|
for (std::weak_ptr<Instance> inst : selection->Get()) {
|
||||||
if (inst.expired()) continue;
|
if (inst.expired()) continue;
|
||||||
historyState.push_back(UndoStateInstanceRemoved { inst.lock(), inst.lock()->GetParent().value() });
|
historyState.push_back(UndoStateInstanceRemoved { inst.lock(), inst.lock()->GetParent() });
|
||||||
inst.lock()->SetParent(std::nullopt);
|
inst.lock()->SetParent(nullptr);
|
||||||
}
|
}
|
||||||
selection->Set({});
|
selection->Set({});
|
||||||
historyState.push_back(UndoStateSelectionChanged {selection->Get(), {}});
|
historyState.push_back(UndoStateSelectionChanged {selection->Get(), {}});
|
||||||
|
@ -433,9 +433,9 @@ void MainWindow::connectActionHandlers() {
|
||||||
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
|
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
|
||||||
for (std::weak_ptr<Instance> inst : selection->Get()) {
|
for (std::weak_ptr<Instance> inst : selection->Get()) {
|
||||||
if (inst.expired()) continue;
|
if (inst.expired()) continue;
|
||||||
historyState.push_back(UndoStateInstanceRemoved { inst.lock(), inst.lock()->GetParent().value() });
|
historyState.push_back(UndoStateInstanceRemoved { inst.lock(), inst.lock()->GetParent() });
|
||||||
inst.lock()->Serialize(rootDoc);
|
inst.lock()->Serialize(rootDoc);
|
||||||
inst.lock()->SetParent(std::nullopt);
|
inst.lock()->SetParent(nullptr);
|
||||||
}
|
}
|
||||||
selection->Set({});
|
selection->Set({});
|
||||||
historyState.push_back(UndoStateSelectionChanged {selection->Get(), {}});
|
historyState.push_back(UndoStateSelectionChanged {selection->Get(), {}});
|
||||||
|
@ -502,8 +502,8 @@ void MainWindow::connectActionHandlers() {
|
||||||
bool done = false;
|
bool done = false;
|
||||||
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
|
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
|
||||||
for (auto object : selection->Get()) {
|
for (auto object : selection->Get()) {
|
||||||
if (firstParent == nullptr && object->GetParent().has_value()) firstParent = object->GetParent().value();
|
if (!firstParent && object->GetParent() != nullptr) firstParent = object->GetParent();
|
||||||
historyState.push_back(UndoStateInstanceReparented { object, object->GetParent().value(), model });
|
historyState.push_back(UndoStateInstanceReparented { object, object->GetParent(), model });
|
||||||
object->SetParent(model);
|
object->SetParent(model);
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
@ -535,13 +535,13 @@ void MainWindow::connectActionHandlers() {
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
for (auto object : model->GetChildren()) {
|
for (auto object : model->GetChildren()) {
|
||||||
historyState.push_back(UndoStateInstanceReparented { object, object->GetParent().value(), model->GetParent().value() });
|
historyState.push_back(UndoStateInstanceReparented { object, object->GetParent(), model->GetParent() });
|
||||||
object->SetParent(model->GetParent());
|
object->SetParent(model->GetParent());
|
||||||
newSelection.push_back(object);
|
newSelection.push_back(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
historyState.push_back(UndoStateInstanceRemoved { model, model->GetParent().value() });
|
historyState.push_back(UndoStateInstanceRemoved { model, model->GetParent() });
|
||||||
model->SetParent(std::nullopt);
|
model->SetParent(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!done)
|
if (!done)
|
||||||
|
|
|
@ -22,24 +22,24 @@ ExplorerModel::ExplorerModel(std::shared_ptr<Instance> dataRoot, QWidget *parent
|
||||||
: QAbstractItemModel(parent)
|
: QAbstractItemModel(parent)
|
||||||
, rootItem(dataRoot) {
|
, rootItem(dataRoot) {
|
||||||
// TODO: Don't use lambdas and handlers like that
|
// TODO: Don't use lambdas and handlers like that
|
||||||
hierarchyPreUpdateHandler = [&](std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) {
|
hierarchyPreUpdateHandler = [&](std::shared_ptr<Instance> object, nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent) {
|
||||||
if (oldParent.has_value()) {
|
if (oldParent) {
|
||||||
auto children = oldParent.value()->GetChildren();
|
auto children = oldParent->GetChildren();
|
||||||
size_t idx = std::find(children.begin(), children.end(), object) - children.begin();
|
size_t idx = std::find(children.begin(), children.end(), object) - children.begin();
|
||||||
beginRemoveRows(toIndex(oldParent.value()), idx, idx);
|
beginRemoveRows(toIndex(oldParent), idx, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newParent.has_value()) {
|
if (newParent) {
|
||||||
size_t size = newParent.value()->GetChildren().size();
|
size_t size = newParent->GetChildren().size();
|
||||||
beginInsertRows(toIndex(newParent.value()), size, size);
|
beginInsertRows(toIndex(newParent), size, size);
|
||||||
} else {
|
} else {
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
hierarchyPostUpdateHandler = [&](std::shared_ptr<Instance> object, std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) {
|
hierarchyPostUpdateHandler = [&](std::shared_ptr<Instance> object, nullable std::shared_ptr<Instance> oldParent, nullable std::shared_ptr<Instance> newParent) {
|
||||||
if (newParent.has_value()) endInsertRows();
|
if (newParent) endInsertRows();
|
||||||
if (oldParent.has_value()) endRemoveRows();
|
if (oldParent) endRemoveRows();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +65,10 @@ QModelIndex ExplorerModel::index(int row, int column, const QModelIndex &parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex ExplorerModel::toIndex(std::shared_ptr<Instance> item) {
|
QModelIndex ExplorerModel::toIndex(std::shared_ptr<Instance> item) {
|
||||||
if (item == rootItem || !item->GetParent().has_value())
|
if (item == rootItem || !item->GetParent())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::shared_ptr<Instance> parentItem = item->GetParent().value();
|
std::shared_ptr<Instance> parentItem = item->GetParent();
|
||||||
// Check above ensures this item is not root, so value() must be valid
|
// Check above ensures this item is not root, so value() must be valid
|
||||||
for (size_t i = 0; i < parentItem->GetChildren().size(); i++)
|
for (size_t i = 0; i < parentItem->GetChildren().size(); i++)
|
||||||
if (parentItem->GetChildren()[i] == item)
|
if (parentItem->GetChildren()[i] == item)
|
||||||
|
@ -86,13 +86,13 @@ QModelIndex ExplorerModel::parent(const QModelIndex &index) const {
|
||||||
|
|
||||||
Instance* childItem = static_cast<Instance*>(index.internalPointer());
|
Instance* childItem = static_cast<Instance*>(index.internalPointer());
|
||||||
// NORISK: The parent must exist if the child was obtained from it during this frame
|
// NORISK: The parent must exist if the child was obtained from it during this frame
|
||||||
std::shared_ptr<Instance> parentItem = childItem->GetParent().value();
|
std::shared_ptr<Instance> parentItem = childItem->GetParent();
|
||||||
|
|
||||||
if (parentItem == rootItem)
|
if (parentItem == rootItem)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
// Check above ensures this item is not root, so value() must be valid
|
// Check above ensures this item is not root, so value() must be valid
|
||||||
std::shared_ptr<Instance> parentParent = parentItem->GetParent().value();
|
std::shared_ptr<Instance> parentParent = parentItem->GetParent();
|
||||||
for (size_t i = 0; i < parentParent->GetChildren().size(); i++)
|
for (size_t i = 0; i < parentParent->GetChildren().size(); i++)
|
||||||
if (parentParent->GetChildren()[i] == parentItem)
|
if (parentParent->GetChildren()[i] == parentItem)
|
||||||
return createIndex(i, 0, parentItem.get());
|
return createIndex(i, 0, parentItem.get());
|
||||||
|
@ -241,7 +241,7 @@ bool ExplorerModel::dropMimeData(const QMimeData *data, Qt::DropAction action, i
|
||||||
UndoState historyState;
|
UndoState historyState;
|
||||||
std::shared_ptr<Instance> parentInst = fromIndex(parent);
|
std::shared_ptr<Instance> parentInst = fromIndex(parent);
|
||||||
for (std::shared_ptr<Instance> instance : slot->instances) {
|
for (std::shared_ptr<Instance> instance : slot->instances) {
|
||||||
historyState.push_back(UndoStateInstanceReparented { instance, instance->GetParent().value_or(nullptr), parentInst });
|
historyState.push_back(UndoStateInstanceReparented { instance, instance->GetParent(), parentInst });
|
||||||
instance->SetParent(parentInst);
|
instance->SetParent(parentInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -333,11 +333,11 @@ void PropertiesView::drawBranches(QPainter *painter, const QRect &rect, const QM
|
||||||
QTreeWidget::drawBranches(painter, rect, index);
|
QTreeWidget::drawBranches(painter, rect, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertiesView::setSelected(std::optional<std::shared_ptr<Instance>> instance) {
|
void PropertiesView::setSelected(nullable std::shared_ptr<Instance> instance) {
|
||||||
clear();
|
clear();
|
||||||
currentInstance = {};
|
currentInstance = {};
|
||||||
if (!instance) return;
|
if (!instance) return;
|
||||||
std::shared_ptr<Instance> inst = instance.value();
|
std::shared_ptr<Instance> inst = instance;
|
||||||
currentInstance = inst;
|
currentInstance = inst;
|
||||||
|
|
||||||
std::map<PropertyCategory, QTreeWidgetItem*> propertyCategories;
|
std::map<PropertyCategory, QTreeWidgetItem*> propertyCategories;
|
||||||
|
|
|
@ -31,5 +31,5 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void setSelected(std::optional<std::shared_ptr<Instance>> instance);
|
void setSelected(nullable std::shared_ptr<Instance> instance);
|
||||||
};
|
};
|
|
@ -70,7 +70,7 @@ void PlaceDocument::updateSelectionListeners(std::shared_ptr<Selection> selectio
|
||||||
selectionConnection = selection->SelectionChanged->Connect([selection, mainWnd](std::vector<Variant> _){
|
selectionConnection = selection->SelectionChanged->Connect([selection, mainWnd](std::vector<Variant> _){
|
||||||
// Update properties
|
// Update properties
|
||||||
if (selection->Get().size() != 1)
|
if (selection->Get().size() != 1)
|
||||||
mainWnd->ui->propertiesView->setSelected(std::nullopt);
|
mainWnd->ui->propertiesView->setSelected(nullptr);
|
||||||
else
|
else
|
||||||
mainWnd->ui->propertiesView->setSelected(selection->Get()[0]);
|
mainWnd->ui->propertiesView->setSelected(selection->Get()[0]);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ void UndoHistory::Undo() {
|
||||||
// The old value used to be valid, so it still should be...
|
// The old value used to be valid, so it still should be...
|
||||||
v->affectedInstance->SetProperty(v->property, v->oldValue).expect();
|
v->affectedInstance->SetProperty(v->property, v->oldValue).expect();
|
||||||
} else if (auto v = std::get_if<UndoStateInstanceCreated>(&change)) {
|
} else if (auto v = std::get_if<UndoStateInstanceCreated>(&change)) {
|
||||||
v->instance->SetParent(std::nullopt);
|
v->instance->SetParent(nullptr);
|
||||||
} else if (auto v = std::get_if<UndoStateInstanceRemoved>(&change)) {
|
} else if (auto v = std::get_if<UndoStateInstanceRemoved>(&change)) {
|
||||||
v->instance->SetParent(v->oldParent);
|
v->instance->SetParent(v->oldParent);
|
||||||
} else if (auto v = std::get_if<UndoStateInstanceReparented>(&change)) {
|
} else if (auto v = std::get_if<UndoStateInstanceReparented>(&change)) {
|
||||||
|
@ -57,7 +57,7 @@ void UndoHistory::Redo() {
|
||||||
} else if (auto v = std::get_if<UndoStateInstanceCreated>(&change)) {
|
} else if (auto v = std::get_if<UndoStateInstanceCreated>(&change)) {
|
||||||
v->instance->SetParent(v->newParent);
|
v->instance->SetParent(v->newParent);
|
||||||
} else if (auto v = std::get_if<UndoStateInstanceRemoved>(&change)) {
|
} else if (auto v = std::get_if<UndoStateInstanceRemoved>(&change)) {
|
||||||
v->instance->SetParent(std::nullopt);
|
v->instance->SetParent(nullptr);
|
||||||
} else if (auto v = std::get_if<UndoStateInstanceReparented>(&change)) {
|
} else if (auto v = std::get_if<UndoStateInstanceReparented>(&change)) {
|
||||||
v->instance->SetParent(v->newParent);
|
v->instance->SetParent(v->newParent);
|
||||||
} else if (auto v = std::get_if<UndoStateSelectionChanged>(&change)) {
|
} else if (auto v = std::get_if<UndoStateSelectionChanged>(&change)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue