mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-13 07:45:39 +07:00
Merge pull request #123 from enduro2d/feature/prefab_children_mod
Feature/prefab children mod
This commit is contained in:
@@ -85,6 +85,10 @@ namespace e2d
|
||||
bool add_child(
|
||||
const node_iptr& child) noexcept;
|
||||
|
||||
bool add_child_at(
|
||||
const node_iptr& child,
|
||||
std::size_t index) noexcept;
|
||||
|
||||
bool add_child_to_back(
|
||||
const node_iptr& child) noexcept;
|
||||
|
||||
@@ -108,6 +112,17 @@ namespace e2d
|
||||
bool remove_child(
|
||||
const node_iptr& child) noexcept;
|
||||
|
||||
node_iptr remove_child_at(
|
||||
std::size_t index) noexcept;
|
||||
|
||||
bool swap_children(
|
||||
const node_iptr& child_l,
|
||||
const node_iptr& child_r) noexcept;
|
||||
|
||||
bool swap_children_at(
|
||||
std::size_t child_l,
|
||||
std::size_t child_r) noexcept;
|
||||
|
||||
bool send_backward() noexcept;
|
||||
bool bring_to_back() noexcept;
|
||||
|
||||
@@ -125,6 +140,12 @@ namespace e2d
|
||||
|
||||
node_iptr next_sibling() noexcept;
|
||||
const_node_iptr next_sibling() const noexcept;
|
||||
|
||||
node_iptr child_at(std::size_t index) noexcept;
|
||||
const_node_iptr child_at(std::size_t index) const noexcept;
|
||||
|
||||
std::pair<std::size_t, bool> child_index(
|
||||
const const_node_iptr& child) const noexcept;
|
||||
protected:
|
||||
node() = default;
|
||||
node(gobject owner);
|
||||
|
||||
@@ -27,22 +27,30 @@ namespace e2d
|
||||
prefab& assign(prefab&& other) noexcept;
|
||||
prefab& assign(const prefab& other);
|
||||
|
||||
prefab& set_prototype(ecs::prototype&& proto) noexcept;
|
||||
prefab& set_prototype(const ecs::prototype& proto);
|
||||
prefab& set_uuid(str&& uuid) noexcept;
|
||||
prefab& set_uuid(const str& uuid);
|
||||
|
||||
prefab& set_children(vector<prefab>&& children) noexcept;
|
||||
prefab& set_children(const vector<prefab>& children);
|
||||
|
||||
prefab& set_prototype(ecs::prototype&& prototype) noexcept;
|
||||
prefab& set_prototype(const ecs::prototype& prototype);
|
||||
|
||||
str& uuid() noexcept;
|
||||
const str& uuid() const noexcept;
|
||||
|
||||
vector<prefab>& children() noexcept;
|
||||
const vector<prefab>& children() const noexcept;
|
||||
|
||||
ecs::prototype& prototype() noexcept;
|
||||
const ecs::prototype& prototype() const noexcept;
|
||||
|
||||
const vector<prefab>& children() const noexcept;
|
||||
private:
|
||||
ecs::prototype prototype_;
|
||||
str uuid_;
|
||||
vector<prefab> children_;
|
||||
ecs::prototype prototype_;
|
||||
};
|
||||
|
||||
void swap(prefab& l, prefab& r) noexcept;
|
||||
bool operator==(const prefab& l, const prefab& r) noexcept;
|
||||
bool operator!=(const prefab& l, const prefab& r) noexcept;
|
||||
bool operator==(const prefab& l, const prefab& r) = delete;
|
||||
bool operator!=(const prefab& l, const prefab& r) = delete;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,20 @@ namespace e2d
|
||||
swap_next(l, r);
|
||||
}
|
||||
}
|
||||
|
||||
static void transfer_nodes(node_ptr p, node_ptr b, node_ptr e) noexcept {
|
||||
if ( b != e ) {
|
||||
node_ptr prev_p = p->prev_;
|
||||
node_ptr prev_b = b->prev_;
|
||||
node_ptr prev_e = e->prev_;
|
||||
prev_e->next_ = p;
|
||||
p->prev_ = prev_e;
|
||||
prev_b->next_ = e;
|
||||
e->prev_ = prev_b;
|
||||
prev_p->next_ = b;
|
||||
b->prev_ = prev_p;
|
||||
}
|
||||
}
|
||||
private:
|
||||
node_ptr prev_{nullptr};
|
||||
node_ptr next_{nullptr};
|
||||
@@ -252,15 +266,15 @@ namespace e2d
|
||||
void swap(intrusive_list& other) noexcept;
|
||||
|
||||
template < typename Disposer >
|
||||
void clear_and_dispose(Disposer&& disposer);
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
void clear() noexcept;
|
||||
|
||||
template < typename Disposer >
|
||||
void pop_back_and_dispose(Disposer&& disposer);
|
||||
void pop_back_and_dispose(Disposer disposer);
|
||||
void pop_back() noexcept;
|
||||
|
||||
template < typename Disposer >
|
||||
void pop_front_and_dispose(Disposer&& disposer);
|
||||
void pop_front_and_dispose(Disposer disposer);
|
||||
void pop_front() noexcept;
|
||||
|
||||
void push_back(T& v) noexcept;
|
||||
@@ -268,11 +282,24 @@ namespace e2d
|
||||
iterator insert(const_iterator pos, T& v) noexcept;
|
||||
|
||||
template < typename Disposer >
|
||||
iterator erase_and_dispose(const_iterator pos, Disposer&& disposer);
|
||||
iterator erase_and_dispose(const_iterator pos, Disposer disposer);
|
||||
iterator erase(const_iterator pos) noexcept;
|
||||
|
||||
void splice(const_iterator pos, intrusive_list& x) noexcept;
|
||||
void splice(const_iterator pos, const_iterator f, const_iterator e) noexcept;
|
||||
|
||||
template < typename Predicate >
|
||||
void merge(intrusive_list& x, Predicate predicate);
|
||||
void merge(intrusive_list& x);
|
||||
|
||||
template < typename Predicate >
|
||||
void sort(Predicate predicate);
|
||||
void sort();
|
||||
|
||||
static iterator iterator_to(T& v) noexcept;
|
||||
static const_iterator iterator_to(const T& v) noexcept;
|
||||
|
||||
static void iterator_swap(iterator l, iterator r) noexcept;
|
||||
private:
|
||||
using node_t = intrusive_list_hook<Tag>;
|
||||
using node_ptr = typename node_t::node_ptr;
|
||||
@@ -406,7 +433,7 @@ namespace e2d
|
||||
|
||||
template < typename T, typename Tag >
|
||||
template < typename Disposer >
|
||||
void intrusive_list<T,Tag>::clear_and_dispose(Disposer&& disposer) {
|
||||
void intrusive_list<T,Tag>::clear_and_dispose(Disposer disposer) {
|
||||
while ( !empty() ) {
|
||||
pop_back_and_dispose(disposer);
|
||||
}
|
||||
@@ -419,7 +446,7 @@ namespace e2d
|
||||
|
||||
template < typename T, typename Tag >
|
||||
template < typename Disposer >
|
||||
void intrusive_list<T,Tag>::pop_back_and_dispose(Disposer&& disposer) {
|
||||
void intrusive_list<T,Tag>::pop_back_and_dispose(Disposer disposer) {
|
||||
E2D_ASSERT(!empty());
|
||||
node_ptr node = root_.prev_;
|
||||
node->unlink();
|
||||
@@ -433,7 +460,7 @@ namespace e2d
|
||||
|
||||
template < typename T, typename Tag >
|
||||
template < typename Disposer >
|
||||
void intrusive_list<T,Tag>::pop_front_and_dispose(Disposer&& disposer) {
|
||||
void intrusive_list<T,Tag>::pop_front_and_dispose(Disposer disposer) {
|
||||
E2D_ASSERT(!empty());
|
||||
node_ptr node = root_.next_;
|
||||
node->unlink();
|
||||
@@ -469,7 +496,7 @@ namespace e2d
|
||||
|
||||
template < typename T, typename Tag >
|
||||
template < typename Disposer >
|
||||
typename intrusive_list<T,Tag>::iterator intrusive_list<T,Tag>::erase_and_dispose(const_iterator pos, Disposer&& disposer) {
|
||||
typename intrusive_list<T,Tag>::iterator intrusive_list<T,Tag>::erase_and_dispose(const_iterator pos, Disposer disposer) {
|
||||
node_ptr node = pos.node();
|
||||
E2D_ASSERT(node != &root_ && node->is_linked());
|
||||
++pos;
|
||||
@@ -483,6 +510,70 @@ namespace e2d
|
||||
return erase_and_dispose(pos, null_disposer());
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
void intrusive_list<T,Tag>::splice(const_iterator pos, intrusive_list& x) noexcept {
|
||||
intrusive_list_hook<Tag>::transfer_nodes(pos.node(), x.begin().node(), x.end().node());
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
void intrusive_list<T,Tag>::splice(const_iterator pos, const_iterator f, const_iterator e) noexcept {
|
||||
intrusive_list_hook<Tag>::transfer_nodes(pos.node(), f.node(), e.node());
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
template < typename Predicate >
|
||||
void intrusive_list<T,Tag>::merge(intrusive_list& x, Predicate predicate) {
|
||||
const_iterator b(cbegin()), e(cend()), ex(x.cend());
|
||||
while ( !x.empty() ) {
|
||||
const_iterator ix(x.cbegin());
|
||||
while ( b != e && !predicate(*ix, *b) ) {
|
||||
++b;
|
||||
}
|
||||
if ( b == e ) {
|
||||
splice(e, x);
|
||||
break;
|
||||
} else {
|
||||
do {
|
||||
++ix;
|
||||
} while ( ix != ex && predicate(*ix, *b) );
|
||||
splice(b, x.begin(), ix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
void intrusive_list<T,Tag>::merge(intrusive_list& x) {
|
||||
merge(x, std::less<value_type>());
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
template < typename Predicate >
|
||||
void intrusive_list<T,Tag>::sort(Predicate predicate) {
|
||||
if ( root_.next_ != &root_ && root_.next_ != root_.prev_ ) {
|
||||
intrusive_list left_list;
|
||||
intrusive_list right_list;
|
||||
|
||||
const_iterator mid(cbegin()), tail(cend());
|
||||
while ( (mid != tail) && (++mid != tail) ) {
|
||||
--tail;
|
||||
}
|
||||
|
||||
left_list.splice(left_list.cbegin(), cbegin(), mid);
|
||||
right_list.splice(right_list.cbegin(), *this);
|
||||
|
||||
left_list.sort(predicate);
|
||||
right_list.sort(predicate);
|
||||
|
||||
splice(cbegin(), left_list);
|
||||
merge(right_list, predicate);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
void intrusive_list<T,Tag>::sort() {
|
||||
sort(std::less<value_type>());
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
typename intrusive_list<T,Tag>::iterator intrusive_list<T,Tag>::iterator_to(T& v) noexcept {
|
||||
node_t& node = static_cast<node_t&>(v);
|
||||
@@ -496,4 +587,10 @@ namespace e2d
|
||||
E2D_ASSERT(node.is_linked());
|
||||
return const_iterator(&node);
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
void intrusive_list<T,Tag>::iterator_swap(iterator l, iterator r) noexcept {
|
||||
E2D_ASSERT(l.node()->is_linked() && r.node()->is_linked());
|
||||
intrusive_list_hook<Tag>::swap_nodes(l.node(), r.node());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [-512,0]
|
||||
@@ -15,7 +15,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [-256,0]
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [0,0]
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [256,0]
|
||||
@@ -45,7 +45,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [-512,-256]
|
||||
@@ -55,7 +55,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [-256,-256]
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [0,-256]
|
||||
@@ -75,7 +75,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [256,-256]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "spine_prefab.json",
|
||||
"prefab" : "spine_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "coin"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "spine_prefab.json",
|
||||
"prefab" : "spine_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "dragon"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "model_prefab.json",
|
||||
"prefab" : "model_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "gnome"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "widget_prefab.json",
|
||||
"prefab" : "widget_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "layout"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "panel"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "spine_prefab.json",
|
||||
"prefab" : "spine_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "raptor"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"prototype" : "sprite_prefab.json",
|
||||
"prefab" : "sprite_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "ship"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"prototype" : "../prefabs/scene_prefab.json",
|
||||
"prefab" : "../prefabs/scene_prefab.json",
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/camera_prefab.json",
|
||||
"prefab" : "../prefabs/camera_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"rotation" : 0.5
|
||||
@@ -14,7 +14,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/camera_prefab.json",
|
||||
"prefab" : "../prefabs/camera_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"rotation" : -0.5
|
||||
@@ -27,7 +27,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/camera_prefab.json",
|
||||
"prefab" : "../prefabs/camera_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"rotation" : 0.5
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/camera_prefab.json",
|
||||
"prefab" : "../prefabs/camera_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"rotation" : -0.5
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/gnome_prefab.json",
|
||||
"prefab" : "../prefabs/gnome_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [0,0],
|
||||
@@ -64,7 +64,7 @@
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"sprite_renderer" : {
|
||||
"blending" : "additive"
|
||||
@@ -77,7 +77,7 @@
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"sprite_renderer" : {
|
||||
"tint" : [255,0,0,255]
|
||||
@@ -91,7 +91,7 @@
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
"prototype" : "../prefabs/label_bm_prefab.json",
|
||||
"prefab" : "../prefabs/label_bm_prefab.json",
|
||||
"components" : {
|
||||
"label" : {
|
||||
"text" : "bm font",
|
||||
@@ -108,7 +108,7 @@
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"prototype" : "../prefabs/label_sdf_prefab.json",
|
||||
"prefab" : "../prefabs/label_sdf_prefab.json",
|
||||
"components" : {
|
||||
"label" : {
|
||||
"text" : "sdf font",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"prototype" : "../prefabs/scene_prefab.json",
|
||||
"prefab" : "../prefabs/scene_prefab.json",
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/camera_prefab.json"
|
||||
"prefab" : "../prefabs/camera_prefab.json"
|
||||
},{
|
||||
"prototype" : "../prefabs/coin_prefab.json",
|
||||
"prefab" : "../prefabs/coin_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [350,250],
|
||||
@@ -14,7 +14,7 @@
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"prototype" : "../prefabs/raptor_prefab.json",
|
||||
"prefab" : "../prefabs/raptor_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [300,-350],
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"prototype" : "../prefabs/dragon_prefab.json",
|
||||
"prefab" : "../prefabs/dragon_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [-100,0],
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"prototype" : "../prefabs/scene_prefab.json",
|
||||
"prefab" : "../prefabs/scene_prefab.json",
|
||||
"components" : {
|
||||
"behaviour" : {
|
||||
"script" : "../scripts/sample_07/sample_07.lua"
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/camera_prefab.json"
|
||||
"prefab" : "../prefabs/camera_prefab.json"
|
||||
},{
|
||||
"prototype" : "../prefabs/background_prefab.json"
|
||||
"prefab" : "../prefabs/background_prefab.json"
|
||||
},{
|
||||
"prototype" : "../prefabs/gnome_prefab.json",
|
||||
"prefab" : "../prefabs/gnome_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [0,0],
|
||||
@@ -21,7 +21,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/label_sdf_prefab.json",
|
||||
"prefab" : "../prefabs/label_sdf_prefab.json",
|
||||
"components" : {
|
||||
"label" : {
|
||||
"text" : "FPS: ",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"prototype" : "../prefabs/scene_prefab.json",
|
||||
"prefab" : "../prefabs/scene_prefab.json",
|
||||
"components" : {
|
||||
"behaviour" : {
|
||||
"script" : "../scripts/sample_08/sample_08.lua"
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/camera_prefab.json",
|
||||
"prefab" : "../prefabs/camera_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"rotation" : 0.5
|
||||
@@ -19,7 +19,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/camera_prefab.json",
|
||||
"prefab" : "../prefabs/camera_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"rotation" : -0.5
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "ship(1)"
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "ship(11)"
|
||||
@@ -69,11 +69,10 @@
|
||||
"offset" : [10,15],
|
||||
"radius" : 33
|
||||
}
|
||||
},
|
||||
"children" : []
|
||||
}
|
||||
}]
|
||||
},{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "ship(2)"
|
||||
@@ -113,7 +112,7 @@
|
||||
}
|
||||
}
|
||||
},{
|
||||
"prototype" : "../prefabs/label_sdf_prefab.json",
|
||||
"prefab" : "../prefabs/label_sdf_prefab.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "label"
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"prototype" : "../prefabs/scene_prefab.json",
|
||||
"prefab" : "../prefabs/scene_prefab.json",
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/background_prefab.json"
|
||||
"prefab" : "../prefabs/background_prefab.json"
|
||||
},{
|
||||
"prototype" : "../prefabs/camera_prefab.json"
|
||||
"prefab" : "../prefabs/camera_prefab.json"
|
||||
},{
|
||||
"prototype" : "../prefabs/panel_prefab.json",
|
||||
"prefab" : "../prefabs/panel_prefab.json",
|
||||
"components" : {
|
||||
"sprite_renderer" : {
|
||||
"scale" : [4,2]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/layout_prefab.json",
|
||||
"prefab" : "../prefabs/layout_prefab.json",
|
||||
"components" : {
|
||||
"layout" : {
|
||||
"justify_content" : "space_evenly"
|
||||
@@ -22,14 +22,14 @@
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/widget_prefab.json",
|
||||
"prefab" : "../prefabs/widget_prefab.json",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [66,113]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [33,56.5]
|
||||
@@ -37,14 +37,14 @@
|
||||
}
|
||||
}]
|
||||
},{
|
||||
"prototype" : "../prefabs/widget_prefab.json",
|
||||
"prefab" : "../prefabs/widget_prefab.json",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [66,113]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [33,56.5]
|
||||
@@ -52,14 +52,14 @@
|
||||
}
|
||||
}]
|
||||
},{
|
||||
"prototype" : "../prefabs/widget_prefab.json",
|
||||
"prefab" : "../prefabs/widget_prefab.json",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [66,113]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"prototype" : "../prefabs/ship_prefab.json",
|
||||
"prefab" : "../prefabs/ship_prefab.json",
|
||||
"components" : {
|
||||
"actor" : {
|
||||
"translation" : [33,56.5]
|
||||
|
||||
@@ -87,6 +87,12 @@ function node.remove_all_children(self) end
|
||||
---@return boolean
|
||||
function node.add_child(self, child) end
|
||||
|
||||
---@param self node
|
||||
---@param child node
|
||||
---@param index integer
|
||||
---@return boolean
|
||||
function node.add_child_at(self, child, index) end
|
||||
|
||||
---@param self node
|
||||
---@param child node
|
||||
---@return boolean
|
||||
@@ -124,6 +130,23 @@ function node.add_sibling_after(self, sibling) end
|
||||
---@return boolean
|
||||
function node.remove_child(self, child) end
|
||||
|
||||
---@param self node
|
||||
---@param index integer
|
||||
---@return node
|
||||
function node.remove_child_at(self, index) end
|
||||
|
||||
---@param self node
|
||||
---@param child_l node
|
||||
---@param child_r node
|
||||
---@return boolean
|
||||
function node.swap_children(self, child_l, child_r) end
|
||||
|
||||
---@param self node
|
||||
---@param child_l integer
|
||||
---@param child_r integer
|
||||
---@return boolean
|
||||
function node.swap_children_at(self, child_l, child_r) end
|
||||
|
||||
---@param self node
|
||||
---@return boolean
|
||||
function node.send_backward(self) end
|
||||
@@ -140,5 +163,15 @@ function node.send_forward(self) end
|
||||
---@return boolean
|
||||
function node.bring_to_front(self) end
|
||||
|
||||
---@param self node
|
||||
---@param index integer
|
||||
---@return node
|
||||
function node.child_at(self, index) end
|
||||
|
||||
---@param self node
|
||||
---@param child node
|
||||
---@return integer, boolean
|
||||
function node.child_index(self, child) end
|
||||
|
||||
---@type node
|
||||
_G.node = _G.node or node
|
||||
|
||||
@@ -24,25 +24,42 @@ namespace
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"prototype" : { "$ref": "#/common_definitions/address" },
|
||||
"components" : { "type" : "object" },
|
||||
"uuid" : { "$ref": "#/common_definitions/uuid" },
|
||||
"prefab" : { "$ref": "#/common_definitions/address" },
|
||||
"children" : { "$ref": "#/definitions/children" },
|
||||
"mod_children" : { "$ref": "#/definitions/mod_children" },
|
||||
"components" : { "type" : "object" }
|
||||
},
|
||||
"definitions" : {
|
||||
"children" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/child" }
|
||||
}
|
||||
},
|
||||
"definitions" : {
|
||||
},
|
||||
"child" : {
|
||||
"type" : "object",
|
||||
"required" : [],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"prototype" : { "$ref": "#/common_definitions/address" },
|
||||
"components" : { "type" : "object" },
|
||||
"children" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/child" }
|
||||
}
|
||||
"uuid" : { "$ref": "#/common_definitions/uuid" },
|
||||
"prefab" : { "$ref": "#/common_definitions/address" },
|
||||
"children" : { "$ref": "#/definitions/children" },
|
||||
"mod_children" : { "$ref": "#/definitions/mod_children" },
|
||||
"components" : { "type" : "object" }
|
||||
}
|
||||
},
|
||||
"mod_children" : {
|
||||
"type" : "array",
|
||||
"items" : { "$ref": "#/definitions/mod_child" }
|
||||
},
|
||||
"mod_child" : {
|
||||
"type" : "object",
|
||||
"required" : [ "uuid" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"uuid" : { "$ref": "#/common_definitions/uuid" },
|
||||
"children" : { "$ref": "#/definitions/children" },
|
||||
"mod_children" : { "$ref": "#/definitions/mod_children" },
|
||||
"components" : { "type" : "object" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,9 +88,23 @@ namespace
|
||||
const rapidjson::Value& root,
|
||||
asset_dependencies& dependencies)
|
||||
{
|
||||
if ( root.HasMember("prototype") ) {
|
||||
if ( root.HasMember("prefab") ) {
|
||||
dependencies.add_dependency<prefab_asset>(
|
||||
path::combine(parent_address, root["prototype"].GetString()));
|
||||
path::combine(parent_address, root["prefab"].GetString()));
|
||||
}
|
||||
|
||||
if ( root.HasMember("children") ) {
|
||||
const rapidjson::Value& children_root = root["children"];
|
||||
for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) {
|
||||
collect_dependencies(parent_address, children_root[i], dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("mod_children") ) {
|
||||
const rapidjson::Value& mod_children_root = root["mod_children"];
|
||||
for ( rapidjson::SizeType i = 0; i < mod_children_root.Size(); ++i ) {
|
||||
collect_dependencies(parent_address, mod_children_root[i], dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("components") ) {
|
||||
@@ -83,9 +114,10 @@ namespace
|
||||
++component_root )
|
||||
{
|
||||
{
|
||||
bool success = the<factory>().validate_json(
|
||||
const bool success = the<factory>().validate_json(
|
||||
component_root->name.GetString(),
|
||||
component_root->value);
|
||||
|
||||
if ( !success ) {
|
||||
throw prefab_asset_loading_exception();
|
||||
}
|
||||
@@ -94,23 +126,18 @@ namespace
|
||||
factory_loader<>::collect_context ctx(
|
||||
str(parent_address),
|
||||
component_root->value);
|
||||
bool success = the<factory>().collect_dependencies(
|
||||
|
||||
const bool success = the<factory>().collect_dependencies(
|
||||
component_root->name.GetString(),
|
||||
dependencies,
|
||||
ctx);
|
||||
|
||||
if ( !success ) {
|
||||
throw prefab_asset_loading_exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("children") ) {
|
||||
const rapidjson::Value& children_root = root["children"];
|
||||
for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) {
|
||||
collect_dependencies(parent_address, children_root[i], dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stdex::promise<asset_group> collect_dependencies(
|
||||
@@ -123,25 +150,92 @@ namespace
|
||||
return dependencies.load_async(library);
|
||||
}
|
||||
|
||||
prefab parse_prefab(
|
||||
prefab* find_prefab_child(prefab& root, str_view child_uuid) noexcept {
|
||||
for ( prefab& child : root.children() ) {
|
||||
if ( child.uuid() == child_uuid ) {
|
||||
return &child;
|
||||
}
|
||||
}
|
||||
|
||||
for ( prefab& child : root.children() ) {
|
||||
if ( prefab* sub_child = find_prefab_child(child, child_uuid) ) {
|
||||
return sub_child;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void parse_prefab_inplace(
|
||||
prefab& content,
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root,
|
||||
const asset_group& dependencies)
|
||||
{
|
||||
prefab content;
|
||||
if ( root.HasMember("uuid") ) {
|
||||
str uuid = root["uuid"].GetString();
|
||||
content.set_uuid(std::move(uuid));
|
||||
}
|
||||
|
||||
if ( root.HasMember("prototype") ) {
|
||||
if ( root.HasMember("prefab") ) {
|
||||
auto proto_res = dependencies.find_asset<prefab_asset>(
|
||||
path::combine(parent_address, root["prototype"].GetString()));
|
||||
path::combine(parent_address, root["prefab"].GetString()));
|
||||
if ( !proto_res ) {
|
||||
the<debug>().error("PREFAB: Dependency 'prototype' is not found:\n"
|
||||
the<debug>().error("PREFAB: Dependency 'prefab' is not found:\n"
|
||||
"--> Parent address: %0\n"
|
||||
"--> Dependency address: %1",
|
||||
parent_address,
|
||||
root["prototype"].GetString());
|
||||
root["prefab"].GetString());
|
||||
throw prefab_asset_loading_exception();
|
||||
}
|
||||
content = proto_res->content();
|
||||
content.set_children(proto_res->content().children());
|
||||
content.set_prototype(proto_res->content().prototype());
|
||||
}
|
||||
|
||||
if ( root.HasMember("children") ) {
|
||||
const rapidjson::Value& children_root = root["children"];
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) {
|
||||
const rapidjson::Value& child_root = children_root[i];
|
||||
|
||||
prefab child;
|
||||
parse_prefab_inplace(
|
||||
child,
|
||||
parent_address,
|
||||
child_root,
|
||||
dependencies);
|
||||
|
||||
content.children().push_back(std::move(child));
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("mod_children") ) {
|
||||
const rapidjson::Value& mod_children_root = root["mod_children"];
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < mod_children_root.Size(); ++i ) {
|
||||
const rapidjson::Value& mod_child_root = mod_children_root[i];
|
||||
|
||||
E2D_ASSERT(
|
||||
mod_child_root.HasMember("uuid") &&
|
||||
mod_child_root["uuid"].IsString());
|
||||
|
||||
prefab* const child_prefab = find_prefab_child(
|
||||
content,
|
||||
mod_child_root["uuid"].GetString());
|
||||
|
||||
if ( !child_prefab ) {
|
||||
the<debug>().error("PREFAB: Modifiable child is not found:\n"
|
||||
"--> Child UUID: %0",
|
||||
mod_child_root["uuid"].GetString());
|
||||
throw prefab_asset_loading_exception();
|
||||
}
|
||||
|
||||
parse_prefab_inplace(
|
||||
*child_prefab,
|
||||
parent_address,
|
||||
mod_child_root,
|
||||
dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("components") ) {
|
||||
@@ -154,30 +248,29 @@ namespace
|
||||
str(parent_address),
|
||||
component_root->value,
|
||||
dependencies);
|
||||
bool success = the<factory>().fill_prototype(
|
||||
|
||||
const bool success = the<factory>().fill_prototype(
|
||||
component_root->name.GetString(),
|
||||
content.prototype(),
|
||||
ctx);
|
||||
|
||||
if ( !success ) {
|
||||
throw prefab_asset_loading_exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("children") ) {
|
||||
const rapidjson::Value& children_root = root["children"];
|
||||
|
||||
vector<prefab> children;
|
||||
children.reserve(children_root.Size());
|
||||
|
||||
for ( rapidjson::SizeType i = 0; i < children_root.Size(); ++i ) {
|
||||
children.emplace_back(parse_prefab(
|
||||
parent_address, children_root[i], dependencies));
|
||||
}
|
||||
|
||||
content.set_children(std::move(children));
|
||||
}
|
||||
|
||||
prefab parse_prefab(
|
||||
str_view parent_address,
|
||||
const rapidjson::Value& root,
|
||||
const asset_group& dependencies)
|
||||
{
|
||||
prefab content;
|
||||
parse_prefab_inplace(
|
||||
content,
|
||||
parent_address,
|
||||
root, dependencies);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,12 @@ namespace e2d::bindings::high
|
||||
return n.add_child(c);
|
||||
},
|
||||
|
||||
"add_child_at", [](node& n, const node_iptr& c, i32 i) -> bool {
|
||||
return i >= 0
|
||||
? n.add_child_at(c, math::numeric_cast<std::size_t>(i))
|
||||
: false;
|
||||
},
|
||||
|
||||
"add_child_to_back", [](node& n, const node_iptr& c) -> bool {
|
||||
return n.add_child_to_back(c);
|
||||
},
|
||||
@@ -115,6 +121,22 @@ namespace e2d::bindings::high
|
||||
return n.remove_child(c);
|
||||
},
|
||||
|
||||
"remove_child_at", [](node& n, i32 i) -> node_iptr {
|
||||
return i >= 0
|
||||
? n.remove_child_at(math::numeric_cast<std::size_t>(i))
|
||||
: node_iptr();
|
||||
},
|
||||
|
||||
"swap_children", [](node& n, const node_iptr& cl, const node_iptr& cr) -> bool {
|
||||
return n.swap_children(cl, cr);
|
||||
},
|
||||
|
||||
"swap_children_at", [](node& n, i32 cl, i32 cr) -> bool {
|
||||
return cl >= 0 && cr >= 0
|
||||
? n.swap_children_at(math::numeric_cast<std::size_t>(cl), math::numeric_cast<std::size_t>(cr))
|
||||
: false;
|
||||
},
|
||||
|
||||
"send_backward", [](node& n) -> bool {
|
||||
return n.send_backward();
|
||||
},
|
||||
@@ -141,7 +163,17 @@ namespace e2d::bindings::high
|
||||
[](node& n) -> node_iptr { return n.prev_sibling(); }),
|
||||
|
||||
"next_sibling", sol::property(
|
||||
[](node& n) -> node_iptr { return n.next_sibling(); })
|
||||
[](node& n) -> node_iptr { return n.next_sibling(); }),
|
||||
|
||||
"child_at", [](node& n, i32 i) -> node_iptr {
|
||||
return i >= 0
|
||||
? n.child_at(math::numeric_cast<std::size_t>(i))
|
||||
: node_iptr();
|
||||
},
|
||||
|
||||
"child_index", [](node& n, const node_iptr& c) -> std::pair<std::size_t, bool> {
|
||||
return n.child_index(c);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,14 +207,25 @@ namespace e2d
|
||||
return count;
|
||||
}
|
||||
|
||||
bool node::add_child(const node_iptr& child) noexcept {
|
||||
bool node::add_child(
|
||||
const node_iptr& child) noexcept
|
||||
{
|
||||
return add_child_to_front(child);
|
||||
}
|
||||
|
||||
bool node::add_child_at(
|
||||
const node_iptr& child,
|
||||
std::size_t index) noexcept
|
||||
{
|
||||
return index == 0u
|
||||
? add_child_to_back(child)
|
||||
: add_child_after(child_at(index - 1u), child);
|
||||
}
|
||||
|
||||
bool node::add_child_to_back(
|
||||
const node_iptr& child) noexcept
|
||||
{
|
||||
if ( !child ) {
|
||||
if ( !child || child == this ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,7 +244,7 @@ namespace e2d
|
||||
bool node::add_child_to_front(
|
||||
const node_iptr& child) noexcept
|
||||
{
|
||||
if ( !child ) {
|
||||
if ( !child || child == this ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -319,6 +330,41 @@ namespace e2d
|
||||
return true;
|
||||
}
|
||||
|
||||
node_iptr node::remove_child_at(std::size_t index) noexcept {
|
||||
node_iptr child = child_at(index);
|
||||
return remove_child(child)
|
||||
? child
|
||||
: node_iptr();
|
||||
}
|
||||
|
||||
bool node::swap_children(
|
||||
const node_iptr& child_l,
|
||||
const node_iptr& child_r) noexcept
|
||||
{
|
||||
if ( !child_l || !child_r ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( child_l->parent_ != this || child_r->parent_ != this ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node_children::iterator_swap(
|
||||
node_children::iterator_to(*child_l),
|
||||
node_children::iterator_to(*child_r));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool node::swap_children_at(
|
||||
std::size_t child_l,
|
||||
std::size_t child_r) noexcept
|
||||
{
|
||||
return swap_children(
|
||||
child_at(child_l),
|
||||
child_at(child_r));
|
||||
}
|
||||
|
||||
bool node::send_backward() noexcept {
|
||||
node_iptr prev = prev_sibling();
|
||||
return prev
|
||||
@@ -414,6 +460,36 @@ namespace e2d
|
||||
}
|
||||
return const_node_iptr(&*iter);
|
||||
}
|
||||
|
||||
node_iptr node::child_at(std::size_t index) noexcept {
|
||||
node_iptr child = first_child();
|
||||
for ( std::size_t i = 0; i < index && child; ++i ) {
|
||||
child = child->next_sibling();
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
const_node_iptr node::child_at(std::size_t index) const noexcept {
|
||||
const_node_iptr child = first_child();
|
||||
for ( std::size_t i = 0; i < index && child; ++i ) {
|
||||
child = child->next_sibling();
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
std::pair<std::size_t, bool> node::child_index(
|
||||
const const_node_iptr& child) const noexcept
|
||||
{
|
||||
if ( !child || child->parent_ != this ) {
|
||||
return {std::size_t(-1), false};
|
||||
}
|
||||
|
||||
const auto distance = std::distance(
|
||||
children_.begin(),
|
||||
node_children::iterator_to(*child));
|
||||
|
||||
return {math::numeric_cast<std::size_t>(distance), true};
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
|
||||
@@ -25,14 +25,16 @@ namespace e2d
|
||||
}
|
||||
|
||||
void prefab::clear() noexcept {
|
||||
prototype_.clear();
|
||||
uuid_.clear();
|
||||
children_.clear();
|
||||
prototype_.clear();
|
||||
}
|
||||
|
||||
void prefab::swap(prefab& other) noexcept {
|
||||
using std::swap;
|
||||
swap(prototype_, other.prototype_);
|
||||
swap(uuid_, other.uuid_);
|
||||
swap(children_, other.children_);
|
||||
swap(prototype_, other.prototype_);
|
||||
}
|
||||
|
||||
prefab& prefab::assign(prefab&& other) noexcept {
|
||||
@@ -46,20 +48,21 @@ namespace e2d
|
||||
prefab& prefab::assign(const prefab& other) {
|
||||
if ( this != &other ) {
|
||||
prefab s;
|
||||
s.prototype_ = other.prototype_;
|
||||
s.uuid_ = other.uuid_;
|
||||
s.children_ = other.children_;
|
||||
s.prototype_ = other.prototype_;
|
||||
swap(s);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
prefab& prefab::set_prototype(ecs::prototype&& proto) noexcept {
|
||||
prototype_ = std::move(proto);
|
||||
prefab& prefab::set_uuid(str&& uuid) noexcept {
|
||||
uuid_ = std::move(uuid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
prefab& prefab::set_prototype(const ecs::prototype& proto) {
|
||||
prototype_ = proto;
|
||||
prefab& prefab::set_uuid(const str& uuid) {
|
||||
uuid_ = uuid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -73,6 +76,32 @@ namespace e2d
|
||||
return *this;
|
||||
}
|
||||
|
||||
prefab& prefab::set_prototype(ecs::prototype&& prototype) noexcept {
|
||||
prototype_ = std::move(prototype);
|
||||
return *this;
|
||||
}
|
||||
|
||||
prefab& prefab::set_prototype(const ecs::prototype& prototype) {
|
||||
prototype_ = prototype;
|
||||
return *this;
|
||||
}
|
||||
|
||||
str& prefab::uuid() noexcept {
|
||||
return uuid_;
|
||||
}
|
||||
|
||||
const str& prefab::uuid() const noexcept {
|
||||
return uuid_;
|
||||
}
|
||||
|
||||
vector<prefab>& prefab::children() noexcept {
|
||||
return children_;
|
||||
}
|
||||
|
||||
const vector<prefab>& prefab::children() const noexcept {
|
||||
return children_;
|
||||
}
|
||||
|
||||
ecs::prototype& prefab::prototype() noexcept {
|
||||
return prototype_;
|
||||
}
|
||||
@@ -80,10 +109,6 @@ namespace e2d
|
||||
const ecs::prototype& prefab::prototype() const noexcept {
|
||||
return prototype_;
|
||||
}
|
||||
|
||||
const vector<prefab>& prefab::children() const noexcept {
|
||||
return children_;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
@@ -91,13 +116,4 @@ namespace e2d
|
||||
void swap(prefab& l, prefab& r) noexcept {
|
||||
l.swap(r);
|
||||
}
|
||||
|
||||
bool operator==(const prefab& l, const prefab& r) noexcept {
|
||||
return l.prototype().empty() && l.children().empty()
|
||||
&& r.prototype().empty() && r.children().empty();
|
||||
}
|
||||
|
||||
bool operator!=(const prefab& l, const prefab& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +197,12 @@ namespace
|
||||
}
|
||||
}]
|
||||
},
|
||||
"guid" : {
|
||||
"type" : "string",
|
||||
"minLength" : 36,
|
||||
"maxLength" : 36,
|
||||
"pattern" : "^[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}$"
|
||||
},
|
||||
"name" : {
|
||||
"type" : "string",
|
||||
"minLength" : 1
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"components" : {
|
||||
"touchable" : {},
|
||||
|
||||
"rect_collider" : {
|
||||
"size" : [1,2],
|
||||
"offset" : [2,4]
|
||||
},
|
||||
|
||||
"circle_collider" : {
|
||||
"radius" : 5,
|
||||
"offset" : [4,2]
|
||||
},
|
||||
|
||||
"polygon_collider" : {
|
||||
"points" : [[1,2],[2,3],[3,4]],
|
||||
"offset" : [8,4]
|
||||
}
|
||||
}
|
||||
}
|
||||
64
untests/bin/library/prefab_child.json
Normal file
64
untests/bin/library/prefab_child.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"prefab" : "prefab_root.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "child"
|
||||
},
|
||||
"rect_collider" : {
|
||||
"size" : [1,2],
|
||||
"offset" : [2,4]
|
||||
},
|
||||
"polygon_collider" : {
|
||||
"points" : [[1,2],[2,3],[3,4]],
|
||||
"offset" : [8,4]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"uuid" : "C07CDC21-8D1A-45E5-9321-AC7B6FADA847",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "child(3)"
|
||||
}
|
||||
}
|
||||
}],
|
||||
"mod_children" : [{
|
||||
"uuid" : "4A93547E-4635-4C2F-9C59-3546E11B1722",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [10,10]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"uuid" : "EA1F7728-8061-495E-9E8A-280C5E2979B3",
|
||||
"prefab" : "prefab_root.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "subchild(1)"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
"uuid" : "58063213-9FC1-457C-B773-B826BE1BE6D7",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [20,20]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"uuid" : "4DDDD08D-F7B9-4588-8597-3E38051AC433",
|
||||
"prefab" : "prefab_root.json",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "subchild(2)"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
"uuid" : "C07CDC21-8D1A-45E5-9321-AC7B6FADA847",
|
||||
"components" : {
|
||||
"widget" : {
|
||||
"size" : [30,30]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
27
untests/bin/library/prefab_root.json
Normal file
27
untests/bin/library/prefab_root.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"uuid" : "73740BC4-CE9F-4A7F-A029-4AB65027A8AE",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "root"
|
||||
},
|
||||
"circle_collider" : {
|
||||
"radius" : 5,
|
||||
"offset" : [4,2]
|
||||
}
|
||||
},
|
||||
"children" : [{
|
||||
"uuid" : "4A93547E-4635-4C2F-9C59-3546E11B1722",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "child(1)"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"uuid" : "58063213-9FC1-457C-B773-B826BE1BE6D7",
|
||||
"components" : {
|
||||
"named" : {
|
||||
"name" : "child(2)"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
@@ -259,28 +259,6 @@ TEST_CASE("library"){
|
||||
REQUIRE(model_res->content().mesh()->content().indices_submesh_count() == 1);
|
||||
REQUIRE_FALSE(model_res->content().mesh()->content().indices(0).empty());
|
||||
}
|
||||
|
||||
{
|
||||
auto prefab_res = l.load_asset<prefab_asset>("prefab.json");
|
||||
REQUIRE(prefab_res);
|
||||
|
||||
ecs::registry w;
|
||||
ecs::entity e = w.create_entity(prefab_res->content().prototype());
|
||||
|
||||
REQUIRE(e.exists_component<touchable>());
|
||||
|
||||
REQUIRE(e.exists_component<rect_collider>());
|
||||
REQUIRE(e.get_component<rect_collider>().size() == v2f(1.f,2.f));
|
||||
REQUIRE(e.get_component<rect_collider>().offset() == v2f(2.f,4.f));
|
||||
|
||||
REQUIRE(e.exists_component<circle_collider>());
|
||||
REQUIRE(math::approximately(e.get_component<circle_collider>().radius(), 5.f));
|
||||
REQUIRE(e.get_component<circle_collider>().offset() == v2f(4.f,2.f));
|
||||
|
||||
REQUIRE(e.exists_component<polygon_collider>());
|
||||
REQUIRE(e.get_component<polygon_collider>().points() == vector<v2f>{{1,2},{2,3},{3,4}});
|
||||
REQUIRE(e.get_component<polygon_collider>().offset() == v2f(8.f,4.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
@@ -9,19 +9,6 @@ using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
class safe_starter_initializer final : private noncopyable {
|
||||
public:
|
||||
safe_starter_initializer() {
|
||||
modules::initialize<starter>(0, nullptr,
|
||||
starter::parameters(
|
||||
engine::parameters("world_untests", "enduro2d")));
|
||||
}
|
||||
|
||||
~safe_starter_initializer() noexcept {
|
||||
modules::shutdown<starter>();
|
||||
}
|
||||
};
|
||||
|
||||
class fake_node final : public node {
|
||||
protected:
|
||||
fake_node() : node() {
|
||||
@@ -61,7 +48,6 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("node") {
|
||||
safe_starter_initializer initializer;
|
||||
SECTION("empty_node") {
|
||||
auto n = node::create();
|
||||
REQUIRE(n);
|
||||
@@ -317,6 +303,33 @@ TEST_CASE("node") {
|
||||
REQUIRE_FALSE(n->bring_to_back());
|
||||
}
|
||||
}
|
||||
SECTION("swap_children") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
auto p2 = node::create();
|
||||
auto n4 = node::create(p2);
|
||||
|
||||
auto n5 = node::create();
|
||||
|
||||
REQUIRE_FALSE(p->swap_children(n1, node_iptr()));
|
||||
REQUIRE_FALSE(p->swap_children(node_iptr(), n1));
|
||||
REQUIRE_FALSE(p->swap_children(n1, p2));
|
||||
REQUIRE_FALSE(p->swap_children(n1, n4));
|
||||
REQUIRE_FALSE(p->swap_children(n1, n5));
|
||||
|
||||
REQUIRE(p->swap_children(n1, n1)); // n1 n2 n3
|
||||
REQUIRE(p->swap_children(n1, n2)); // n2 n1 n3
|
||||
REQUIRE(p->swap_children(n2, n3)); // n3 n1 n2
|
||||
REQUIRE(p->swap_children(n2, n1)); // n3 n2 n1
|
||||
|
||||
REQUIRE(p->child_at(0u) == n3);
|
||||
REQUIRE(p->child_at(1u) == n2);
|
||||
REQUIRE(p->child_at(2u) == n1);
|
||||
}
|
||||
SECTION("send_forward/bring_to_front") {
|
||||
{
|
||||
auto p = node::create();
|
||||
@@ -429,6 +442,142 @@ TEST_CASE("node") {
|
||||
REQUIRE_FALSE(cn4->next_sibling());
|
||||
}
|
||||
}
|
||||
SECTION("child_at") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
REQUIRE(p->child_at(0) == n1);
|
||||
REQUIRE(p->child_at(1) == n2);
|
||||
REQUIRE(p->child_at(2) == n3);
|
||||
REQUIRE_FALSE(p->child_at(3));
|
||||
|
||||
{
|
||||
const_node_iptr cp = p;
|
||||
|
||||
REQUIRE(cp->child_at(0) == n1);
|
||||
REQUIRE(cp->child_at(1) == n2);
|
||||
REQUIRE(cp->child_at(2) == n3);
|
||||
REQUIRE_FALSE(cp->child_at(3));
|
||||
}
|
||||
}
|
||||
SECTION("child_index") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
auto p2 = node::create();
|
||||
auto n4 = node::create(p2);
|
||||
|
||||
auto n5 = node::create();
|
||||
|
||||
REQUIRE(p->child_index(n1).second);
|
||||
REQUIRE(p->child_index(n2).second);
|
||||
REQUIRE(p->child_index(n3).second);
|
||||
REQUIRE_FALSE(p->child_index(n4).second);
|
||||
REQUIRE_FALSE(p->child_index(n5).second);
|
||||
|
||||
REQUIRE(p->child_index(n1).first == 0u);
|
||||
REQUIRE(p->child_index(n2).first == 1u);
|
||||
REQUIRE(p->child_index(n3).first == 2u);
|
||||
|
||||
{
|
||||
const_node_iptr cp = p;
|
||||
|
||||
const_node_iptr cn1 = n1;
|
||||
const_node_iptr cn2 = n2;
|
||||
const_node_iptr cn3 = n3;
|
||||
const_node_iptr cn4 = n4;
|
||||
const_node_iptr cn5 = n5;
|
||||
|
||||
REQUIRE(cp->child_index(cn1).second);
|
||||
REQUIRE(cp->child_index(cn2).second);
|
||||
REQUIRE(cp->child_index(cn3).second);
|
||||
REQUIRE_FALSE(cp->child_index(cn4).second);
|
||||
REQUIRE_FALSE(cp->child_index(cn5).second);
|
||||
|
||||
REQUIRE(cp->child_index(cn1).first == 0u);
|
||||
REQUIRE(cp->child_index(cn2).first == 1u);
|
||||
REQUIRE(cp->child_index(cn3).first == 2u);
|
||||
}
|
||||
}
|
||||
SECTION("remove_child_at") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
REQUIRE_FALSE(n1->remove_child_at(0));
|
||||
|
||||
REQUIRE(p->remove_child_at(1) == n2);
|
||||
REQUIRE_FALSE(n2->has_parent());
|
||||
REQUIRE(p->child_count() == 2u);
|
||||
|
||||
REQUIRE(p->remove_child_at(0) == n1);
|
||||
REQUIRE_FALSE(n1->has_parent());
|
||||
REQUIRE(p->child_count() == 1u);
|
||||
|
||||
REQUIRE(p->remove_child_at(0) == n3);
|
||||
REQUIRE_FALSE(n3->has_parent());
|
||||
REQUIRE(p->child_count() == 0u);
|
||||
}
|
||||
SECTION("swap_children_at") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
REQUIRE_FALSE(p->swap_children_at(0u, 3u));
|
||||
REQUIRE_FALSE(p->swap_children_at(3u, 0u));
|
||||
|
||||
REQUIRE(p->swap_children_at(0, 0)); // n1 n2 n3
|
||||
REQUIRE(p->swap_children_at(0, 1)); // n2 n1 n3
|
||||
REQUIRE(p->swap_children_at(0, 2)); // n3 n1 n2
|
||||
REQUIRE(p->swap_children_at(2, 1)); // n3 n2 n1
|
||||
|
||||
REQUIRE(p->child_at(0u) == n3);
|
||||
REQUIRE(p->child_at(1u) == n2);
|
||||
REQUIRE(p->child_at(2u) == n1);
|
||||
}
|
||||
SECTION("add_child_at") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create();
|
||||
auto n2 = node::create();
|
||||
auto n3 = node::create();
|
||||
auto n4 = node::create();
|
||||
|
||||
REQUIRE_FALSE(p->add_child_at(p, 0u));
|
||||
REQUIRE_FALSE(p->add_child_at(nullptr, 0u));
|
||||
REQUIRE_FALSE(p->add_child_at(n1, 1u));
|
||||
|
||||
REQUIRE(p->add_child_at(n1, 0u)); // n1
|
||||
REQUIRE(p->add_child_at(n2, 0u)); // n2 n1
|
||||
REQUIRE(p->add_child_at(n3, 2u)); // n2 n1 n3
|
||||
REQUIRE(p->add_child_at(n4, 2u)); // n2 n1 n4 n3
|
||||
|
||||
REQUIRE(p->child_at(0u) == n2);
|
||||
REQUIRE(p->child_at(1u) == n1);
|
||||
REQUIRE(p->child_at(2u) == n4);
|
||||
REQUIRE(p->child_at(3u) == n3);
|
||||
|
||||
REQUIRE_FALSE(p->add_child_at(n1, 5u));
|
||||
REQUIRE(p->add_child_at(n1, 4u)); // n2 n4 n3 n1
|
||||
REQUIRE(p->add_child_at(n3, 0u)); // n3 n2 n4 n1
|
||||
REQUIRE(p->add_child_at(n4, 1u)); // n3 n4 n2 n1
|
||||
REQUIRE(p->add_child_at(n4, p->child_index(n4).first)); // n3 n4 n2 n1
|
||||
|
||||
REQUIRE(p->child_at(0u) == n3);
|
||||
REQUIRE(p->child_at(1u) == n4);
|
||||
REQUIRE(p->child_at(2u) == n2);
|
||||
REQUIRE(p->child_at(3u) == n1);
|
||||
}
|
||||
SECTION("add_child_to_back/add_child_to_front") {
|
||||
auto p = node::create();
|
||||
auto n1 = node::create();
|
||||
@@ -439,6 +588,7 @@ TEST_CASE("node") {
|
||||
REQUIRE(p->add_child_to_back(n1));
|
||||
REQUIRE(p->add_child_to_back(n2));
|
||||
REQUIRE(p->add_child_to_back(n3)); // n3 n2 n1
|
||||
REQUIRE_FALSE(p->add_child_to_back(p));
|
||||
REQUIRE_FALSE(p->add_child_to_back(nullptr));
|
||||
|
||||
REQUIRE(n1->prev_sibling() == n2);
|
||||
@@ -474,6 +624,7 @@ TEST_CASE("node") {
|
||||
REQUIRE(p->add_child_to_front(n1));
|
||||
REQUIRE(p->add_child_to_front(n2));
|
||||
REQUIRE(p->add_child_to_front(n3)); // n1 n2 n3
|
||||
REQUIRE_FALSE(p->add_child_to_front(p));
|
||||
REQUIRE_FALSE(p->add_child_to_front(nullptr));
|
||||
|
||||
REQUIRE(n1->next_sibling() == n2);
|
||||
|
||||
194
untests/sources/untests_high/prefab.cpp
Normal file
194
untests/sources/untests_high/prefab.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "_high.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
namespace
|
||||
{
|
||||
class safe_starter_initializer final : private noncopyable {
|
||||
public:
|
||||
safe_starter_initializer() {
|
||||
modules::initialize<starter>(0, nullptr,
|
||||
starter::parameters(
|
||||
engine::parameters("prefab_untests", "enduro2d")));
|
||||
}
|
||||
|
||||
~safe_starter_initializer() noexcept {
|
||||
modules::shutdown<starter>();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("prefab"){
|
||||
safe_starter_initializer initializer;
|
||||
library& l = the<library>();
|
||||
{
|
||||
auto prefab_root_res = l.load_asset<prefab_asset>("prefab_root.json");
|
||||
REQUIRE(prefab_root_res);
|
||||
|
||||
const prefab& prefab_root = prefab_root_res->content();
|
||||
REQUIRE(prefab_root.uuid() == "73740BC4-CE9F-4A7F-A029-4AB65027A8AE");
|
||||
|
||||
REQUIRE(prefab_root.children().size() == 2u);
|
||||
REQUIRE(prefab_root.children()[0].uuid() == "4A93547E-4635-4C2F-9C59-3546E11B1722");
|
||||
REQUIRE(prefab_root.children()[1].uuid() == "58063213-9FC1-457C-B773-B826BE1BE6D7");
|
||||
|
||||
auto go = the<world>().instantiate(prefab_root);
|
||||
|
||||
{
|
||||
REQUIRE(go.component<named>());
|
||||
REQUIRE(go.component<named>()->name() == "root");
|
||||
|
||||
REQUIRE(go.component<circle_collider>());
|
||||
REQUIRE(go.component<circle_collider>()->radius() == Approx(5.f));
|
||||
REQUIRE(go.component<circle_collider>()->offset() == v2f(4.f,2.f));
|
||||
}
|
||||
|
||||
{
|
||||
node_iptr go_node = go.component<actor>()
|
||||
? go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
REQUIRE(go_node);
|
||||
REQUIRE(go_node->owner() == go);
|
||||
REQUIRE(go_node->child_count() == 2u);
|
||||
|
||||
node_iptr child1 = go_node->child_at(0u);
|
||||
node_iptr child2 = go_node->child_at(1u);
|
||||
|
||||
REQUIRE(child1);
|
||||
REQUIRE(child2);
|
||||
|
||||
gobject child1_go = child1->owner();
|
||||
gobject child2_go = child2->owner();
|
||||
|
||||
REQUIRE(child1_go);
|
||||
REQUIRE(child2_go);
|
||||
|
||||
REQUIRE(child1_go.component<named>());
|
||||
REQUIRE(child1_go.component<named>()->name() == "child(1)");
|
||||
|
||||
REQUIRE(child2_go.component<named>());
|
||||
REQUIRE(child2_go.component<named>()->name() == "child(2)");
|
||||
|
||||
node_iptr child1_node = child1_go.component<actor>()
|
||||
? child1_go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
node_iptr child2_node = child2_go.component<actor>()
|
||||
? child2_go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
REQUIRE(child1_node);
|
||||
REQUIRE(child1_node->owner() == child1_go);
|
||||
REQUIRE(child1_node->child_count() == 0u);
|
||||
|
||||
REQUIRE(child2_node);
|
||||
REQUIRE(child2_node->owner() == child2_go);
|
||||
REQUIRE(child2_node->child_count() == 0u);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto prefab_child_res = l.load_asset<prefab_asset>("prefab_child.json");
|
||||
REQUIRE(prefab_child_res);
|
||||
|
||||
const prefab& prefab_child = prefab_child_res->content();
|
||||
REQUIRE(prefab_child.uuid().empty());
|
||||
|
||||
REQUIRE(prefab_child.children().size() == 3u);
|
||||
REQUIRE(prefab_child.children()[0].uuid() == "4A93547E-4635-4C2F-9C59-3546E11B1722");
|
||||
REQUIRE(prefab_child.children()[1].uuid() == "58063213-9FC1-457C-B773-B826BE1BE6D7");
|
||||
REQUIRE(prefab_child.children()[2].uuid() == "C07CDC21-8D1A-45E5-9321-AC7B6FADA847");
|
||||
|
||||
auto go = the<world>().instantiate(prefab_child);
|
||||
|
||||
{
|
||||
REQUIRE(go.component<named>());
|
||||
REQUIRE(go.component<named>()->name() == "child");
|
||||
|
||||
REQUIRE(go.component<rect_collider>());
|
||||
REQUIRE(go.component<rect_collider>()->size() == v2f(1.f,2.f));
|
||||
REQUIRE(go.component<rect_collider>()->offset() == v2f(2.f,4.f));
|
||||
|
||||
REQUIRE(go.component<circle_collider>());
|
||||
REQUIRE(go.component<circle_collider>()->radius() == Approx(5.f));
|
||||
REQUIRE(go.component<circle_collider>()->offset() == v2f(4.f,2.f));
|
||||
|
||||
REQUIRE(go.component<polygon_collider>());
|
||||
REQUIRE(go.component<polygon_collider>()->points() == vector<v2f>{{1,2},{2,3},{3,4}});
|
||||
REQUIRE(go.component<polygon_collider>()->offset() == v2f(8.f,4.f));
|
||||
}
|
||||
|
||||
{
|
||||
node_iptr go_node = go.component<actor>()
|
||||
? go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
REQUIRE(go_node);
|
||||
REQUIRE(go_node->owner() == go);
|
||||
REQUIRE(go_node->child_count() == 3u);
|
||||
|
||||
node_iptr child1 = go_node->child_at(0u);
|
||||
node_iptr child2 = go_node->child_at(1u);
|
||||
node_iptr child3 = go_node->child_at(2u);
|
||||
|
||||
REQUIRE(child1);
|
||||
REQUIRE(child2);
|
||||
REQUIRE(child3);
|
||||
|
||||
gobject child1_go = child1->owner();
|
||||
gobject child2_go = child2->owner();
|
||||
gobject child3_go = child3->owner();
|
||||
|
||||
REQUIRE(child1_go);
|
||||
REQUIRE(child2_go);
|
||||
REQUIRE(child3_go);
|
||||
|
||||
REQUIRE(child1_go.component<named>());
|
||||
REQUIRE(child1_go.component<widget>());
|
||||
REQUIRE(child1_go.component<named>()->name() == "child(1)");
|
||||
REQUIRE(child1_go.component<widget>()->size() == v2f(10.f, 10.f));
|
||||
|
||||
REQUIRE(child2_go.component<named>());
|
||||
REQUIRE(child2_go.component<widget>());
|
||||
REQUIRE(child2_go.component<named>()->name() == "child(2)");
|
||||
REQUIRE(child2_go.component<widget>()->size() == v2f(20.f, 20.f));
|
||||
|
||||
REQUIRE(child3_go.component<named>());
|
||||
REQUIRE(child3_go.component<widget>());
|
||||
REQUIRE(child3_go.component<named>()->name() == "child(3)");
|
||||
REQUIRE(child3_go.component<widget>()->size() == v2f(30.f, 30.f));
|
||||
|
||||
node_iptr child1_node = child1_go.component<actor>()
|
||||
? child1_go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
node_iptr child2_node = child2_go.component<actor>()
|
||||
? child2_go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
node_iptr child3_node = child3_go.component<actor>()
|
||||
? child3_go.component<actor>()->node()
|
||||
: node_iptr();
|
||||
|
||||
REQUIRE(child1_node);
|
||||
REQUIRE(child1_node->owner() == child1_go);
|
||||
REQUIRE(child1_node->child_count() == 1u);
|
||||
REQUIRE(child1_node->first_child()->child_count() == 2u);
|
||||
|
||||
REQUIRE(child2_node);
|
||||
REQUIRE(child2_node->owner() == child2_go);
|
||||
REQUIRE(child2_node->child_count() == 1u);
|
||||
REQUIRE(child2_node->first_child()->child_count() == 2u);
|
||||
|
||||
REQUIRE(child3_node);
|
||||
REQUIRE(child3_node->owner() == child3_go);
|
||||
REQUIRE(child3_node->child_count() == 0u);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "_utils.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct ilist_tag1 {};
|
||||
@@ -21,6 +23,10 @@ namespace
|
||||
obj_t() = default;
|
||||
obj_t(int ni) : i(ni) {}
|
||||
};
|
||||
|
||||
bool operator<(const obj_t& l, const obj_t& r) noexcept {
|
||||
return l.i < r.i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("intrusive_list") {
|
||||
@@ -433,4 +439,36 @@ TEST_CASE("intrusive_list") {
|
||||
}
|
||||
}
|
||||
}
|
||||
SECTION("sort") {
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 rnd(rd());
|
||||
|
||||
std::uniform_int_distribution<u32> uni_size(0, 1024);
|
||||
std::uniform_int_distribution<i32> uni_number(-65536, 65535);
|
||||
|
||||
const auto pred = [](const obj_t& l, const obj_t& r) noexcept {
|
||||
return l.i < r.i;
|
||||
};
|
||||
|
||||
const auto r_pred = [](const obj_t& l, const obj_t& r) noexcept {
|
||||
return l.i > r.i;
|
||||
};
|
||||
|
||||
for ( std::size_t i = 0; i < 1024; ++i ) {
|
||||
vector<std::unique_ptr<obj_t>> objs;
|
||||
intrusive_list<obj_t, ilist_tag1> l;
|
||||
for ( u32 b = 0, e = uni_size(rnd); b < e; ++b ) {
|
||||
objs.push_back(std::make_unique<obj_t>(uni_number(rnd)));
|
||||
l.push_back(*objs.back());
|
||||
}
|
||||
l.sort();
|
||||
REQUIRE(std::is_sorted(l.cbegin(), l.cend()));
|
||||
l.sort(r_pred);
|
||||
REQUIRE(std::is_sorted(l.cbegin(), l.cend(), r_pred));
|
||||
l.sort(pred);
|
||||
REQUIRE(std::is_sorted(l.cbegin(), l.cend(), pred));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user