refactor(instance): implemented GetDescendant and replaced GetChildren in renderer and simulation with it
This commit is contained in:
parent
215f8ed500
commit
4de2b97c2d
4 changed files with 89 additions and 4 deletions
|
@ -108,6 +108,15 @@ std::optional<std::shared_ptr<Instance>> Instance::GetParent() {
|
||||||
return parent.value().lock();
|
return parent.value().lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<Instance> DUMMY_INSTANCE;
|
||||||
|
DescendantsIterator Instance::GetDescendantsStart() {
|
||||||
|
return DescendantsIterator(GetChildren().size() > 0 ? GetChildren()[0] : DUMMY_INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
DescendantsIterator Instance::GetDescendantsEnd() {
|
||||||
|
return DescendantsIterator(DUMMY_INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
bool Instance::IsParentLocked() {
|
bool Instance::IsParentLocked() {
|
||||||
return this->parentLocked;
|
return this->parentLocked;
|
||||||
}
|
}
|
||||||
|
@ -231,4 +240,49 @@ InstanceRef Instance::Deserialize(pugi::xml_node* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescendantsIterator
|
||||||
|
|
||||||
|
DescendantsIterator::DescendantsIterator(std::shared_ptr<Instance> current) : current(current), root(current == DUMMY_INSTANCE ? DUMMY_INSTANCE : current->GetParent()), siblingIndex { 0 } { }
|
||||||
|
|
||||||
|
DescendantsIterator::self_type DescendantsIterator::operator++(int _) {
|
||||||
|
// If the current item is dummy, an error has occurred, this is not supposed to happen.
|
||||||
|
if (current == DUMMY_INSTANCE) {
|
||||||
|
Logger::fatalError("Attempt to increment a descendant iterator past its end\n");
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current item has children, enter it
|
||||||
|
if (current->GetChildren().size() > 0) {
|
||||||
|
siblingIndex.push_back(0);
|
||||||
|
current = current->GetChildren()[0];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we move to the next sibling, if applicable.
|
||||||
|
|
||||||
|
// But not if one up is null or the root element
|
||||||
|
if (!current->GetParent() || current == root) {
|
||||||
|
current = DUMMY_INSTANCE;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've hit the end of this item's children, move one up
|
||||||
|
while (current->GetParent() && current->GetParent().value()->GetChildren().size() <= (siblingIndex.back() + 1)) {
|
||||||
|
siblingIndex.pop_back();
|
||||||
|
current = current->GetParent().value();
|
||||||
|
|
||||||
|
// But not if one up is null or the root element
|
||||||
|
if (!current->GetParent() || current == root) {
|
||||||
|
current = DUMMY_INSTANCE;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now move to the next sibling
|
||||||
|
siblingIndex.back()++;
|
||||||
|
current = current->GetParent().value()->GetChildren()[siblingIndex.back()];
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
@ -30,6 +31,8 @@ struct InstanceType {
|
||||||
std::string explorerIcon = "";
|
std::string explorerIcon = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DescendantsIterator;
|
||||||
|
|
||||||
// Base class for all instances in the data model
|
// Base class for all instances in the data model
|
||||||
// Note: enable_shared_from_this HAS to be public or else its field will not be populated
|
// Note: enable_shared_from_this HAS to be public or else its field will not be populated
|
||||||
// Maybe this could be replaced with a friendship? But that seems unnecessary.
|
// Maybe this could be replaced with a friendship? But that seems unnecessary.
|
||||||
|
@ -69,7 +72,9 @@ public:
|
||||||
std::optional<std::shared_ptr<Instance>> GetParent();
|
std::optional<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; }
|
||||||
|
|
||||||
|
DescendantsIterator GetDescendantsStart();
|
||||||
|
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()); }
|
||||||
|
|
||||||
|
@ -87,4 +92,28 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<Instance> InstanceRef;
|
typedef std::shared_ptr<Instance> InstanceRef;
|
||||||
typedef std::weak_ptr<Instance> InstanceRefWeak;
|
typedef std::weak_ptr<Instance> InstanceRefWeak;
|
||||||
|
|
||||||
|
// https://gist.github.com/jeetsukumaran/307264
|
||||||
|
class DescendantsIterator {
|
||||||
|
public:
|
||||||
|
typedef DescendantsIterator self_type;
|
||||||
|
typedef std::shared_ptr<Instance> value_type;
|
||||||
|
typedef std::shared_ptr<Instance>& reference;
|
||||||
|
typedef std::shared_ptr<Instance> pointer;
|
||||||
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
|
typedef int difference_type;
|
||||||
|
|
||||||
|
DescendantsIterator(std::shared_ptr<Instance> current);
|
||||||
|
inline self_type operator++() { self_type i = *this; ++*this; return i; }
|
||||||
|
inline std::shared_ptr<Instance> operator*() { return current; }
|
||||||
|
inline std::shared_ptr<Instance> operator->() { return current; }
|
||||||
|
inline bool operator==(const self_type& rhs) { return current == rhs.current; }
|
||||||
|
inline bool operator!=(const self_type& rhs) { return current != rhs.current; }
|
||||||
|
|
||||||
|
self_type operator++(int _);
|
||||||
|
private:
|
||||||
|
std::optional<std::shared_ptr<Instance>> root;
|
||||||
|
std::shared_ptr<Instance> current;
|
||||||
|
std::vector<int> siblingIndex;
|
||||||
|
};
|
|
@ -77,7 +77,8 @@ void physicsStep(float deltaTime) {
|
||||||
|
|
||||||
// Naive implementation. Parts are only considered so if they are just under Workspace
|
// Naive implementation. Parts are only considered so if they are just under Workspace
|
||||||
// TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance
|
// TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance
|
||||||
for (InstanceRef obj : gWorkspace()->GetChildren()) {
|
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
|
||||||
|
InstanceRef obj = *it;
|
||||||
if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly
|
if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly
|
||||||
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(obj);
|
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(obj);
|
||||||
const rp::Transform& transform = part->rigidBody->getTransform();
|
const rp::Transform& transform = part->rigidBody->getTransform();
|
||||||
|
|
|
@ -125,7 +125,8 @@ void renderParts() {
|
||||||
|
|
||||||
// Sort by nearest
|
// Sort by nearest
|
||||||
std::map<float, std::shared_ptr<Part>> sorted;
|
std::map<float, std::shared_ptr<Part>> sorted;
|
||||||
for (InstanceRef inst : gWorkspace()->GetChildren()) {
|
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
|
||||||
|
InstanceRef inst = *it;
|
||||||
if (inst->GetClass()->className != "Part") continue;
|
if (inst->GetClass()->className != "Part") continue;
|
||||||
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
|
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
|
||||||
if (part->transparency > 0.00001) {
|
if (part->transparency > 0.00001) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue