[ekiga/ds-opal-refactoring] Opal: Reengineered engine around the new DynamicObjects.



commit bc61d7a68c286afd1f5ffd30ee1135864f9a2073
Author: Damien Sandras <dsandras seconix com>
Date:   Tue Mar 31 18:13:02 2015 +0200

    Opal: Reengineered engine around the new DynamicObjects.
    
    The Opal::Call creation and destruction is now handled by the engine and
    boost instead of Opal itself. We have no leaks anymore.

 lib/engine/components/opal/opal-call.cpp           |   29 +++++++-------
 .../components/opal/process/opal-endpoint.cpp      |   40 +++++++++++++++-----
 lib/engine/components/opal/process/opal-endpoint.h |    3 +-
 lib/engine/protocol/call-core.cpp                  |   33 +++++++++-------
 lib/engine/protocol/call-core.h                    |   10 ++--
 lib/engine/protocol/call.h                         |   37 ++++++++----------
 6 files changed, 85 insertions(+), 67 deletions(-)
---
diff --git a/lib/engine/components/opal/opal-call.cpp b/lib/engine/components/opal/opal-call.cpp
index 0770bb2..4c93f7b 100644
--- a/lib/engine/components/opal/opal-call.cpp
+++ b/lib/engine/components/opal/opal-call.cpp
@@ -101,7 +101,6 @@ Opal::Call::Call (Opal::EndPoint& _manager,
     call_setup(false), outgoing(false)
 {
   NoAnswerTimer.SetNotifier (PCREATE_NOTIFIER (OnNoAnswerTimeout));
-  NoAnswerTimer.SetInterval (0, 5);
 
   add_action (Ekiga::ActionPtr (new Ekiga::Action ("hangup", _("Hangup"),
                                                    boost::bind (&Call::hang_up, this))));
@@ -116,6 +115,9 @@ Opal::Call::Call (Opal::EndPoint& _manager,
 
 Opal::Call::~Call ()
 {
+#if DEBUG
+  std::cout << "Opal::Call: Destructor invoked" << std::endl << std::flush;
+#endif
 }
 
 
@@ -233,9 +235,9 @@ Opal::Call::toggle_stream_pause (StreamType type)
       stream->SetPaused (!paused);
 
       if (paused)
-       Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_resumed), stream_name, type));
+       Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_resumed), get_shared_ptr (), 
stream_name, type));
       else
-       Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_paused), stream_name, type));
+       Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_paused), get_shared_ptr (), stream_name, 
type));
     }
   }
 }
@@ -484,7 +486,7 @@ Opal::Call::OnEstablished (OpalConnection & connection)
     remove_action ("reject");
 
     parse_info (connection);
-    Ekiga::Runtime::run_in_main (boost::ref (established));
+    Ekiga::Runtime::run_in_main (boost::bind (boost::ref (established), get_shared_ptr ()));
   }
 
   if (PIsDescendant(&connection, OpalRTPConnection)) {
@@ -626,11 +628,9 @@ Opal::Call::OnCleared ()
     }
 
     if (IsEstablished () || is_outgoing ())
-      Ekiga::Runtime::run_in_main (boost::bind (boost::ref (cleared), reason));
+      Ekiga::Runtime::run_in_main (boost::bind (boost::ref (cleared), get_shared_ptr (), reason));
     else
-      Ekiga::Runtime::run_in_main (boost::ref (missed));
-
-    Ekiga::Runtime::run_in_main (boost::ref (removed));
+      Ekiga::Runtime::run_in_main (boost::bind (boost::ref (missed), get_shared_ptr ()));
 }
 
 
@@ -661,7 +661,8 @@ Opal::Call::OnSetUp (OpalConnection & connection)
   call_setup = true;
   new CallSetup (*this, connection);
 
-  Ekiga::Runtime::run_in_main (boost::ref (setup));
+  std::cout << "Call SETUP" << std::endl;
+  Ekiga::Runtime::run_in_main (boost::bind (boost::ref (setup), get_shared_ptr ()));
 
   return true;
 }
@@ -671,7 +672,7 @@ PBoolean
 Opal::Call::OnAlerting (OpalConnection & connection)
 {
   if (!PIsDescendant(&connection, OpalPCSSConnection))
-    Ekiga::Runtime::run_in_main (boost::ref (ringing));
+    Ekiga::Runtime::run_in_main (boost::bind (boost::ref (ringing), get_shared_ptr ()));
 
   return OpalCall::OnAlerting (connection);
 }
@@ -683,9 +684,9 @@ Opal::Call::OnHold (OpalConnection & /*connection*/,
                     bool on_hold)
 {
   if (on_hold)
-    Ekiga::Runtime::run_in_main (boost::ref (held));
+    Ekiga::Runtime::run_in_main (boost::bind (boost::ref (held), get_shared_ptr ()));
   else
-    Ekiga::Runtime::run_in_main (boost::ref (retrieved));
+    Ekiga::Runtime::run_in_main (boost::bind (boost::ref (retrieved), get_shared_ptr ()));
 }
 
 
@@ -700,7 +701,7 @@ Opal::Call::OnOpenMediaStream (OpalMediaStream & stream)
   std::transform (stream_name.begin (), stream_name.end (), stream_name.begin (), (int (*) (int)) toupper);
   is_transmitting = !stream.IsSource ();
 
-  Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_opened), stream_name, type, is_transmitting));
+  Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_opened), get_shared_ptr (), stream_name, 
type, is_transmitting));
 
   if (type == Ekiga::Call::Video)
     add_action (Ekiga::ActionPtr (new Ekiga::Action ("transmit-video", _("Transmit Video"),
@@ -719,7 +720,7 @@ Opal::Call::OnClosedMediaStream (OpalMediaStream & stream)
   std::transform (stream_name.begin (), stream_name.end (), stream_name.begin (), (int (*) (int)) toupper);
   is_transmitting = !stream.IsSource ();
 
-  Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_closed), stream_name, type, is_transmitting));
+  Ekiga::Runtime::run_in_main (boost::bind (boost::ref (stream_closed), get_shared_ptr (), stream_name, 
type, is_transmitting));
 }
 
 
diff --git a/lib/engine/components/opal/process/opal-endpoint.cpp 
b/lib/engine/components/opal/process/opal-endpoint.cpp
index 88b38b8..daf696c 100644
--- a/lib/engine/components/opal/process/opal-endpoint.cpp
+++ b/lib/engine/components/opal/process/opal-endpoint.cpp
@@ -547,31 +547,51 @@ void Opal::EndPoint::GetVideoOptions (Opal::EndPoint::VideoOptions & options) co
 
 OpalCall *Opal::EndPoint::CreateCall (void *uri)
 {
-  Opal::Call* call = 0;
+  boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
+  Opal::Call* _call = 0;
 
   if (uri != 0)
-    call = new Opal::Call (*this, (const char *) uri);
+    _call = new Opal::Call (*this, (const char *) uri);
   else
-    call = new Opal::Call (*this, "");
+    _call = new Opal::Call (*this, "");
+
+  /* We want to hold a shared_ptr to the call object
+   * before the call object has a chance to emit any
+   * signal, otherwise shared_from_this might fail.
+   */
+  boost::shared_ptr<Opal::Call> call(_call);
 
-  Ekiga::Runtime::run_in_main (boost::bind (&Opal::EndPoint::OnCreatedCall, this, call));
+  /* We could pass a const reference to the shared_ptr, but then
+   * we would not be sure that the shared_ptr still exist when
+   * Opal returns the _call instance to its internal system.
+   */
+  Ekiga::Runtime::run_in_main (boost::bind (&Ekiga::CallCore::add_call, call_core, call));
 
-  return call;
+  return _call;
 }
 
 
 void
-Opal::EndPoint::DestroyCall (G_GNUC_UNUSED OpalCall *call)
-{
+Opal::EndPoint::DestroyCall (OpalCall *__call)
+{
+  /* This is suboptimal, but we have no other way.
+   *
+   * We remove the object from the collection when Opal decides to do it.
+   *
+   * Once it has been done, if there are no more references, the object can
+   * be destroyed by boost.
+   */
+  Opal::Call *_call = dynamic_cast<Opal::Call *>(__call);
+  boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
+  if (_call)
+    Ekiga::Runtime::run_in_main (boost::bind (static_cast<void 
(Opal::EndPoint::*)(boost::shared_ptr<Ekiga::Call>)>(&Opal::EndPoint::DestroyCall), this, 
_call->get_shared_ptr ()));
 }
 
 
 void
-Opal::EndPoint::OnCreatedCall (Opal::Call *_call)
+Opal::EndPoint::DestroyCall (boost::shared_ptr<Ekiga::Call> call)
 {
-  boost::shared_ptr<Ekiga::CallCore> call_core = core.get<Ekiga::CallCore> ("call-core");
-  boost::shared_ptr<Opal::Call> call(_call);
-  call_core->add_call (call);
+  call->removed (call);
 }
 
 
diff --git a/lib/engine/components/opal/process/opal-endpoint.h 
b/lib/engine/components/opal/process/opal-endpoint.h
index b7a4ee9..d0aa5db 100644
--- a/lib/engine/components/opal/process/opal-endpoint.h
+++ b/lib/engine/components/opal/process/opal-endpoint.h
@@ -143,7 +143,6 @@ public:
     void SetVideoOptions (const VideoOptions & options);
     void GetVideoOptions (VideoOptions & options) const;
 
-    boost::signals2::signal<void(Opal::Call *)> created_call;
     boost::signals2::signal<void(void)> ready;
 
 private:
@@ -151,7 +150,7 @@ private:
 
     void DestroyCall (OpalCall * call);
 
-    void OnCreatedCall (Call *call);
+    void DestroyCall (boost::shared_ptr<Ekiga::Call> call);
 
     void HandleSTUNResult ();
 
diff --git a/lib/engine/protocol/call-core.cpp b/lib/engine/protocol/call-core.cpp
index b47af45..82ccf63 100644
--- a/lib/engine/protocol/call-core.cpp
+++ b/lib/engine/protocol/call-core.cpp
@@ -157,7 +157,7 @@ CallCore::set_codecs (Ekiga::CodecList & codecs)
 }
 
 
-void CallCore::add_call (boost::shared_ptr<Call> call)
+void CallCore::add_call (const boost::shared_ptr<Call> & call)
 {
   Ekiga::FriendOrFoe::Identification id = iff->decide ("call", call->get_remote_uri ());
 
@@ -168,29 +168,32 @@ void CallCore::add_call (boost::shared_ptr<Call> call)
   }
 
   created_call (call);
-
   calls.add_object (call);
-  calls.add_connection (call, call->ringing.connect (boost::bind (boost::ref (ringing_call), call)));
-  calls.add_connection (call, call->setup.connect (boost::bind (boost::ref (setup_call), call)));
-  calls.add_connection (call, call->missed.connect (boost::bind (&CallCore::on_missed_call, this, call)));
-  calls.add_connection (call, call->cleared.connect (boost::bind (boost::ref (cleared_call), call, _1)));
-  calls.add_connection (call, call->established.connect (boost::bind (boost::ref (established_call), call)));
-  calls.add_connection (call, call->held.connect (boost::bind (boost::ref (held_call), call)));
-  calls.add_connection (call, call->retrieved.connect (boost::bind (boost::ref (retrieved_call), call)));
-  calls.add_connection (call, call->stream_opened.connect (boost::bind (boost::ref (stream_opened), call, 
_1, _2, _3)));
-  calls.add_connection (call, call->stream_closed.connect (boost::bind (boost::ref (stream_closed), call, 
_1, _2, _3)));
-  calls.add_connection (call, call->stream_paused.connect (boost::bind (boost::ref (stream_paused), call, 
_1, _2)));
-  calls.add_connection (call, call->stream_resumed.connect (boost::bind (boost::ref (stream_resumed), call, 
_1, _2)));
+
+  // Relay signals
+  calls.add_connection (call, call->ringing.connect (boost::bind (boost::ref (ringing_call), _1)));
+  calls.add_connection (call, call->setup.connect (boost::bind (boost::ref (setup_call), _1)));
+  calls.add_connection (call, call->missed.connect (boost::bind (&CallCore::on_missed_call, this, _1)));
+  calls.add_connection (call, call->cleared.connect (boost::bind (boost::ref (cleared_call), _1, _2)));
+  calls.add_connection (call, call->established.connect (boost::bind (boost::ref (established_call), _1)));
+  calls.add_connection (call, call->held.connect (boost::bind (boost::ref (held_call), _1)));
+  calls.add_connection (call, call->retrieved.connect (boost::bind (boost::ref (retrieved_call), _1)));
+  calls.add_connection (call, call->stream_opened.connect (boost::bind (boost::ref (stream_opened), _1, _2, 
_3, _4)));
+  calls.add_connection (call, call->stream_closed.connect (boost::bind (boost::ref (stream_closed), _1, _2, 
_3, _4)));
+  calls.add_connection (call, call->stream_paused.connect (boost::bind (boost::ref (stream_paused), _1, _2, 
_3)));
+  calls.add_connection (call, call->stream_resumed.connect (boost::bind (boost::ref (stream_resumed), _1, 
_2, _3)));
+  calls.add_connection (call, call->removed.connect (boost::bind (&CallCore::remove_call, this, _1)));
 }
 
 
-void CallCore::remove_call (boost::shared_ptr<Call> call)
+void CallCore::remove_call (const boost::shared_ptr<Call> & call)
 {
   calls.remove_object (call);
+  call_removed (call);
 }
 
 
-void CallCore::on_missed_call (boost::shared_ptr<Call> call)
+void CallCore::on_missed_call (const boost::shared_ptr<Call> & call)
 {
   boost::shared_ptr<Ekiga::NotificationCore> _notification_core = notification_core.lock ();
   if (_notification_core) {
diff --git a/lib/engine/protocol/call-core.h b/lib/engine/protocol/call-core.h
index 4e634d7..ca8f6a0 100644
--- a/lib/engine/protocol/call-core.h
+++ b/lib/engine/protocol/call-core.h
@@ -40,7 +40,7 @@
 #include "chain-of-responsibility.h"
 #include "services.h"
 #include "reflister.h"
-
+#include "dynamic-object-store.h"
 #include "friend-or-foe/friend-or-foe.h"
 #include "call.h"
 #include "call-manager.h"
@@ -102,12 +102,12 @@ namespace Ekiga
       /** Adds a call handled by the CallCore serice.
        * @param call is the call to be added.
        */
-      void add_call (boost::shared_ptr<Call> call);
+      void add_call (const boost::shared_ptr<Call> & call);
 
       /** Remove a call handled by the CallCore serice.
        * @param call is the call to be removed.
        */
-      void remove_call (boost::shared_ptr<Call> call);
+      void remove_call (const boost::shared_ptr<Call> & call);
 
       /** Adds a CallManager to the CallCore service.
        * @param The manager to be added.
@@ -197,12 +197,12 @@ namespace Ekiga
 
   private:
 
-      void on_missed_call (boost::shared_ptr<Call> call);
+      void on_missed_call (const boost::shared_ptr<Call> & call);
 
       boost::shared_ptr<Ekiga::FriendOrFoe> iff;
       boost::weak_ptr<Ekiga::NotificationCore> notification_core;
 
-      RefLister<Ekiga::Call> calls;
+      DynamicObjectStore<Ekiga::Call> calls;
       RefLister<Ekiga::CallManager> managers;
     };
 
diff --git a/lib/engine/protocol/call.h b/lib/engine/protocol/call.h
index a5a32d1..517fa46 100644
--- a/lib/engine/protocol/call.h
+++ b/lib/engine/protocol/call.h
@@ -37,15 +37,14 @@
 #ifndef __CALL_H__
 #define __CALL_H__
 
+#include <boost/smart_ptr.hpp>
 #include <boost/signals2.hpp>
 #include <boost/bind.hpp>
 #include <string>
 
-#include <boost/smart_ptr.hpp>
-
 #include "actor.h"
-#include "live-object.h"
 #include "rtcp-statistics.h"
+#include "dynamic-object.h"
 
 namespace Ekiga
 {
@@ -61,8 +60,8 @@ namespace Ekiga
    */
   class Call
     : public Actor,
-      public virtual LiveObject
-    {
+      public DynamicObject<Call>
+  {
 
   public:
 
@@ -167,69 +166,65 @@ namespace Ekiga
 
       /* Signal emitted when the call is established
        */
-      boost::signals2::signal<void(void)> established;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> established;
 
       /* Signal emitted when an established call is cleared
        * @param: a string describing why the call was cleared
        */
-      boost::signals2::signal<void(std::string)> cleared;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>, std::string)> cleared;
 
       /* Signal emitted when the call is missed, ie cleared
        * without having been established
        */
-      boost::signals2::signal<void(void)> missed;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> missed;
 
       /* Signal emitted when the call is forwarded
        */
-      boost::signals2::signal<void(void)> forwarded;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> forwarded;
 
       /* Signal emitted when the call is held
        */
-      boost::signals2::signal<void(void)> held;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> held;
 
       /* Signal emitted when the call is being setup
        */
-      boost::signals2::signal<void(void)> setup;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> setup;
 
       /* Signal emitted when the call is retrieved
        */
-      boost::signals2::signal<void(void)> retrieved;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> retrieved;
 
       /* Signal emitted when the remote party is ringing
        */
-      boost::signals2::signal<void(void)> ringing;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>)> ringing;
 
       /* Signal emitted when a stream is opened
        * @param the stream name
        * @param the stream type
        * @param transmission or reception
        */
-      boost::signals2::signal<void(std::string, StreamType, bool)> stream_opened;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>, std::string, StreamType, bool)> 
stream_opened;
 
       /* Signal emitted when a stream is closed
        * @param the stream name
        * @param the stream type
        * @param transmission or reception
        */
-      boost::signals2::signal<void(std::string, StreamType, bool)> stream_closed;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>, std::string, StreamType, bool)> 
stream_closed;
 
       /* Signal emitted when a transmitted stream is paused
        * @param the stream name
        * @param the stream type
        * @param transmission or reception
        */
-      boost::signals2::signal<void(std::string, StreamType)> stream_paused;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>, std::string, StreamType)> stream_paused;
 
       /* Signal emitted when a transmitted stream is resumed
        * @param the stream name
        * @param the stream type
        * @param transmission or reception
        */
-      boost::signals2::signal<void(std::string, StreamType)> stream_resumed;
-
-      /** This signal is emitted when the Call is removed.
-       */
-      boost::signals2::signal<void(void)> removed;
+      boost::signals2::signal<void(boost::shared_ptr<Ekiga::Call>, std::string, StreamType)> stream_resumed;
     };
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]