Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Maintenance - Mise à jour mensuelle Lundi 6 Février entre 7h00 et 9h00
Open sidebar
Gauthier Quesnel
irritator
Commits
8b57e7d6
Commit
8b57e7d6
authored
Apr 20, 2020
by
Gauthier Quesnel
Browse files
gui: add a window logging system
parent
3bde1162
Pipeline
#11033
passed with stage
in 47 seconds
Changes
4
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
app/gui/CMakeLists.txt
View file @
8b57e7d6
...
...
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project
(
irritator-gui VERSION 0.1.0 LANGUAGES CXX
)
set
(
gui_sources
imnodes.cpp imnodes.hpp node-editor.cpp
imnodes.cpp imnodes.hpp
window-logger.cpp
node-editor.cpp
${
PROJECT_SOURCE_DIR
}
/../../external/imgui/imgui.cpp
${
PROJECT_SOURCE_DIR
}
/../../external/imgui/imgui.h
${
PROJECT_SOURCE_DIR
}
/../../external/imgui/imgui_demo.cpp
...
...
app/gui/gui.hpp
View file @
8b57e7d6
...
...
@@ -5,6 +5,8 @@
#ifndef ORG_VLEPROJECT_IRRITATOR_APP_GUI_2020
#define ORG_VLEPROJECT_IRRITATOR_APP_GUI_2020
#include
<imgui.h>
namespace
irt
{
void
...
...
@@ -16,6 +18,22 @@ node_editor_show();
void
node_editor_shutdown
();
struct
window_logger
{
ImGuiTextBuffer
buffer
;
ImGuiTextFilter
filter
;
ImVector
<
int
>
line_offsets
;
bool
auto_scroll
=
true
;
bool
scroll_to_bottom
=
false
;
void
clear
()
noexcept
;
void
log
(
const
int
level
,
const
char
*
fmt
,
...)
IM_FMTARGS
(
3
);
void
log
(
const
int
level
,
const
char
*
fmt
,
va_list
args
)
IM_FMTLIST
(
3
);
void
show
(
bool
*
is_show
);
};
}
// namespace irt
#endif
app/gui/node-editor.cpp
View file @
8b57e7d6
...
...
@@ -17,6 +17,8 @@
namespace
irt
{
window_logger
log_w
;
enum
class
simulation_status
{
success
,
...
...
@@ -87,12 +89,14 @@ run_simulation(simulation& sim,
{
current
=
begin
;
if
(
irt
::
is_bad
(
sim
.
initialize
(
current
)))
{
log_w
.
log
(
3
,
"Simulation initialization failure"
);
st
=
simulation_status
::
internal_error
;
return
;
}
do
{
if
(
!
is_success
(
sim
.
run
(
current
)))
{
log_w
.
log
(
3
,
"Simulation run failure"
);
st
=
simulation_status
::
internal_error
;
return
;
}
...
...
@@ -130,7 +134,7 @@ struct editor
model_id
get_model
(
int
index
)
const
noexcept
{
auto
*
mdl
=
sim
.
models
.
try_to_get
(
static_cast
<
u32
>
(
index
));
auto
*
mdl
=
sim
.
models
.
try_to_get
(
static_cast
<
u32
>
(
index
));
return
sim
.
models
.
get_id
(
mdl
);
}
...
...
@@ -708,13 +712,12 @@ show_editor(const char* editor_name, editor& ed)
if
(
ImGui
::
BeginMenu
(
"Examples"
))
{
if
(
ImGui
::
MenuItem
(
"Insert Lotka Volterra model"
))
{
if
(
is_bad
(
ed
.
initialize_lotka_volterra
()))
fmt
::
print
(
"Error: f
ail to initialize a
l
otka
v
olterra"
);
log_w
.
log
(
3
,
"F
ail to initialize a
L
otka
V
olterra"
);
}
if
(
ImGui
::
MenuItem
(
"Insert Iz
z
hikevitch model"
))
{
if
(
ImGui
::
MenuItem
(
"Insert Izhikevitch model"
))
{
if
(
is_bad
(
ed
.
initialize_izhikevitch
()))
fmt
::
print
(
stderr
,
"fail to initialize an Izzhikevitch model
\n
"
);
log_w
.
log
(
3
,
"Fail to initialize an Izhikevitch model"
);
}
ImGui
::
EndMenu
();
...
...
@@ -724,7 +727,7 @@ show_editor(const char* editor_name, editor& ed)
}
ImGui
::
Text
(
"X -- delete selected nodes and/or connections /"
" D -- duplicate selected nodes
and/or connections
"
);
" D -- duplicate selected nodes"
);
imnodes
::
BeginNodeEditor
();
...
...
@@ -758,8 +761,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
none_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
none_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
none_models
.
get_id
(
mdl
),
"none"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
none_models
.
get_id
(
mdl
),
"none"
);
}
}
...
...
@@ -767,9 +769,8 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
integrator_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
integrator_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
integrator_models
.
get_id
(
mdl
),
"integrator"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
integrator_models
.
get_id
(
mdl
),
"integrator"
);
}
}
...
...
@@ -777,9 +778,8 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
quantifier_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
quantifier_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
quantifier_models
.
get_id
(
mdl
),
"quantifier"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
quantifier_models
.
get_id
(
mdl
),
"quantifier"
);
}
}
...
...
@@ -787,8 +787,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
adder_2_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
adder_2_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
adder_2_models
.
get_id
(
mdl
),
"adder"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
adder_2_models
.
get_id
(
mdl
),
"adder"
);
}
}
...
...
@@ -796,8 +795,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
adder_3_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
adder_3_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
adder_3_models
.
get_id
(
mdl
),
"adder"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
adder_3_models
.
get_id
(
mdl
),
"adder"
);
}
}
...
...
@@ -805,8 +803,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
adder_4_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
adder_4_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
adder_4_models
.
get_id
(
mdl
),
"adder"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
adder_4_models
.
get_id
(
mdl
),
"adder"
);
}
}
...
...
@@ -814,8 +811,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
mult_2_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
mult_2_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
mult_2_models
.
get_id
(
mdl
),
"mult"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
mult_2_models
.
get_id
(
mdl
),
"mult"
);
}
}
...
...
@@ -823,8 +819,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
mult_3_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
mult_3_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
mult_3_models
.
get_id
(
mdl
),
"mult"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
mult_3_models
.
get_id
(
mdl
),
"mult"
);
}
}
...
...
@@ -832,8 +827,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
mult_4_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
mult_4_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
mult_4_models
.
get_id
(
mdl
),
"mult"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
mult_4_models
.
get_id
(
mdl
),
"mult"
);
}
}
...
...
@@ -841,8 +835,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
counter_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
counter_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
counter_models
.
get_id
(
mdl
),
"counter"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
counter_models
.
get_id
(
mdl
),
"counter"
);
}
}
...
...
@@ -850,9 +843,8 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
generator_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
generator_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
generator_models
.
get_id
(
mdl
),
"generator"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
generator_models
.
get_id
(
mdl
),
"generator"
);
}
}
...
...
@@ -860,9 +852,8 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
constant_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
constant_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
constant_models
.
get_id
(
mdl
),
"constant"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
constant_models
.
get_id
(
mdl
),
"constant"
);
}
}
...
...
@@ -870,8 +861,7 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
cross_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
cross_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
cross_models
.
get_id
(
mdl
),
"cross"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
cross_models
.
get_id
(
mdl
),
"cross"
);
}
}
...
...
@@ -879,14 +869,13 @@ show_editor(const char* editor_name, editor& ed)
if
(
ed
.
sim
.
time_func_models
.
can_alloc
(
1u
)
&&
ed
.
sim
.
models
.
can_alloc
(
1u
))
{
auto
&
mdl
=
ed
.
sim
.
time_func_models
.
alloc
();
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
time_func_models
.
get_id
(
mdl
),
"time-func"
);
ed
.
sim
.
alloc
(
mdl
,
ed
.
sim
.
time_func_models
.
get_id
(
mdl
),
"time-func"
);
}
}
ImGui
::
EndPopup
();
//imnodes::SetNodeScreenSpacePos(new_node, click_pos);
//
imnodes::SetNodeScreenSpacePos(new_node, click_pos);
}
ImGui
::
PopStyleVar
();
...
...
@@ -914,9 +903,8 @@ show_editor(const char* editor_name, editor& ed)
std
::
fill_n
(
selected_links
.
data
(),
selected_links
.
size
(),
-
1
);
imnodes
::
GetSelectedLinks
(
selected_links
.
data
());
std
::
sort
(
selected_links
.
begin
(),
selected_links
.
end
(),
std
::
less
<
int
>
());
std
::
sort
(
selected_links
.
begin
(),
selected_links
.
end
(),
std
::
less
<
int
>
());
for
(
size_t
i
=
0
;
i
!=
selected_links
.
size
();
++
i
)
assert
(
selected_links
[
i
]
!=
-
1
);
...
...
@@ -926,11 +914,14 @@ show_editor(const char* editor_name, editor& ed)
int
current_link_id
=
0
;
output_port
*
o_port
=
nullptr
;
while
(
ed
.
sim
.
output_ports
.
next
(
o_port
)
&&
link_id_to_delete
!=
-
1
)
{
while
(
ed
.
sim
.
output_ports
.
next
(
o_port
)
&&
link_id_to_delete
!=
-
1
)
{
for
(
const
auto
dst
:
o_port
->
connections
)
{
if
(
auto
*
i_port
=
ed
.
sim
.
input_ports
.
try_to_get
(
dst
);
i_port
)
{
if
(
auto
*
i_port
=
ed
.
sim
.
input_ports
.
try_to_get
(
dst
);
i_port
)
{
if
(
current_link_id
==
link_id_to_delete
)
{
ed
.
sim
.
disconnect
(
ed
.
sim
.
output_ports
.
get_id
(
o_port
),
dst
);
ed
.
sim
.
disconnect
(
ed
.
sim
.
output_ports
.
get_id
(
o_port
),
dst
);
++
i
;
...
...
@@ -1065,7 +1056,7 @@ void
node_editor_initialize
()
{
if
(
!
ed
.
initialize
())
{
fmt
::
print
(
stderr
,
"node_editor_initialize failed
\n
"
);
log_w
.
log
(
3
,
"Fail to initialize node editor
\n
"
);
return
;
}
...
...
@@ -1076,7 +1067,10 @@ void
node_editor_show
()
{
if
(
ed
.
initialized
)
show_editor
(
"editor1"
,
ed
);
show_editor
(
"Editor 1"
,
ed
);
static
bool
show_log
=
true
;
log_w
.
show
(
&
show_log
);
}
void
...
...
app/gui/window-logger.cpp
0 → 100644
View file @
8b57e7d6
// Copyright (c) 2020 INRA Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include
"gui.hpp"
namespace
irt
{
void
window_logger
::
clear
()
noexcept
{
buffer
.
clear
();
line_offsets
.
clear
();
line_offsets
.
push_back
(
0
);
}
static
const
char
*
log_prefix
[]
=
{
"[emergency]"
,
"[alert]"
,
"[critical]"
,
"[error]"
,
"[warning]"
,
"[notice]"
,
"[info]"
,
"[debug]"
};
void
window_logger
::
log
(
const
int
level
,
const
char
*
fmt
,
...)
{
auto
old_size
=
buffer
.
size
();
va_list
args
;
va_start
(
args
,
fmt
);
buffer
.
append
(
log_prefix
[
level
]);
buffer
.
appendfv
(
fmt
,
args
);
va_end
(
args
);
for
(
auto
new_size
=
buffer
.
size
();
old_size
<
new_size
;
++
old_size
)
if
(
buffer
[
old_size
]
==
'\n'
)
line_offsets
.
push_back
(
old_size
+
1
);
if
(
auto_scroll
)
scroll_to_bottom
=
true
;
}
void
window_logger
::
log
(
const
int
level
,
const
char
*
fmt
,
va_list
args
)
{
auto
old_size
=
buffer
.
size
();
buffer
.
append
(
log_prefix
[
level
]);
buffer
.
appendfv
(
fmt
,
args
);
for
(
auto
new_size
=
buffer
.
size
();
old_size
<
new_size
;
++
old_size
)
if
(
buffer
[
old_size
]
==
'\n'
)
line_offsets
.
push_back
(
old_size
+
1
);
if
(
auto_scroll
)
scroll_to_bottom
=
true
;
}
void
window_logger
::
show
(
bool
*
is_show
)
{
ImGui
::
SetNextWindowSize
(
ImVec2
(
500
,
400
),
ImGuiCond_FirstUseEver
);
if
(
!
ImGui
::
Begin
(
"Log"
,
is_show
))
{
ImGui
::
End
();
return
;
}
if
(
ImGui
::
BeginPopup
(
"Options"
))
{
if
(
ImGui
::
Checkbox
(
"Auto-scroll"
,
&
auto_scroll
))
if
(
auto_scroll
)
scroll_to_bottom
=
true
;
ImGui
::
EndPopup
();
}
if
(
ImGui
::
Button
(
"Options"
))
ImGui
::
OpenPopup
(
"Options"
);
ImGui
::
SameLine
();
bool
need_clear
=
ImGui
::
Button
(
"Clear"
);
ImGui
::
SameLine
();
bool
need_copy
=
ImGui
::
Button
(
"Copy"
);
ImGui
::
SameLine
();
filter
.
Draw
(
"Filter"
,
-
100.0
f
);
ImGui
::
Separator
();
ImGui
::
BeginChild
(
"scrolling"
,
ImVec2
(
0
,
0
),
false
,
ImGuiWindowFlags_HorizontalScrollbar
);
if
(
need_clear
)
clear
();
if
(
need_copy
)
ImGui
::
LogToClipboard
();
ImGui
::
PushStyleVar
(
ImGuiStyleVar_ItemSpacing
,
ImVec2
(
0
,
0
));
const
char
*
buf
=
buffer
.
begin
();
const
char
*
buf_end
=
buffer
.
end
();
if
(
filter
.
IsActive
())
{
for
(
auto
line_no
=
0
;
line_no
<
line_offsets
.
Size
;
line_no
++
)
{
const
char
*
line_start
=
buf
+
line_offsets
[
line_no
];
const
char
*
line_end
=
(
line_no
+
1
<
line_offsets
.
Size
)
?
(
buf
+
line_offsets
[
line_no
+
1
]
-
1
)
:
buf_end
;
if
(
filter
.
PassFilter
(
line_start
,
line_end
))
ImGui
::
TextUnformatted
(
line_start
,
line_end
);
}
}
else
{
ImGuiListClipper
clipper
;
clipper
.
Begin
(
line_offsets
.
Size
);
while
(
clipper
.
Step
())
{
for
(
int
line_no
=
clipper
.
DisplayStart
;
line_no
<
clipper
.
DisplayEnd
;
line_no
++
)
{
const
char
*
line_start
=
buf
+
line_offsets
[
line_no
];
const
char
*
line_end
=
(
line_no
+
1
<
line_offsets
.
Size
)
?
(
buf
+
line_offsets
[
line_no
+
1
]
-
1
)
:
buf_end
;
ImGui
::
TextUnformatted
(
line_start
,
line_end
);
}
}
clipper
.
End
();
}
ImGui
::
PopStyleVar
();
if
(
scroll_to_bottom
)
ImGui
::
SetScrollHereY
(
1.0
f
);
scroll_to_bottom
=
false
;
ImGui
::
EndChild
();
ImGui
::
End
();
}
}
// irt
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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