diff options
author | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2017-06-19 21:26:59 -0300 |
---|---|---|
committer | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2017-06-19 21:26:59 -0300 |
commit | 8f95d71f0deb00e35f7d965c8e17694c42bc197a (patch) | |
tree | 497cfd0b93151be96f6d2a939ec28781c671b289 | |
parent | c6660adea2551d6a585bab264dc9d405f52b935c (diff) | |
download | efl-8f95d71f0deb00e35f7d965c8e17694c42bc197a.tar.gz |
mono: Support error handling on events
If an exception occurs in a managed callback, the exception is caught
and the error reported to the stderr throught eina.Log.Error. An eina
error is set to be raised when the code comes back to the managed side.
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/klass.hh | 18 | ||||
-rw-r--r-- | src/tests/efl_mono/Errors.cs | 21 |
2 files changed, 35 insertions, 4 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index 42fa18f699..89fbf6c568 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -479,7 +479,7 @@ struct klass return true; if (!as_generator(scope_tab << "private readonly object eventLock = new object();\n" - << scope_tab << "Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n") + << scope_tab << "private Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n") .generate(sink, NULL, context)) return false; @@ -496,6 +496,7 @@ struct klass << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Failed to add event proxy for event ${key}\");\n" << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" << scope_tab << scope_tab << scope_tab << "}\n" + << scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOcurred();\n" << scope_tab << scope_tab << "} \n" << scope_tab << scope_tab << "event_cb_count[key]++;\n" << scope_tab << scope_tab << "return true;\n" @@ -511,6 +512,7 @@ struct klass << scope_tab << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Failed to remove event proxy for event ${key}\");\n" << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" << scope_tab << scope_tab << scope_tab << "}\n" + << scope_tab << scope_tab << scope_tab << "eina.Error.RaiseIfOcurred();\n" << scope_tab << scope_tab << "} else if (event_count == 0) {\n" << scope_tab << scope_tab << scope_tab << "eina.Log.Error(\"Trying to remove proxy for event ${key} when there is nothing registered.\");\n" << scope_tab << scope_tab << scope_tab << "return false;\n" @@ -562,7 +564,12 @@ struct klass << scope_tab << "public void on_" << event_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)\n" << scope_tab << "{\n" << scope_tab << event_args - << scope_tab << scope_tab << "On_" << event_name << "(args);\n" + << scope_tab << scope_tab << "try {\n" + << scope_tab << scope_tab << scope_tab << "On_" << event_name << "(args);\n" + << scope_tab << scope_tab << "} catch (Exception e) {\n" + << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.Message);\n" + << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n" + << scope_tab << scope_tab << "}\n" << scope_tab << "}\n" << scope_tab << "efl.Event_Cb evt_" << event_name << "_delegate;\n" << scope_tab << "event EventHandler" << wrapper_args_template << " " << cls.cxx_name << "." << upper_name << "{\n") @@ -644,7 +651,12 @@ struct klass << scope_tab << "protected void on_" << wrapper_evt_name << "_NativeCallback(System.IntPtr data, ref efl.Event evt)" << scope_tab << "{\n" << scope_tab << event_args - << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n" + << scope_tab << scope_tab << "try {\n" + << scope_tab << scope_tab << scope_tab << "On_" << wrapper_evt_name << "(args);\n" + << scope_tab << scope_tab << "} catch (Exception e) {\n" + << scope_tab << scope_tab << scope_tab << "eina.Log.Error(e.Message);\n" + << scope_tab << scope_tab << scope_tab << "eina.Error.Set(eina.Error.EFL_ERROR);\n" + << scope_tab << scope_tab << "}\n" << scope_tab << "}\n" << scope_tab << "event EventHandler" << wrapper_args_template << " " << *(lower_case[string] << ".") << klass.cxx_name << ".") .generate(sink, escape_namespace(klass.namespaces), context)) diff --git a/src/tests/efl_mono/Errors.cs b/src/tests/efl_mono/Errors.cs index 042e4ae0e4..c8c05a7afa 100644 --- a/src/tests/efl_mono/Errors.cs +++ b/src/tests/efl_mono/Errors.cs @@ -94,6 +94,25 @@ class TestEolianError } // events - // virtual callbacks + class Listener + { + public bool called = false; + public void callback(object sender, EventArgs e) { + throw (new CustomException("Event exception")); + } + public void another_callback(object sender, EventArgs e) {} + } + + public static void eina_error_event_raise_exception() + { + // An event whose managed delegate generates an exception + // must set an eina_error so it can be reported back to + // the managed code + efl.Loop loop = new efl.LoopConcrete(); + Listener listener = new Listener(); + loop.CALLBACK_ADD += listener.callback; + + Test.AssertRaises<efl.EflException>(() => loop.IDLE += listener.another_callback); + } } } |