Modify event notification from broadcast to subscribe model 81/11481/4
authorKazumasa Mitsunari <knimitz@witz-inc.co.jp>
Mon, 23 Oct 2017 09:26:46 +0000 (18:26 +0900)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Wed, 1 Nov 2017 11:02:10 +0000 (11:02 +0000)
The event notification was implemented using a broadcast model,
change it to a subscription model.

Bug-AGL: SPEC-987

Change-Id: I344a3a73320eb81c3f670736b032f07400bb8f64
Signed-off-by: Kazumasa Mitsunari <knimitz@witz-inc.co.jp>
generate-binding-glue.py
src/app.cpp
src/app.hpp
src/main.cpp

index dbebbcd..376350a 100644 (file)
@@ -30,22 +30,41 @@ def p(*args):
 
 def emit_func_impl(api, f):
     args = f.get('args', [])
-    if len(args) > 0:
-        p('   json_object *jreq = afb_req_json(req);', '')
-        for arg in args:
-            arg['jtype'] = arg.get('jtype', arg['type']) # add jtype default
-            p('   json_object *j_%(name)s = nullptr;' % arg,
-              '   if (! json_object_object_get_ex(jreq, "%(name)s", &j_%(name)s)) {' % arg,
-              '      afb_req_fail(req, "failed", "Need %(type)s argument %(name)s");' % arg,
-              '      return;',
-              '   }',
-              '   %(type)s a_%(name)s = json_object_get_%(jtype)s(j_%(name)s);' % arg, '')
-    p('   auto ret = %(api)s' % api + '%(name)s(' % f + ', '.join(map(lambda x: 'a_' + x['name'], args)) + ');')
-    p('   if (ret.is_err()) {',
-      '      afb_req_fail(req, "failed", ret.unwrap_err());',
-      '      return;',
-      '   }', '')
-    p('   afb_req_success(req, ret.unwrap(), "success");')
+    func_name = f.get('name', [])
+    if "wm_subscribe" == func_name:
+        p('   json_object *jreq = afb_req_json(req);')
+        p('   json_object *j = nullptr;')
+        p('   if (! json_object_object_get_ex(jreq, "event", &j)) {')
+        p('      afb_req_fail(req, "failed", "Need char const* argument event");')
+        p('      return;')
+        p('   }')
+        p('   int event_type = json_object_get_int(j);')
+        p('   const char *event_name = g_afb_instance->app.kListEventName[event_type];')
+        p('   struct afb_event event = g_afb_instance->app.map_afb_event[event_name];')
+        p('   int ret = afb_req_subscribe(req, event);')
+        p('   if (ret) {',
+          '      afb_req_fail(req, "failed", "Error: afb_req_subscribe()");',
+          '      return;',
+          '   }')
+        p('   afb_req_success(req, NULL, "success");')
+
+    else:
+        if len(args) > 0:
+            p('   json_object *jreq = afb_req_json(req);', '')
+            for arg in args:
+                arg['jtype'] = arg.get('jtype', arg['type']) # add jtype default
+                p('   json_object *j_%(name)s = nullptr;' % arg,
+                  '   if (! json_object_object_get_ex(jreq, "%(name)s", &j_%(name)s)) {' % arg,
+                  '      afb_req_fail(req, "failed", "Need %(type)s argument %(name)s");' % arg,
+                  '      return;',
+                  '   }',
+                  '   %(type)s a_%(name)s = json_object_get_%(jtype)s(j_%(name)s);' % arg, '')
+        p('   auto ret = %(api)s' % api + '%(name)s(' % f + ', '.join(map(lambda x: 'a_' + x['name'], args)) + ');')
+        p('   if (ret.is_err()) {',
+          '      afb_req_fail(req, "failed", ret.unwrap_err());',
+          '      return;',
+          '   }', '')
+        p('   afb_req_success(req, ret.unwrap(), "success");')
 
 def emit_func(api, f):
     p('void %(impl_name)s(afb_req req) noexcept {' % f)
@@ -132,6 +151,8 @@ API = {
                     { 'name': 'drawing_name', 'type': 'char const*', 'jtype': 'string' },
                 ],
             },
+            { 'name': 'wm_subscribe', },
+
             { 'name': 'list_drawing_names', },
             { 'name': 'ping' },
 
index f38668f..f4dbba6 100644 (file)
@@ -105,6 +105,11 @@ int App::init() {
       return -1;
    }
 
+   // Make afb event
+   for (int i=Event_Val_Min; i<=Event_Val_Max; i++) {
+      map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i]);
+   }
+
    this->display->add_global_handler(
       "wl_output", [this](wl_registry *r, uint32_t name, uint32_t v) {
          this->outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
@@ -118,8 +123,7 @@ int App::init() {
          // Init controller hooks
          this->controller->chooks = &this->chooks;
 
-         // XXX: This protocol needs the output, so lets just add our mapping
-         // here...
+         // This protocol needs the output, so lets just add our mapping here...
          this->controller->add_proxy_to_id_mapping(
             this->outputs.back()->proxy.get(),
             wl_proxy_get_id(reinterpret_cast<struct wl_proxy *>(
@@ -575,23 +579,23 @@ void App::surface_removed(uint32_t surface_id) {
 }
 
 void App::emit_activated(char const *label) {
-   this->api.send_event("active", label);
+   this->api.send_event(kListEventName[Event_Active], label);
 }
 
 void App::emit_deactivated(char const *label) {
-   this->api.send_event("inactive", label);
+   this->api.send_event(kListEventName[Event_Inactive], label);
 }
 
 void App::emit_syncdraw(char const *label, char const *area) {
-   this->api.send_event("syncdraw", label, area);
+    this->api.send_event(kListEventName[Event_SyncDraw], label, area);
 }
 
 void App::emit_flushdraw(char const *label) {
-   this->api.send_event("flushdraw", label);
+   this->api.send_event(kListEventName[Event_FlushDraw], label);
 }
 
 void App::emit_visible(char const *label, bool is_visible) {
-   this->api.send_event(is_visible ? "visible" : "invisible", label);
+   this->api.send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label);
 }
 
 void App::emit_invisible(char const *label) {
@@ -603,7 +607,7 @@ void App::emit_visible(char const *label) { return emit_visible(label, true); }
 result<int> App::api_request_surface(char const *drawing_name) {
    auto lid = this->layers.get_layer_id(std::string(drawing_name));
    if (!lid) {
-      // XXX: to we need to put these applications on the App layer?
+      // TODO: Do we need to put these applications on the App layer?
       return Err<int>("Drawing name does not match any role");
    }
 
@@ -613,8 +617,7 @@ result<int> App::api_request_surface(char const *drawing_name) {
       auto id = int(this->id_alloc.generate_id(drawing_name));
       this->layers.add_surface(id, *lid);
 
-      // XXX: we set the main_surface[_name] here and now,
-      // not sure if we want this, but it worked so far.
+      // set the main_surface[_name] here and now
       if (!this->layers.main_surface_name.empty() &&
           this->layers.main_surface_name == drawing_name) {
          this->layers.main_surface = id;
index ea3e92b..9f8b7ce 100644 (file)
@@ -93,7 +93,6 @@ struct id_allocator {
    }
 
    // Remove a surface id and name
-   // I don't think I will need this, do I?
    void remove_id(std::string const &name) {
       auto i = this->name2id.find(name);
       if (i != this->name2id.end()) {
@@ -112,6 +111,30 @@ struct id_allocator {
 };
 
 struct App {
+   enum EventType {
+      Event_Val_Min = 0,
+
+      Event_Active = Event_Val_Min,
+      Event_Inactive,
+
+      Event_Visible,
+      Event_Invisible,
+
+      Event_SyncDraw,
+      Event_FlushDraw,
+
+      Event_Val_Max = Event_FlushDraw,
+   };
+
+   const std::vector<const char *> kListEventName{
+     "active",
+     "inactive",
+     "visible",
+     "invisible",
+     "syncdraw",
+     "flushdraw"
+   };
+
    struct binding_api api;
    struct controller_hooks chooks;
 
@@ -136,6 +159,8 @@ struct App {
 
    Policy policy;
 
+   std::map<const char *, struct afb_event> map_afb_event;
+
    explicit App(wl::display *d);
    ~App() = default;
 
@@ -155,6 +180,7 @@ struct App {
    char const *api_activate_surface(char const *drawing_name, char const *drawing_area);
    char const *api_deactivate_surface(char const *drawing_name);
    char const *api_enddraw(char const *drawing_name);
+   char const *api_subscribe(afb_req *req, char const *event_name);
    void api_ping();
 
    // Events from the compositor we are interested in
index f33b20e..c90eeb1 100755 (executable)
@@ -167,22 +167,22 @@ void binding_api::send_event(char const *evname, char const *label) {
    json_object *j = json_object_new_object();
    json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
 
-   int ret = afb_daemon_broadcast_event(evname, j);
+   int ret = afb_event_push(g_afb_instance->app.map_afb_event[evname], j);
    if (ret != 0) {
-      logdebug("afb_event_broadcast failed: %m");
+      logdebug("afb_event_push failed: %m");
    }
 }
 
 void binding_api::send_event(char const *evname, char const *label, char const *area) {
-  logdebug("%s: %s(%s, %s)", __func__, evname, label, area);
+   logdebug("%s: %s(%s, %s)", __func__, evname, label, area);
 
    json_object *j = json_object_new_object();
    json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
    json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area));
 
-   int ret = afb_daemon_broadcast_event(evname, j);
+   int ret = afb_event_push(g_afb_instance->app.map_afb_event[evname], j);
    if (ret != 0) {
-      logdebug("afb_event_broadcast failed: %m");
+      logdebug("afb_event_push failed: %m");
    }
 }
 } // namespace wm