Second iteration of callbacks
authorKlaus Kämpf <kkaempf@suse.de>
Sun, 7 Nov 2010 14:51:54 +0000 (15:51 +0100)
committerKlaus Kämpf <kkaempf@suse.de>
Sun, 7 Nov 2010 14:51:54 +0000 (15:51 +0100)
Define CommitCallbacks class with a connect() and disconnect() to a
callbacks receiver instance.
Add (passing) Ruby and (nonpassing) Python testcase.

swig/Callbacks.i
swig/CommitCallbacks.h
swig/python/tests/CMakeLists.txt
swig/python/tests/commit_callbacks.py [new file with mode: 0644]
swig/ruby/tests/commit_callbacks.rb [new file with mode: 0644]
swig/zypp.i

index 016fdc4..fec4335 100644 (file)
 struct PatchMessageReportReceiver : public zypp::callback::ReceiveReport<zypp::target::PatchMessageReport>
 {
 
-  private:
-    Target_Type _instance;
-  public:
-  PatchMessageReportReceiver(Target_Type instance) { _instance = instance; }
+  Target_Type instance;
+
   /** Display \c patch->message().
    * Return \c true to continue, \c false to abort commit.
    */
@@ -45,10 +43,7 @@ struct PatchMessageReportReceiver : public zypp::callback::ReceiveReport<zypp::t
 struct PatchScriptReportReceiver : public zypp::callback::ReceiveReport<zypp::target::PatchScriptReport>
 {
 
-  private:
-    Target_Type _instance;
-  public:
-  PatchScriptReportReceiver(Target_Type instance) { _instance = instance; }
+  Target_Type instance;
 
   virtual void start( const zypp::Package::constPtr & package,
                      const zypp::Pathname & path_r ) // script path
@@ -86,16 +81,13 @@ struct PatchScriptReportReceiver : public zypp::callback::ReceiveReport<zypp::ta
 struct RemoveResolvableReportReceiver : public zypp::callback::ReceiveReport<zypp::target::rpm::RemoveResolvableReport>
 {
 
-  private:
-    Target_Type _instance;
-  public:
-  RemoveResolvableReportReceiver(Target_Type instance) { _instance = instance; }
+  Target_Type instance;
 
   virtual void start( zypp::Resolvable::constPtr resolvable )
   {
     Target_Type r = SWIG_NewPointerObj((void *)&(*resolvable), SWIGTYPE_p_zypp__Resolvable, 0);
 #if defined(SWIGPYTHON)
-    PyObject *pyfunc = PyObject_GetAttrString(_instance, "removal_start"); 
+    PyObject *pyfunc = PyObject_GetAttrString(instance, "removal_start"); 
     PyObject *prv = NULL;
 
     if (pyfunc == NULL)
@@ -122,12 +114,7 @@ cleanup:
 #endif
 
 #if defined(SWIGRUBY)
-#if SWIG_VERSION < 0x010340
-#define COMMIT_CLASS cTransport
-#else
-#define COMMIT_CLASS SwigClassTransport
-#endif
-    VALUE result = rb_funcall( _instance, rb_intern("removal_start" ), 1, r );
+    VALUE result = rb_funcall( instance, rb_intern("removal_start" ), 1, r );
 #endif
  
     return;
@@ -157,10 +144,7 @@ cleanup:
 struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zypp::target::rpm::InstallResolvableReport>
 {
 
-  private:
-    Target_Type _instance;
-  public:
-  InstallResolvableReportReceiver(Target_Type instance) { _instance = instance; }
+  Target_Type instance;
 
   void display_step( zypp::Resolvable::constPtr resolvable, int value )
   {
index e02cb73..ac8b935 100644 (file)
@@ -5,17 +5,12 @@ class CommitCallbacks {
     PatchScriptReportReceiver _scriptReceiver;
     RemoveResolvableReportReceiver _installReceiver;
     InstallResolvableReportReceiver _removeReceiver;
-
     Target_Type _instance;
+
   public:
-    CommitCallbacks(Target_Type instance)
-      : _messageReceiver(instance)
-      , _scriptReceiver(instance)
-      , _installReceiver(instance)
-      , _removeReceiver(instance)
+    CommitCallbacks()
+     : _instance(Target_Null)
     {
-      _instance = instance;
-      Target_INCREF(_instance);
       _messageReceiver.connect();
       _scriptReceiver.connect();
       _installReceiver.connect();
@@ -28,6 +23,43 @@ class CommitCallbacks {
       _installReceiver.disconnect();
       _scriptReceiver.disconnect();
       _messageReceiver.disconnect();
-      Target_DECREF(_instance);
+      disconnect();
+    }
+   /*
+    * Connect callback to receiver instance
+    * Pass NULL receiver to disconnect
+    * 
+    */
+    void connect(Target_Type instance) {
+      disconnect();
+      if (instance) {
+       _instance = instance;
+       Target_INCREF(_instance);
+       _messageReceiver.instance = _instance;
+       _scriptReceiver.instance = _instance;
+       _installReceiver.instance = _instance;
+       _removeReceiver.instance = _instance;
+      }
+    }
+    /*
+     * Disconnect receiver instance
+     * 
+     */
+    void disconnect() {
+      if (_instance != Target_Null) {
+       _messageReceiver.instance = Target_Null;
+       _scriptReceiver.instance = Target_Null;
+       _installReceiver.instance = Target_Null;
+       _removeReceiver.instance = Target_Null;
+       Target_DECREF(_instance);
+        _instance = Target_Null;
+      }
+    }
+    /*
+     * Get current receiver instance
+     * 
+     */
+    Target_Type receiver() {
+      return _instance;
     }
 };
index 70eb6df..8424cc0 100644 (file)
@@ -1,4 +1,4 @@
-#
+##
 # CMakeLists.txt for libzypp-bindings/swig/python/tests
 #
 
@@ -6,3 +6,4 @@ ENABLE_TESTING()
 
 ADD_TEST(bindings_python_loading     python ${CMAKE_CURRENT_SOURCE_DIR}/loading.py)
 ADD_TEST(bindings_python_repoinfo    python ${CMAKE_CURRENT_SOURCE_DIR}/repoinfo.py)
+ADD_TEST(bindings_python_commit_callbacks  python ${CMAKE_CURRENT_SOURCE_DIR}/commit_callbacks.py)
\ No newline at end of file
diff --git a/swig/python/tests/commit_callbacks.py b/swig/python/tests/commit_callbacks.py
new file mode 100644 (file)
index 0000000..61c9315
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# Test commit callbacks
+#
+
+import unittest
+
+import sys
+sys.path.insert(0, '../../../../build/swig/python')
+
+from zypp import CommitCallbacks
+
+class CommitReceiver:
+  def removal_start(self, resolvable):
+    print "Starting to remove ", resolvable
+
+class CommitCallbacksTestCase(unittest.TestCase):
+    def testRemoveCallback(self):
+        commit_callbacks = CommitCallbacks()
+        assert None == commit_callbacks.receiver()
+        commit_receiver = CommitReceiver()
+        commit_callbacks.connect(commit_receiver)
+        assert commit_receiver == commit_callbacks.receiver()
+        commit_callbacks.disconnect()
+        assert None == commit_callbacks.receiver()
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/swig/ruby/tests/commit_callbacks.rb b/swig/ruby/tests/commit_callbacks.rb
new file mode 100644 (file)
index 0000000..1dbd408
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# Test commit callbacks
+#
+
+$:.unshift "../../../build/swig/ruby"
+
+
+require 'test/unit'
+require 'zypp'
+
+class CommitReceiver
+  # Define class function, we pass the class (not an instance of the class)
+  # to the CommitCallbacks
+  def self.removal_start resolvable
+    $stderr.puts "Starting to remove #{resolvable}"
+  end
+end
+
+class CommitCallbacksTest < Test::Unit::TestCase
+  def test_removal_callback
+    commit_callbacks = Zypp::CommitCallbacks.new
+    assert_equal nil, commit_callbacks.receiver
+    # In Ruby the class is also an object, so we connect to the class
+    commit_callbacks.connect CommitReceiver
+    assert_equal CommitReceiver, commit_callbacks.receiver
+    commit_callbacks.disconnect
+    assert_equal nil, commit_callbacks.receiver
+  end
+end
index 7dd31e6..a9323d3 100644 (file)
@@ -143,6 +143,16 @@ typedef std::list<std::string> StringList;
 
 %nodefault ByKind;
 
+#if defined(SWIGRUBY)
+#define Target_Type VALUE
+#endif
+#if defined(SWIGPYTHON)
+#define Target_Type PyObject*
+#endif
+#if defined(SWIGPERL)
+#define Target_Type SV *
+#endif
+
 %rename("+") "operator+";
 %rename("<<") "operator<<";
 %rename("!=") "operator!=";