Empirical
RawImage.h
Go to the documentation of this file.
1 
10 #ifndef EMP_RAW_IMAGE_H
11 #define EMP_RAW_IMAGE_H
12 
13 #include <functional>
14 #include <map>
15 #include <string>
16 #include <vector>
17 
18 #include "../base/Ptr.h"
19 #include "../base/vector.h"
20 #include "../control/Signal.h"
21 #include "../tools/map_utils.h"
22 
23 #include "emfunctions.h"
24 #include "JSWrap.h"
25 
26 namespace emp {
27 
28  namespace internal {
30  struct ImageInfo {
31  int img_id;
32  std::string url;
33  mutable bool has_loaded;
34  mutable bool has_error;
37 
38  ImageInfo(const std::string & _url)
39  : img_id(-1), url(_url), has_loaded(false), has_error(false), on_load(), on_error()
40  {
41  size_t loaded_callback = JSWrapOnce( std::function<void()>(std::bind(&ImageInfo::MarkLoaded, this)) );
42  size_t error_callback = JSWrapOnce( std::function<void()>(std::bind(&ImageInfo::MarkError, this)) );
43 
44  img_id = EM_ASM_INT({
45  var url = Pointer_stringify($0);
46  var img_id = emp_i.images.length;
47  emp_i.images[img_id] = new Image();
48  emp_i.images[img_id].src = url;
49 
50  emp_i.images[img_id].onload = function() {
51  emp_i.image_load_count += 1;
52  emp.Callback($1);
53  };
54 
55  emp_i.images[img_id].onerror = function() {
56  emp_i.image_error_count += 1;
57  emp.Callback($2);
58  };
59 
60  return img_id;
61  }, url.c_str(), loaded_callback, error_callback);
62  }
63 
65  void MarkLoaded() {
66  has_loaded = true; // Mark that load is finished for future use.
67  on_load.Trigger(); // Trigger any other code that needs to be run now.
68  on_load.Clear(); // Now that the load is finished, we don't need to run these again.
69  }
70 
72  void MarkError() {
73  has_error = true;
74  emp::Alert(std::string("Error loading image: ") + url);
75  on_error.Trigger(); // Trigger any other code that needs to be run now.
76  on_error.Clear(); // Now that the load is finished, we don't need to run these again.
77  }
78 
80  void OnLoad(const std::function<void()> & callback_fun) {
81  on_load.AddAction(callback_fun);
82  }
83 
85  void OnError(const std::function<void()> & callback_fun) {
86  on_error.AddAction(callback_fun);
87  }
88  };
89 
90  class ImageManager {
91  private:
92  emp::vector<Ptr<ImageInfo>> image_info;
93  std::map<std::string, size_t> image_id_map;
94 
95  public:
96  ImageManager() : image_info(0), image_id_map() { ; }
98  for (auto ptr : image_info) ptr.Delete();
99  }
100 
102  bool Has(const std::string & url) { return emp::Has(image_id_map, url); }
103 
105  Ptr<ImageInfo> Add(const std::string & url) {
106  emp_assert(Has(url) == false);
107  size_t img_id = image_info.size();
108  Ptr<ImageInfo> new_info = NewPtr<ImageInfo>(url);
109  image_info.push_back(new_info);
110  image_id_map[url] = img_id;
111  return image_info[img_id];
112  }
113 
115  Ptr<ImageInfo> GetInfo(const std::string & url) {
116  if (Has(url)) return image_info[ image_id_map[url] ];
117  return Add(url);
118  }
119  };
120 
121  } // End internal namespace
122 
124  class RawImage {
125  private:
127 
128  static internal::ImageManager & GetManager() {
129  static internal::ImageManager manager;
130  return manager;
131  }
132  public:
133  RawImage(const std::string & url) : info(GetManager().GetInfo(url)) { ; }
134  RawImage(const RawImage &) = default;
135  ~RawImage() { ; }
136 
137  RawImage & operator=(const RawImage &) = default;
138 
139  int GetID() const { return info->img_id; }
140  const std::string & GetURL() const { return info->url; }
141  bool HasLoaded() const { return info->has_loaded; }
142  bool HasError() const { return info->has_error; }
143 
145  void OnLoad(const std::function<void()> & callback_fun) {
146  if (HasLoaded()) callback_fun();
147  else info->on_load.AddAction(callback_fun);
148  }
149 
151  void OnError(const std::function<void()> & callback_fun) {
152  if (HasError()) callback_fun();
153  else info->on_error.AddAction(callback_fun);
154  }
155  };
156 
157 }
158 
159 #endif
Signal< void()> on_load
Actions for when image is finished loading.
Definition: RawImage.h:35
int GetID() const
Definition: RawImage.h:139
bool has_error
Were there any errors in loading image?
Definition: RawImage.h:34
void OnError(const std::function< void()> &callback_fun)
Add a new function to be called if an image load has an error.
Definition: RawImage.h:85
Definition: RawImage.h:90
Signal< void()> on_error
Actions for when image has trouble loading.
Definition: RawImage.h:36
bool Has(const std::string &url)
Is an image with the provided name currently being managed?
Definition: RawImage.h:102
Ptr< ImageInfo > Add(const std::string &url)
Create a new image with the provided name.
Definition: RawImage.h:105
void OnLoad(const std::function< void()> &callback_fun)
Add a new function to be called when the image finishes loading.
Definition: RawImage.h:80
~RawImage()
Definition: RawImage.h:135
void MarkError()
Trigger this image as having an error.
Definition: RawImage.h:72
void push_back(PB_Ts &&...args)
Definition: vector.h:189
ImageInfo(const std::string &_url)
Definition: RawImage.h:38
bool HasLoaded() const
Definition: RawImage.h:141
size_t size() const
Definition: vector.h:151
bool has_loaded
Is this image finished loading?
Definition: RawImage.h:33
Specialized, useful function for Empirical.
RawImage(const std::string &url)
Definition: RawImage.h:133
bool HasError() const
Definition: RawImage.h:142
void MarkLoaded()
Trigger this image as loaded.
Definition: RawImage.h:65
bool Has(const MAP_T &in_map, const KEY_T &key)
Take any map type, and run find to determine if a key is present.
Definition: map_utils.h:21
ImageManager()
Definition: RawImage.h:96
std::string url
Full URL of file containing image.
Definition: RawImage.h:32
void Alert(const std::string &msg)
Definition: alert.h:29
Wrap a C++ function and convert it to an integer that can be called from Javascript.
If we are in emscripten, make sure to include the header.
Definition: array.h:37
Definition: Ptr.h:711
Build a debug wrapper emp::vector around std::vector.
Definition: vector.h:42
Detailed information about an image.
Definition: RawImage.h:30
#define emp_assert(...)
Definition: assert.h:199
Fundamental information about a single image.
Definition: RawImage.h:124
void OnError(const std::function< void()> &callback_fun)
Add a new function to be called if an image load has an error.
Definition: RawImage.h:151
const std::string & GetURL() const
Definition: RawImage.h:140
Ptr< ImageInfo > GetInfo(const std::string &url)
Get the info about a specified image (loading it only if needed!)
Definition: RawImage.h:115
void OnLoad(const std::function< void()> &callback_fun)
Add a new function to be called when the image finishes loading.
Definition: RawImage.h:145
~ImageManager()
Definition: RawImage.h:97
int img_id
Unique ID for this image.
Definition: RawImage.h:31