Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gauthier Quesnel
irritator
Commits
aa8aa45e
Commit
aa8aa45e
authored
Jun 15, 2020
by
Gauthier Quesnel
Browse files
gui: adds automatic reorder graph
parent
4830b289
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
app/gui/node-editor.cpp
View file @
aa8aa45e
This diff is collapsed.
Click to expand it.
app/gui/node-editor.hpp
View file @
aa8aa45e
...
...
@@ -10,7 +10,6 @@
#include <filesystem>
#include <fstream>
#include <thread>
#include <unordered_map>
#include <variant>
#include <vector>
...
...
@@ -19,6 +18,22 @@
namespace
irt
{
template
<
class
C
>
constexpr
int
length
(
const
C
&
c
)
noexcept
{
return
static_cast
<
int
>
(
c
.
size
());
}
template
<
class
T
,
size_t
N
>
constexpr
int
length
(
const
T
(
&
array
)[
N
])
noexcept
{
(
void
)
array
;
return
static_cast
<
int
>
(
N
);
}
template
<
typename
Identifier
>
constexpr
Identifier
undefined
()
noexcept
...
...
@@ -47,50 +62,59 @@ static inline constexpr int not_found = -1;
struct
top_cluster
{
std
::
vector
<
child_id
>
children
;
std
::
vector
<
int
>
nodes
;
std
::
vector
<
std
::
pair
<
child_id
,
int
>>
children
;
int
next_node_id
=
0
;
static
inline
constexpr
int
not_found
=
-
1
;
status
init
(
size_t
models
)
noexcept
{
try
{
children
.
reserve
(
models
);
}
catch
(
const
std
::
bad_alloc
&
)
{
std
::
vector
<
std
::
pair
<
child_id
,
int
>>
().
swap
(
children
);
irt_bad_return
(
status
::
gui_not_enough_memory
);
}
return
status
::
success
;
}
int
get_index
(
const
child_id
id
)
const
noexcept
{
auto
it
=
std
::
find
(
std
::
begin
(
children
),
std
::
end
(
children
)
,
i
d
);
if
(
it
==
std
::
end
(
children
)
)
return
not_found
;
for
(
int
i
=
0
,
e
=
length
(
children
)
;
i
!=
e
;
++
i
)
if
(
children
[
i
].
first
==
id
)
return
i
;
return
static_cast
<
int
>
(
std
::
distance
(
std
::
begin
(
children
),
it
))
;
return
not_found
;
}
int
get_index
(
const
int
node
)
const
noexcept
{
auto
it
=
std
::
find
(
std
::
begin
(
nodes
),
std
::
end
(
nodes
),
node
);
if
(
it
==
std
::
end
(
node
s
)
)
return
not_found
;
for
(
int
i
=
0
,
e
=
length
(
children
);
i
!=
e
;
++
i
)
if
(
children
[
i
].
second
==
node
)
return
i
;
return
static_cast
<
int
>
(
std
::
distance
(
std
::
begin
(
nodes
),
it
))
;
return
not_found
;
}
void
clear
()
noexcept
{
children
.
clear
();
nodes
.
clear
();
}
void
pop
(
const
int
index
)
noexcept
{
std
::
swap
(
children
[
index
],
children
.
back
());
children
.
pop_back
();
std
::
swap
(
nodes
[
index
],
nodes
.
back
());
nodes
.
pop_back
();
}
void
emplace_back
(
const
child_id
id
)
int
emplace_back
(
const
child_id
id
)
{
children
.
emplace_back
(
id
);
nodes
.
emplace_back
(
next_node_id
);
++
next_node_id
;
int
ret
=
next_node_id
++
;
children
.
emplace_back
(
id
,
ret
);
return
ret
;
}
};
...
...
@@ -180,11 +204,13 @@ struct editor
array
<
cluster_id
>
clusters_mapper
;
/* group per cluster_id */
array
<
cluster_id
>
models_mapper
;
/* group per model_id */
ImVector
<
ImVec2
>
positions
;
ImVector
<
ImVec2
>
displacements
;
top_cluster
top
;
status
initialize
(
u32
id
)
noexcept
;
void
clear
()
noexcept
;
void
reorder
()
noexcept
;
void
group
(
const
ImVector
<
int
>&
nodes
)
noexcept
;
void
ungroup
(
const
int
node
)
noexcept
;
...
...
@@ -192,9 +218,12 @@ struct editor
void
free_children
(
const
ImVector
<
int
>&
nodes
)
noexcept
;
status
copy
(
const
ImVector
<
int
>&
nodes
)
noexcept
;
void
reorder_subgroup
(
const
size_t
from
,
const
size_t
length
,
ImVec2
click_pos
)
noexcept
;
void
reorder
()
noexcept
;
bool
is_in_hierarchy
(
const
cluster
&
group
,
const
cluster_id
group_to_search
)
const
noexcept
;
cluster_id
ancestor
(
const
child_id
child
)
const
noexcept
;
int
get_top_group_ref
(
const
child_id
child
)
const
noexcept
;
cluster_id
parent
(
cluster_id
child
)
const
noexcept
{
...
...
@@ -216,7 +245,7 @@ struct editor
models_mapper
[
get_index
(
child
)]
=
parent
;
}
int
get_in
(
input_port_id
id
)
const
noexcept
static
int
get_in
(
input_port_id
id
)
noexcept
{
return
static_cast
<
int
>
(
get_index
(
id
));
}
...
...
@@ -228,7 +257,7 @@ struct editor
return
port
?
sim
.
input_ports
.
get_id
(
port
)
:
undefined
<
input_port_id
>
();
}
int
get_out
(
output_port_id
id
)
const
noexcept
static
int
get_out
(
output_port_id
id
)
noexcept
{
constexpr
u32
is_output
=
1
<<
31
;
u32
index
=
get_index
(
id
);
...
...
@@ -261,4 +290,4 @@ struct editor
}
// namespace irt
#endif
\ No newline at end of file
#endif
lib/include/irritator/core.hpp
View file @
aa8aa45e
...
...
@@ -4390,25 +4390,24 @@ struct simulation
{
return
dispatch
(
mdl
.
type
,
[
dyn_id
=
mdl
.
id
,
port
,
index
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
y
);
i
!=
e
;
++
i
)
{
if
(
dyn
->
y
[
i
]
==
port
)
{
*
index
=
static_cast
<
int
>
(
i
);
return
status
::
success
;
}
}
}
return
status
::
dynamics_unknown_port_id
;
});
[
dyn_id
=
mdl
.
id
,
port
,
index
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
y
);
i
!=
e
;
++
i
)
{
if
(
dyn
->
y
[
i
]
==
port
)
{
*
index
=
static_cast
<
int
>
(
i
);
return
status
::
success
;
}
}
}
return
status
::
dynamics_unknown_port_id
;
});
}
template
<
typename
Function
>
...
...
@@ -4416,20 +4415,19 @@ struct simulation
{
dispatch
(
mdl
.
type
,
[
this
,
&
f
,
dyn_id
=
mdl
.
id
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
if
(
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
dyn
)
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
x
);
i
!=
e
;
++
i
)
if
(
auto
*
port
=
input_ports
.
try_to_get
(
dyn
->
x
[
i
]);
port
)
f
(
*
port
);
}
return
status
::
success
;
});
[
this
,
&
f
,
dyn_id
=
mdl
.
id
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
if
(
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
dyn
)
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
x
);
i
!=
e
;
++
i
)
if
(
auto
*
port
=
input_ports
.
try_to_get
(
dyn
->
x
[
i
]);
port
)
f
(
*
port
,
dyn
->
x
[
i
]);
}
return
status
::
success
;
});
}
template
<
typename
Function
>
...
...
@@ -4437,20 +4435,20 @@ struct simulation
{
dispatch
(
mdl
.
type
,
[
this
,
&
f
,
dyn_id
=
mdl
.
id
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
if
(
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
dyn
)
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
y
);
i
!=
e
;
++
i
)
if
(
auto
*
port
=
output_ports
.
try_to_get
(
dyn
->
y
[
i
]);
port
)
f
(
*
port
);
}
return
status
::
success
;
});
[
this
,
&
f
,
dyn_id
=
mdl
.
id
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
if
(
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
dyn
)
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
y
);
i
!=
e
;
++
i
)
if
(
auto
*
port
=
output_ports
.
try_to_get
(
dyn
->
y
[
i
]);
port
)
f
(
*
port
,
dyn
->
y
[
i
]
);
}
return
status
::
success
;
});
}
status
get_input_port_index
(
const
model
&
mdl
,
...
...
@@ -4459,25 +4457,24 @@ struct simulation
{
return
dispatch
(
mdl
.
type
,
[
dyn_id
=
mdl
.
id
,
port
,
index
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
x
);
i
!=
e
;
++
i
)
{
if
(
dyn
->
x
[
i
]
==
port
)
{
*
index
=
static_cast
<
int
>
(
i
);
return
status
::
success
;
}
}
}
return
status
::
dynamics_unknown_port_id
;
});
[
dyn_id
=
mdl
.
id
,
port
,
index
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
for
(
size_t
i
=
0
,
e
=
std
::
size
(
dyn
->
x
);
i
!=
e
;
++
i
)
{
if
(
dyn
->
x
[
i
]
==
port
)
{
*
index
=
static_cast
<
int
>
(
i
);
return
status
::
success
;
}
}
}
return
status
::
dynamics_unknown_port_id
;
});
}
status
get_output_port_id
(
const
model
&
mdl
,
...
...
@@ -4486,26 +4483,24 @@ struct simulation
{
return
dispatch
(
mdl
.
type
,
[
dyn_id
=
mdl
.
id
,
index
,
port
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
[
dyn_id
=
mdl
.
id
,
index
,
port
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
irt_return_if_fail
(
0
<=
index
&&
static_cast
<
size_t
>
(
index
)
<
std
::
size
(
dyn
->
y
),
status
::
dynamics_unknown_port_id
);
irt_return_if_fail
(
0
<=
index
&&
static_cast
<
size_t
>
(
index
)
<
std
::
size
(
dyn
->
y
),
status
::
dynamics_unknown_port_id
);
*
port
=
dyn
->
y
[
index
];
return
status
::
success
;
}
*
port
=
dyn
->
y
[
index
];
return
status
::
success
;
}
return
status
::
dynamics_unknown_port_id
;
});
return
status
::
dynamics_unknown_port_id
;
});
}
status
get_input_port_id
(
const
model
&
mdl
,
...
...
@@ -4514,26 +4509,24 @@ struct simulation
{
return
dispatch
(
mdl
.
type
,
[
dyn_id
=
mdl
.
id
,
index
,
port
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
irt_return_if_fail
(
0
<=
index
&&
static_cast
<
size_t
>
(
index
)
<
std
::
size
(
dyn
->
x
),
status
::
dynamics_unknown_port_id
);
*
port
=
dyn
->
x
[
index
];
return
status
::
success
;
}
[
dyn_id
=
mdl
.
id
,
index
,
port
]
<
typename
DynamicsM
>
(
DynamicsM
&
dyn_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
{
auto
*
dyn
=
dyn_models
.
try_to_get
(
dyn_id
);
irt_return_if_fail
(
dyn
,
status
::
dynamics_unknown_id
);
irt_return_if_fail
(
0
<=
index
&&
static_cast
<
size_t
>
(
index
)
<
std
::
size
(
dyn
->
x
),
status
::
dynamics_unknown_port_id
);
*
port
=
dyn
->
x
[
index
];
return
status
::
success
;
}
return
status
::
dynamics_unknown_port_id
;
});
return
status
::
dynamics_unknown_port_id
;
});
}
template
<
typename
Iterator
>
...
...
@@ -4628,37 +4621,36 @@ public:
auto
ret
=
dispatch
(
mdl
->
type
,
[
this
,
&
mdl
,
copy
]
<
typename
DynamicsM
>
(
DynamicsM
&
dynamics_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
[
this
,
&
mdl
,
copy
]
<
typename
DynamicsM
>
(
DynamicsM
&
dynamics_models
)
->
status
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
irt_return_if_fail
(
dynamics_models
.
can_alloc
(
1
),
status
::
dynamics_not_enough_memory
);
irt_return_if_fail
(
dynamics_models
.
can_alloc
(
1
),
status
::
dynamics_not_enough_memory
);
auto
*
dyn_ptr
=
dynamics_models
.
try_to_get
(
mdl
->
id
);
irt_return_if_fail
(
dyn_ptr
,
status
::
dynamics_unknown_id
);
auto
*
dyn_ptr
=
dynamics_models
.
try_to_get
(
mdl
->
id
);
irt_return_if_fail
(
dyn_ptr
,
status
::
dynamics_unknown_id
);
auto
&
new_dyn
=
dynamics_models
.
alloc
(
*
dyn_ptr
);
auto
new_dyn_id
=
dynamics_models
.
get_id
(
new_dyn
);
auto
&
new_dyn
=
dynamics_models
.
alloc
(
*
dyn_ptr
);
auto
new_dyn_id
=
dynamics_models
.
get_id
(
new_dyn
);
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
x
,
std
::
size
(
new_dyn
.
x
),
static_cast
<
input_port_id
>
(
0
));
if
constexpr
(
is_detected_v
<
has_input_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
x
,
std
::
size
(
new_dyn
.
x
),
static_cast
<
input_port_id
>
(
0
));
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
y
,
std
::
size
(
new_dyn
.
y
),
static_cast
<
output_port_id
>
(
0
));
if
constexpr
(
is_detected_v
<
has_output_port_t
,
Dynamics
>
)
std
::
fill_n
(
new_dyn
.
y
,
std
::
size
(
new_dyn
.
y
),
static_cast
<
output_port_id
>
(
0
));
irt_return_if_bad
(
this
->
alloc
(
new_dyn
,
new_dyn_id
,
mdl
->
name
.
c_str
()));
irt_return_if_bad
(
this
->
alloc
(
new_dyn
,
new_dyn_id
,
mdl
->
name
.
c_str
()));
*
copy
=
new_dyn
.
id
;
*
copy
=
new_dyn
.
id
;
return
status
::
success
;
});
return
status
::
success
;
});
irt_return_if_bad
(
ret
);
}
...
...
@@ -4670,8 +4662,8 @@ public:
auto
ret
=
dispatch
(
mdl
->
type
,
[
this
,
model_it
,
first
,
last
,
out
]
<
typename
DynamicsM
>
(
DynamicsM
&
dynamics_models
)
{
[
this
,
model_it
,
first
,
last
,
out
]
<
typename
DynamicsM
>
(
DynamicsM
&
dynamics_models
)
{
using
Dynamics
=
typename
DynamicsM
::
value_type
;
auto
*
mdl_src
=
this
->
models
.
try_to_get
(
*
(
first
+
model_it
));
...
...
@@ -5162,8 +5154,7 @@ public:
{
return
dispatch
(
mdl
.
type
,
[
this
,
&
mdl
,
t
]
<
typename
DynamicsModels
>
(
DynamicsModels
&
dyn_models
)
{
[
this
,
&
mdl
,
t
]
<
typename
DynamicsModels
>
(
DynamicsModels
&
dyn_models
)
{
return
this
->
make_initialize
(
mdl
,
dyn_models
.
get
(
mdl
.
id
),
t
);
});
}
...
...
@@ -5229,12 +5220,12 @@ public:
time
t
,
flat_list
<
output_port_id
>&
o
)
noexcept
{
return
dispatch
(
mdl
.
type
,
[
this
,
&
mdl
,
t
,
&
o
]
<
typename
DynamicsModels
>
(
DynamicsModels
&
dyn_models
)
{
return
this
->
make_transition
(
mdl
,
dyn_models
.
get
(
mdl
.
id
),
t
,
o
);
});
return
dispatch
(
mdl
.
type
,
[
this
,
&
mdl
,
t
,
&
o
]
<
typename
DynamicsModels
>
(
DynamicsModels
&
dyn_models
)
{
return
this
->
make_transition
(
mdl
,
dyn_models
.
get
(
mdl
.
id
),
t
,
o
);
});
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment