Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control panel for simulations #443

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1d769c0
Simple button group class
lemniscate8 Aug 2, 2021
be39c0c
Idea for concatenating button groups
lemniscate8 Aug 2, 2021
1a160a4
Toggle button setup for play/pause button
lemniscate8 Aug 2, 2021
ce2d52e
Some setup for the toggle button
lemniscate8 Aug 3, 2021
8992466
Fix switch styling in Bootstrap v5.0
lemniscate8 Aug 3, 2021
22cb37f
Get toggle button working
lemniscate8 Aug 3, 2021
033ac59
Some documentation
lemniscate8 Aug 4, 2021
5db885f
Add styling for imbedded toggle button groups
lemniscate8 Aug 4, 2021
8f649f3
Input works on radio buttons now
lemniscate8 Aug 4, 2021
6ebd496
No need for components as members
lemniscate8 Aug 9, 2021
9f5a3fd
Control panel basics
lemniscate8 Aug 9, 2021
875640b
Allow grouping buttons in ControlPanel
lemniscate8 Aug 10, 2021
7408f8f
No more control panel for now
lemniscate8 Aug 18, 2021
2149bef
Ironing out
lemniscate8 Aug 19, 2021
b9fcedc
Use checker function
lemniscate8 Aug 19, 2021
c2e1aa0
Fix bug with toggle clicks
lemniscate8 Aug 20, 2021
3ae3215
Optimize checker and fix reference issues
lemniscate8 Aug 20, 2021
50ba064
Document control panel
lemniscate8 Aug 20, 2021
b099a3b
Remove step button disabling
lemniscate8 Aug 20, 2021
0d3256e
Add documentation
lemniscate8 Aug 20, 2021
b0be177
Swap rate and unit parameters in constructor
lemniscate8 Aug 25, 2021
5a4cc26
Add unit test for control panel
lemniscate8 Aug 25, 2021
21f8b50
Test for ToggleButtonGroup
lemniscate8 Aug 25, 2021
d0faa5c
Address feedback
lemniscate8 Sep 3, 2021
e4f3f2a
More documentation
lemniscate8 Sep 3, 2021
ca489f3
Simplify some stuff
lemniscate8 Sep 3, 2021
2aac8ac
Remove cout
lemniscate8 Sep 3, 2021
c9abe28
More descriptive template types
lemniscate8 Sep 9, 2021
8ba6455
Explain DivInfo constructor for Div
lemniscate8 Sep 9, 2021
e3db915
Use map to hold checker instances
lemniscate8 Sep 22, 2021
6be2bb2
Name change for clarity
lemniscate8 Sep 27, 2021
892c1d0
Merge branch 'master' into control-panel
mmore500 Sep 29, 2021
0ef6beb
Include string header
mmore500 Sep 29, 2021
7bab656
Include string header
mmore500 Sep 29, 2021
9179f2e
Implement and test DisjointVariant
mmore500 Sep 29, 2021
30e0ed1
Use relative path for in-library includes
mmore500 Sep 29, 2021
9927976
Fix duplicated constructor
mmore500 Sep 29, 2021
30ae1ca
Add missing header
mmore500 Sep 29, 2021
e65067c
Add Assign and Activate methods
mmore500 Sep 29, 2021
b150900
Refactor ControlPanel to use DisjointVariant
mmore500 Sep 29, 2021
359be34
Add DyanmicRefreshChecker
mmore500 Sep 29, 2021
167ce5b
Add zero-overhead static test
mmore500 Sep 29, 2021
4deacf4
Buff DisjointVariant static asserts
mmore500 Sep 29, 2021
6083037
Implement and test ApplyToAll
mmore500 Oct 1, 2021
eae6c72
Mock up describe functions
mmore500 Oct 1, 2021
a656377
Revert "Refactor ControlPanel to use DisjointVariant"
mmore500 Oct 1, 2021
414e349
Minor refactoring on @lemniscate8's approach
mmore500 Oct 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Optimize checker and fix reference issues
lemniscate8 committed Aug 20, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 3ae32156fc848ce5f35942e08068976ec432ed88
67 changes: 39 additions & 28 deletions include/emp/prefab/ControlPanel.hpp
Original file line number Diff line number Diff line change
@@ -25,20 +25,44 @@ namespace emp::prefab {
std::map<std::string, int> refresh_rates{
{"MILLISECONDS", 100}, {"FRAMES", 5}
};
checker_func_t redraw_checker;

const std::map<std::string, const checker_func_t> refresh_checkers{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unordered_map

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain what they take as a param and what they return

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm... it looks like you're only allowing one refresh checker at a time?

What I would do is make two functor classes as public members of this class

ControlPanel::MillisecondRefresher

ControlPanel::FrameRefresher

Both functor classes would take a value as their constructor

instead of storing refresh_rates, refrhesh_units, and refresh_checkers

I would just store a std::function refresh_checker

{ "MILLISECONDS",
[elapsed_milliseconds = 0, this]
(const web::Animate & anim) mutable {
int rate = this->refresh_rates[this->refresh_unit];
elapsed_milliseconds += anim.GetStepTime();
if (elapsed_milliseconds > rate) {
elapsed_milliseconds -= rate;
if (elapsed_milliseconds > rate) elapsed_milliseconds = 0;
return true;
}
return false;
}},
{ "FRAMES",
[this](const web::Animate & anim) {
return anim.GetFrameCount() % this->refresh_rates[this->refresh_unit];
}
}
};

checker_func_t do_redraw;

emp::vector<web::Widget> refresh_list;
std::function<void()> simulation;

public:
ControlPanelInfo(const std::string & in_id="")
: DivInfo(in_id), simulation([](){ ; }) { ; }
: DivInfo(in_id),
refresh_unit("MILLISECONDS"),
do_redraw(refresh_checkers.at(refresh_unit)),
simulation([](){ ; }) { ; }

const checker_func_t & GetRedrawChecker() const {
return redraw_checker;
return do_redraw;
}

void SetSimulation(std::function<void()> & sim) {
void SetSimulation(const std::function<void()> & sim) {
simulation = sim;
}

@@ -48,24 +72,7 @@ namespace emp::prefab {

void SetUnit(const std::string & unit) {
refresh_unit = unit;

const int & rate = refresh_rates[refresh_unit];
if (unit == "MILLISECONDS") {
redraw_checker = [elapsed_milliseconds = 0, rate]
(const web::Animate & anim) mutable {
elapsed_milliseconds += anim.GetStepTime();
if (elapsed_milliseconds > rate) {
elapsed_milliseconds -= rate;
if (elapsed_milliseconds > rate) elapsed_milliseconds = 0;
return true;
}
return false;
};
} else if (unit == "FRAMES") {
redraw_checker = [rate](const web::Animate & anim) {
return anim.GetFrameCount() % rate;
};
}
do_redraw = refresh_checkers.at(refresh_unit);
}

void SetRate(const int & rate) {
@@ -139,15 +146,17 @@ namespace emp::prefab {
);

AddAnimation(GetID(),
[&, run_sim=GetSimulation(),
refresh_list=Info()->GetRefreshList(),
check_redraw=Info()->GetRedrawChecker()]
[&run_sim=GetSimulation(),
&refresh_list=Info()->GetRefreshList(),
&do_redraw=Info()->GetRedrawChecker()]
(const web::Animate & anim) mutable {
// Run the simulation function every frame
run_sim();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would name this step_sim, or update_sim

// Redraw widgets according to a rule
if(check_redraw(anim)) {
for (emp::web::Widget & wid : refresh_list) {
if(do_redraw(anim)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename do_redraw should_redraw

I might also move auto& wid : refresh_list wid.Redraw to a helper method (probably private?) called do_redraw

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or DoRedraw

std::cout << "List size " << refresh_list.size() << std::endl;
for (auto & wid : refresh_list) {
std::cout << "Redrawing " << wid.GetID() << std::endl;
wid.Redraw();
}
}
@@ -158,6 +167,7 @@ namespace emp::prefab {
[&anim=Animate(GetID()), step=web::Button(step)]
(bool is_active) mutable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const bool

if (is_active) {

anim.Start();
} else {
anim.Stop();
@@ -181,7 +191,7 @@ namespace emp::prefab {
new internal::ControlPanelInfo(in_id)
) { ; }

ControlPanel & SetSimulation(std::function<void()> & sim) {
ControlPanel & SetSimulation(const std::function<void()> & sim) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SetSimulationUpdateCallback

Info()->SetSimulation(sim);
return *this;
}
@@ -201,6 +211,7 @@ namespace emp::prefab {

void AddToRefreshList(Widget & area) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a definite use case for public access to this? We can make it private and then always make it public later

Info()->GetRefreshList().push_back(area);
std::cout << Info()->GetRefreshList().size() << std::endl;
}

template <typename IN_TYPE>