Shaka Player Embedded
event_target.h
Go to the documentation of this file.
1 // Copyright 2016 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SHAKA_EMBEDDED_JS_EVENTS_EVENT_TARGET_H_
16 #define SHAKA_EMBEDDED_JS_EVENTS_EVENT_TARGET_H_
17 
18 #include <list>
19 #include <memory>
20 #include <string>
21 #include <unordered_map>
22 #include <utility>
23 
24 #include "shaka/optional.h"
26 #include "src/core/member.h"
27 #include "src/core/ref_ptr.h"
28 #include "src/debug/thread_event.h"
29 #include "src/js/events/event.h"
33 #include "src/mapping/callback.h"
35 
36 namespace shaka {
37 namespace js {
38 namespace events {
39 
40 class EventTarget : public BackingObject {
41  DECLARE_TYPE_INFO(EventTarget);
42 
43  public:
44  EventTarget();
45 
47 
48  void Trace(memory::HeapTracer* tracer) const override;
49 
55  void AddEventListener(const std::string& type, Listener callback);
56 
63  void SetCppEventListener(EventType type, std::function<void()> callback);
64 
70  void RemoveEventListener(const std::string& type, Listener callback);
71 
76  void UnsetCppEventListener(EventType type);
77 
87  return DispatchEventInternal(event, nullptr);
88  }
89 
98  bool* did_listeners_throw);
99 
107  template <typename EventType, typename... Args>
108  std::shared_ptr<ThreadEvent<bool>> ScheduleEvent(Args&&... args) {
109  RefPtr<EventType> event = new EventType(std::forward<Args>(args)...);
110  RefPtr<EventTarget> target(this);
112  TaskPriority::Events, std::string("Schedule ") + EventType::name(),
113  [=]() {
114  ExceptionOr<bool> val = target->DispatchEvent(event);
115  if (holds_alternative<bool>(val)) {
116  return get<bool>(val);
117  } else {
118  LocalVar<JsValue> except = get<js::JsError>(val).error();
119  LOG(INFO) << "Exception thrown while raising event: "
120  << ConvertToString(except);
121  return false;
122  }
123  });
124  }
125 
130  template <typename EventType, typename... Args>
132  RefPtr<EventType> backing = new EventType(args...);
133  return this->DispatchEvent(backing);
134  }
135 
136  protected:
138  void AddListenerField(EventType type, Listener* on_field) {
139  on_listeners_[to_string(type)] = on_field;
140  }
141 
142  private:
143  struct ListenerInfo {
144  ListenerInfo(Listener listener, const std::string& type);
145  ~ListenerInfo();
146 
147  Listener callback_;
148  std::string type_;
149  bool should_remove_;
150  };
151 
153  void InvokeListeners(RefPtr<Event> event, bool* did_listeners_throw);
154 
156  std::list<ListenerInfo>::iterator FindListener(const Listener& callback,
157  const std::string& type);
158 
159  std::unordered_map<std::string, std::function<void()>> cpp_listeners_;
160 
161  // Elements are stored in insert order. Use a list since we store an iterator
162  // while invoking and it needs to remain valid with concurrent inserts. This
163  // will also have faster removals since we only use iterators.
164  std::list<ListenerInfo> listeners_;
165  // A map of the on-event listeners (e.g. onerror).
166  std::unordered_map<std::string, Listener*> on_listeners_;
167  bool is_dispatching_;
168 };
169 
170 class EventTargetFactory : public BackingObjectFactory<EventTarget> {
171  public:
173 };
174 
175 } // namespace events
176 } // namespace js
177 } // namespace shaka
178 
179 #endif // SHAKA_EMBEDDED_JS_EVENTS_EVENT_TARGET_H_
ExceptionOr< bool > DispatchEventInternal(RefPtr< Event > event, bool *did_listeners_throw)
Definition: event_target.cc:68
const char * name
std::string to_string(VideoReadyState state)
Definition: media_player.cc:32
ExceptionCode type
ExceptionOr< bool > RaiseEvent(Args... args)
Definition: event_target.h:131
void RemoveEventListener(const std::string &type, Listener callback)
Definition: event_target.cc:52
void UnsetCppEventListener(EventType type)
Definition: event_target.cc:64
void Trace(memory::HeapTracer *tracer) const override
Definition: event_target.cc:31
std::shared_ptr< ThreadEvent< impl::RetOf< Func > > > AddInternalTask(TaskPriority priority, const std::string &name, Func &&callback)
Definition: task_runner.h:219
ExceptionOr< bool > DispatchEvent(RefPtr< Event > event)
Definition: event_target.h:86
void AddEventListener(const std::string &type, Listener callback)
Definition: event_target.cc:41
std::string ConvertToString(Handle< JsValue > value)
Definition: js_wrappers.cc:203
void SetCppEventListener(EventType type, std::function< void()> callback)
Definition: event_target.cc:47
std::shared_ptr< ThreadEvent< bool > > ScheduleEvent(Args &&... args)
Definition: event_target.h:108
void AddListenerField(EventType type, Listener *on_field)
Definition: event_target.h:138
TaskRunner * MainThread()