Empirical
Animate.h
Go to the documentation of this file.
1 
16 #ifndef EMP_WEB_ANIMATE_H
17 #define EMP_WEB_ANIMATE_H
18 
19 #include <functional>
20 
21 #include "../base/assert.h"
22 #include "../base/vector.h"
23 
24 #include "Button.h"
25 #include "emfunctions.h"
26 #include "JSWrap.h"
27 #include "Widget.h"
28 
29 
30 namespace emp {
31 namespace web {
32 
61 
62  class Animate {
63  protected:
64 
66  using anim_fun_t = std::function<void(const Animate &)>;
67 
70  bool active;
71  bool do_step;
72  size_t callback_id;
73 
74  double start_time;
75  double prev_time;
76  double cur_time;
77  double run_time;
78 
80 
82 
84 
85  void LoadTargets() { ; }
86  template <typename... T>
87  void LoadTargets(const web::Widget & target1, const T&... other_targets) {
88  targets.push_back(target1);
89  LoadTargets(other_targets...);
90  }
91 
92  void AdvanceFrame() {
93  if (!active && !do_step) return; // If Stop has been called, halt animating.
94 
95  prev_time = cur_time; // Update timing.
96  cur_time = emp::GetTime();
97  do_step = false; // Make sure we don't keep advancing by a single step.
98  if (anim_fun) anim_fun(*this); // If anim function exist, call it and send this object.
99  DoFrame(); // Call DoFrame in this class.
100 
101  // Loop through all widget targets to be redrawn and do so.
102  for (auto & w : targets) { w.Redraw(); }
103 
104  // Setup the callback for the next frame of the animation.
105  EM_ASM_ARGS({
106  requestAnimFrame(function() { emp.Callback($0); });
107  }, callback_id);
108 
109  frame_count++;
110  }
111 
114  virtual void DoFrame() { ; }
115 
116  public:
120  Animate() : active(false), do_step(false), run_time(0.0), frame_count(0)
121  {
122  emp::InitializeAnim(); // Make sure JS is intialized for animations.
123  callback_id = JSWrap( std::function<void()>([this](){ this->AdvanceFrame(); }) );
124  }
125 
128  template <typename... W_TYPES>
129  Animate(const anim_fun_t & fun, W_TYPES&... targets) : Animate()
130  {
131  anim_fun = fun;
132  LoadTargets(targets...);
133  }
134 
135  template <typename... W_TYPES>
136  Animate(const std::function<void(double)> & fun, W_TYPES&... targets)
137  : Animate([fun,this](const Animate &){fun(GetStepTime());}, targets...) { ; }
138 
139  template <typename... W_TYPES>
140  Animate(const std::function<void()> & fun, W_TYPES&... targets)
141  : Animate([fun](const Animate &){fun();}, targets...) { ; }
142 
143  virtual ~Animate() { ; }
144 
146  Animate(const Animate &) = delete;
147  Animate & operator=(const Animate &) = delete;
148 
150  void Start() {
151  if (active) return; // If animation is already active, ignore start.
152  active=true; // Mark active.
153  do_step=false; // Shouild be continuously active.
154  start_time = emp::GetTime(); // Record the time that we started the animation.
155  cur_time = start_time; // Initialize cur_time to now.
156  AdvanceFrame(); // Take the first animation step to get going.
157  }
158 
160  void Stop() {
161  run_time += emp::GetTime() - start_time;
162  active = false;
163  }
164 
166  void Step() {
167  do_step = true;
168  AdvanceFrame();
169  // @CAO modify run time?
170  }
171 
173  void ToggleActive() { if (active) Stop(); else Start(); }
174 
176  bool GetActive() const { return active; }
177 
179  bool GetDoStep() const { return do_step; }
180 
182  double GetStartTime() const { return start_time; }
183 
185  double GetPrevTime() const { return prev_time; }
186 
188  double GetCurTime() const { return cur_time; }
189 
191  double GetStepTime() const { return cur_time - prev_time; }
192 
194  double GetRunTime() const { return run_time + cur_time - start_time; }
195 
197  int GetFrameCount() const { return frame_count; }
198 
201  void SetCallback(const anim_fun_t & fun) { anim_fun = fun; }
202 
205  void SetCallback(const std::function<void(double)> & fun) {
206  anim_fun = [fun, this](const Animate &){fun(GetStepTime());};
207  }
208 
210  void SetCallback(const std::function<void()> & fun) {
211  anim_fun = [fun](const Animate &){fun();};
212  }
213 
218  Button GetToggleButton(const std::string & but_name, const std::string & start_label="Start", const std::string & stop_label="Stop") {
219  toggle_but = Button( [this, but_name, start_label, stop_label]() {
220  ToggleActive();
221  toggle_but.Label(active ? stop_label : start_label);
222  }, start_label, but_name);
223  return toggle_but;
224  }
225 
229  Button GetStepButton(const std::string & but_name, const std::string & label="Step") {
230  step_but = Button( [this, but_name, label]() {
231  this->do_step = true;
232  this->AdvanceFrame();
233  }, label, but_name);
234  return step_but;
235  }
236  };
237 
238 }
239 }
240 
241 #endif
double GetTime()
Get the current time, as provided by the web browser.
Definition: emfunctions.h:53
Button GetStepButton(const std::string &but_name, const std::string &label="Step")
Definition: Animate.h:229
Animate(const std::function< void()> &fun, W_TYPES &...targets)
Definition: Animate.h:140
Create/control an HTML button and call a specified function when that button is clicked.
void SetCallback(const std::function< void(double)> &fun)
Definition: Animate.h:205
Button step_but
A button to advance this animation one step.
Definition: Animate.h:83
Button toggle_but
A button to start/stop this animation.
Definition: Animate.h:81
void Start()
Start this animation running.
Definition: Animate.h:150
anim_fun_t anim_fun
Function to repeatedly run for animation.
Definition: Animate.h:68
bool GetActive() const
Determine if this animation is currently running.
Definition: Animate.h:176
Animate(const anim_fun_t &fun, W_TYPES &...targets)
Definition: Animate.h:129
double run_time
How much run time has accumulated?
Definition: Animate.h:77
void LoadTargets(const web::Widget &target1, const T &...other_targets)
Definition: Animate.h:87
bool GetDoStep() const
Determine if this animation is currently in the process of running a single step. ...
Definition: Animate.h:179
void push_back(PB_Ts &&...args)
Definition: vector.h:189
int frame_count
How many animation frames have gone by?
Definition: Animate.h:79
bool active
Is this animation currently running?
Definition: Animate.h:70
An object that, when active, repeatedly calls a function as fast as possible, to a maximum of 60 fram...
Definition: Animate.h:62
void SetCallback(const std::function< void()> &fun)
Set a new function for this animation to call when running that takes no arguments.
Definition: Animate.h:210
Specialized, useful function for Empirical.
double GetStepTime() const
Determine how long the last step between frames took.
Definition: Animate.h:191
double GetPrevTime() const
Determine the time point when this animation last updated a frame.
Definition: Animate.h:185
bool do_step
Should this animation take just a single step?
Definition: Animate.h:71
void AdvanceFrame()
Definition: Animate.h:92
void Stop()
Halt this animation for now.
Definition: Animate.h:160
double prev_time
What was the time point of the previous frame?
Definition: Animate.h:75
std::function< void(const Animate &)> anim_fun_t
The full version of the animate function takes a const reference to the animate object.
Definition: Animate.h:66
void LoadTargets()
Definition: Animate.h:85
int GetFrameCount() const
Determine how many total frames have existed thus far in this animation.
Definition: Animate.h:197
Animate & operator=(const Animate &)=delete
static bool InitializeAnim()
Stub for when Emscripten is not in use.
Definition: init.h:104
double GetStartTime() const
Return the time point that this animation started MOST RECENTLY.
Definition: Animate.h:182
Button GetToggleButton(const std::string &but_name, const std::string &start_label="Start", const std::string &stop_label="Stop")
Definition: Animate.h:218
Widgets maintain individual components on a web page and link to Elements.
double GetRunTime() const
Determine the total amount of time that this animation has run.
Definition: Animate.h:194
Wrap a C++ function and convert it to an integer that can be called from Javascript.
void Step()
Take a single step in this animation.
Definition: Animate.h:166
If we are in emscripten, make sure to include the header.
Definition: array.h:37
virtual ~Animate()
Definition: Animate.h:143
Button & Label(const std::string &in_label)
Set a new label to appear on this Button.
Definition: Button.h:154
double GetCurTime() const
Get the current time of the animation.
Definition: Animate.h:188
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
Create or control an HTML Button object that you can manipulate and update as needed.
Definition: Button.h:42
Widget is effectively a smart pointer to a WidgetInfo object, plus some basic accessors.
Definition: Widget.h:78
emp::vector< web::Widget > targets
What widgets should be refreshed after each frame?
Definition: Animate.h:69
double cur_time
What time did the current frame start?
Definition: Animate.h:76
void ToggleActive()
Toggle whether this animation is running or paused.
Definition: Animate.h:173
Animate()
Definition: Animate.h:120
Animate(const std::function< void(double)> &fun, W_TYPES &...targets)
Definition: Animate.h:136
double start_time
At what time did this animation most recently start?
Definition: Animate.h:74
size_t callback_id
Intenral ID for javascript to call back AdvanceFrame()
Definition: Animate.h:72
virtual void DoFrame()
Definition: Animate.h:114
void SetCallback(const anim_fun_t &fun)
Definition: Animate.h:201