@@ -15,13 +15,10 @@ namespace PokemonAutomation{
1515
1616
1717void VideoOverlaySession::add_listener (ContentListener& listener){
18- WriteSpinLock lg (m_lock);
19- m_content_listeners.insert (&listener);
18+ m_listeners.add (listener);
2019}
2120void VideoOverlaySession::remove_listener (ContentListener& listener){
22- WriteSpinLock lg (m_lock);
23- // listener.on_overlay_update_stats(nullptr);
24- m_content_listeners.erase (&listener);
21+ m_listeners.remove (listener);
2522}
2623
2724
@@ -53,7 +50,6 @@ void VideoOverlaySession::get(VideoOverlayOption& option){
5350 option.stats .store (stats, std::memory_order_relaxed);
5451}
5552void VideoOverlaySession::set (const VideoOverlayOption& option){
56- WriteSpinLock lg (m_lock, " VideoOverlaySession::set_enabled_boxes()" );
5753 bool boxes = option.boxes .load (std::memory_order_relaxed);
5854 bool text = option.text .load (std::memory_order_relaxed);
5955 bool images = option.images .load (std::memory_order_relaxed);
@@ -64,13 +60,11 @@ void VideoOverlaySession::set(const VideoOverlayOption& option){
6460 m_option.images .store (images, std::memory_order_relaxed);
6561 m_option.log .store (log, std::memory_order_relaxed);
6662 m_option.stats .store (stats, std::memory_order_relaxed);
67- for (ContentListener* listener : m_content_listeners){
68- listener->on_overlay_enabled_boxes (boxes);
69- listener->on_overlay_enabled_text (text);
70- listener->on_overlay_enabled_images (images);
71- listener->on_overlay_enabled_log (log);
72- listener->on_overlay_enabled_stats (stats);
73- }
63+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_boxes, boxes);
64+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_text, text);
65+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_images, images);
66+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_log, log);
67+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_stats, stats);
7468}
7569
7670
@@ -95,38 +89,23 @@ void VideoOverlaySession::stats_thread(){
9589
9690void VideoOverlaySession::set_enabled_boxes (bool enabled){
9791 m_option.boxes .store (enabled, std::memory_order_relaxed);
98- ReadSpinLock lg (m_lock, " VideoOverlaySession::set_enabled_boxes()" );
99- for (ContentListener* listener : m_content_listeners){
100- listener->on_overlay_enabled_boxes (enabled);
101- }
92+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_boxes, enabled);
10293}
10394void VideoOverlaySession::set_enabled_text (bool enabled){
10495 m_option.text .store (enabled, std::memory_order_relaxed);
105- ReadSpinLock lg (m_lock, " VideoOverlaySession::set_enabled_text()" );
106- for (ContentListener* listener : m_content_listeners){
107- listener->on_overlay_enabled_text (enabled);
108- }
96+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_text, enabled);
10997}
11098void VideoOverlaySession::set_enabled_images (bool enabled){
11199 m_option.images .store (enabled, std::memory_order_relaxed);
112- ReadSpinLock lg (m_lock, " VideoOverlaySession::set_enabled_images()" );
113- for (ContentListener* listener : m_content_listeners){
114- listener->on_overlay_enabled_images (enabled);
115- }
100+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_images, enabled);
116101}
117102void VideoOverlaySession::set_enabled_log (bool enabled){
118103 m_option.log .store (enabled, std::memory_order_relaxed);
119- ReadSpinLock lg (m_lock, " VideoOverlaySession::set_enabled_log()" );
120- for (ContentListener* listener : m_content_listeners){
121- listener->on_overlay_enabled_log (enabled);
122- }
104+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_log, enabled);
123105}
124106void VideoOverlaySession::set_enabled_stats (bool enabled){
125107 m_option.stats .store (enabled, std::memory_order_relaxed);
126- ReadSpinLock lg (m_lock, " VideoOverlaySession::set_enabled_stats()" );
127- for (ContentListener* listener : m_content_listeners){
128- listener->on_overlay_enabled_stats (enabled);
129- }
108+ m_listeners.run_method_unique (&ContentListener::on_overlay_enabled_stats, enabled);
130109}
131110
132111
@@ -135,30 +114,32 @@ void VideoOverlaySession::set_enabled_stats(bool enabled){
135114//
136115
137116void VideoOverlaySession::add_box (const OverlayBox& box){
138- WriteSpinLock lg (m_lock, " VideoOverlaySession::add_box()" );
139- m_boxes.insert (&box);
140- push_box_update ();
141- }
142- void VideoOverlaySession::remove_box (const OverlayBox& box){
143- WriteSpinLock lg (m_lock, " VideoOverlaySession::remove_box()" );
144- m_boxes.erase (&box);
145- push_box_update ();
146- }
117+ std::shared_ptr<std::vector<OverlayBox>> ptr = std::make_shared<std::vector<OverlayBox>>();
118+ {
119+ WriteSpinLock lg (m_lock, " VideoOverlaySession::add_box()" );
120+ m_boxes.insert (&box);
147121
148- void VideoOverlaySession::push_box_update (){
149- if (m_content_listeners.empty ()){
150- return ;
122+ // We create a newly allocated Box vector to avoid listener accessing
123+ // `m_boxes` asynchronously.
124+ for (const auto & item : m_boxes){
125+ ptr->emplace_back (*item);
126+ }
151127 }
152-
153- // We create a newly allocated Box vector to avoid listener accessing
154- // `m_boxes` asynchronously.
128+ m_listeners. run_method_unique (&ContentListener::on_overlay_update_boxes, ptr);
129+ }
130+ void VideoOverlaySession::remove_box ( const OverlayBox& box){
155131 std::shared_ptr<std::vector<OverlayBox>> ptr = std::make_shared<std::vector<OverlayBox>>();
156- for (const auto & item : m_boxes){
157- ptr->emplace_back (*item);
158- }
159- for (ContentListener* listener : m_content_listeners){
160- listener->on_overlay_update_boxes (ptr);
132+ {
133+ WriteSpinLock lg (m_lock, " VideoOverlaySession::remove_box()" );
134+ m_boxes.erase (&box);
135+
136+ // We create a newly allocated Box vector to avoid listener accessing
137+ // `m_boxes` asynchronously.
138+ for (const auto & item : m_boxes){
139+ ptr->emplace_back (*item);
140+ }
161141 }
142+ m_listeners.run_method_unique (&ContentListener::on_overlay_update_boxes, ptr);
162143}
163144std::vector<OverlayBox> VideoOverlaySession::boxes () const {
164145 ReadSpinLock lg (m_lock);
@@ -175,30 +156,32 @@ std::vector<OverlayBox> VideoOverlaySession::boxes() const{
175156//
176157
177158void VideoOverlaySession::add_text (const OverlayText& text){
178- WriteSpinLock lg (m_lock, " VideoOverlaySession::add_text()" );
179- m_texts.insert (&text);
180- push_text_update ();
181- }
182- void VideoOverlaySession::remove_text (const OverlayText& text){
183- WriteSpinLock lg (m_lock, " VideoOverlaySession::remove_text()" );
184- m_texts.erase (&text);
185- push_text_update ();
186- }
159+ std::shared_ptr<std::vector<OverlayText>> ptr = std::make_shared<std::vector<OverlayText>>();
160+ {
161+ WriteSpinLock lg (m_lock, " VideoOverlaySession::add_text()" );
162+ m_texts.insert (&text);
187163
188- void VideoOverlaySession::push_text_update (){
189- if (m_content_listeners.empty ()){
190- return ;
164+ // We create a newly allocated Box vector to avoid listener accessing
165+ // `m_texts` asynchronously.
166+ for (const auto & item : m_texts){
167+ ptr->emplace_back (*item);
168+ }
191169 }
192-
193- // We create a newly allocated Box vector to avoid listener accessing
194- // `m_texts` asynchronously.
170+ m_listeners. run_method_unique (&ContentListener::on_overlay_update_text, ptr);
171+ }
172+ void VideoOverlaySession::remove_text ( const OverlayText& text){
195173 std::shared_ptr<std::vector<OverlayText>> ptr = std::make_shared<std::vector<OverlayText>>();
196- for (const auto & item : m_texts){
197- ptr->emplace_back (*item);
198- }
199- for (ContentListener* listener : m_content_listeners){
200- listener->on_overlay_update_text (ptr);
174+ {
175+ WriteSpinLock lg (m_lock, " VideoOverlaySession::remove_text()" );
176+ m_texts.erase (&text);
177+
178+ // We create a newly allocated Box vector to avoid listener accessing
179+ // `m_texts` asynchronously.
180+ for (const auto & item : m_texts){
181+ ptr->emplace_back (*item);
182+ }
201183 }
184+ m_listeners.run_method_unique (&ContentListener::on_overlay_update_text, ptr);
202185}
203186std::vector<OverlayText> VideoOverlaySession::texts () const {
204187 ReadSpinLock lg (m_lock);
@@ -215,30 +198,32 @@ std::vector<OverlayText> VideoOverlaySession::texts() const{
215198//
216199
217200void VideoOverlaySession::add_image (const OverlayImage& image){
218- WriteSpinLock lg (m_lock, " VideoOverlaySession::add_image()" );
219- m_images.insert (&image);
220- push_image_update ();
221- }
222- void VideoOverlaySession::remove_image (const OverlayImage& image){
223- WriteSpinLock lg (m_lock, " VideoOverlaySession::remove_image()" );
224- m_images.erase (&image);
225- push_image_update ();
226- }
201+ std::shared_ptr<std::vector<OverlayImage>> ptr = std::make_shared<std::vector<OverlayImage>>();
202+ {
203+ WriteSpinLock lg (m_lock, " VideoOverlaySession::add_image()" );
204+ m_images.insert (&image);
227205
228- void VideoOverlaySession::push_image_update (){
229- if (m_content_listeners.empty ()){
230- return ;
206+ // We create a newly allocated Box vector to avoid listener accessing
207+ // `m_images` asynchronously.
208+ for (const auto & item : m_images){
209+ ptr->emplace_back (*item);
210+ }
231211 }
232-
233- // We create a newly allocated Box vector to avoid listener accessing
234- // `m_images` asynchronously.
212+ m_listeners. run_method_unique (&ContentListener::on_overlay_update_images, ptr);
213+ }
214+ void VideoOverlaySession::remove_image ( const OverlayImage& image){
235215 std::shared_ptr<std::vector<OverlayImage>> ptr = std::make_shared<std::vector<OverlayImage>>();
236- for (const auto & item : m_images){
237- ptr->emplace_back (*item);
238- }
239- for (ContentListener* listener : m_content_listeners){
240- listener->on_overlay_update_images (ptr);
216+ {
217+ WriteSpinLock lg (m_lock, " VideoOverlaySession::remove_image()" );
218+ m_images.erase (&image);
219+
220+ // We create a newly allocated Box vector to avoid listener accessing
221+ // `m_images` asynchronously.
222+ for (const auto & item : m_images){
223+ ptr->emplace_back (*item);
224+ }
241225 }
226+ m_listeners.run_method_unique (&ContentListener::on_overlay_update_images, ptr);
242227}
243228std::vector<OverlayImage> VideoOverlaySession::images () const {
244229 ReadSpinLock lg (m_lock);
@@ -255,35 +240,36 @@ std::vector<OverlayImage> VideoOverlaySession::images() const{
255240//
256241
257242void VideoOverlaySession::add_log (std::string message, Color color){
258- WriteSpinLock lg (m_lock, " VideoOverlaySession::add_log_text()" );
259- m_log_texts.emplace_front (color, std::move (message));
243+ std::shared_ptr<std::vector<OverlayLogLine>> ptr = std::make_shared<std::vector<OverlayLogLine>>();
244+ {
245+ WriteSpinLock lg (m_lock, " VideoOverlaySession::add_log_text()" );
246+ m_log_texts.emplace_front (color, std::move (message));
260247
261- if (m_log_texts.size () > LOG_MAX_LINES){
262- m_log_texts.pop_back ();
263- }
248+ if (m_log_texts.size () > LOG_MAX_LINES){
249+ m_log_texts.pop_back ();
250+ }
264251
265- push_log_text_update ();
252+ // We create a newly allocated Box vector to avoid listener accessing
253+ // `m_log_texts` asynchronously.
254+ for (const auto & item : m_log_texts){
255+ ptr->emplace_back (item);
256+ }
257+ }
258+ m_listeners.run_method_unique (&ContentListener::on_overlay_update_log, ptr);
266259}
267260void VideoOverlaySession::clear_log (){
268- WriteSpinLock lg (m_lock, " VideoOverlaySession::clear_log_texts()" );
269- m_log_texts.clear ();
270- push_log_text_update ();
271- }
272-
273- void VideoOverlaySession::push_log_text_update (){
274- if (m_content_listeners.empty ()){
275- return ;
276- }
277-
278- // We create a newly allocated Box vector to avoid listener accessing
279- // `m_log_texts` asynchronously.
280261 std::shared_ptr<std::vector<OverlayLogLine>> ptr = std::make_shared<std::vector<OverlayLogLine>>();
281- for (const auto & item : m_log_texts){
282- ptr->emplace_back (item);
283- }
284- for (ContentListener* listener : m_content_listeners){
285- listener->on_overlay_update_log (ptr);
262+ {
263+ WriteSpinLock lg (m_lock, " VideoOverlaySession::clear_log_texts()" );
264+ m_log_texts.clear ();
265+
266+ // We create a newly allocated Box vector to avoid listener accessing
267+ // `m_log_texts` asynchronously.
268+ for (const auto & item : m_log_texts){
269+ ptr->emplace_back (item);
270+ }
286271 }
272+ m_listeners.run_method_unique (&ContentListener::on_overlay_update_log, ptr);
287273}
288274std::vector<OverlayLogLine> VideoOverlaySession::log_texts () const {
289275 ReadSpinLock lg (m_lock);
0 commit comments