summaryrefslogtreecommitdiff
path: root/src/bin/eolian_mono/eolian/mono/klass.hh
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-04-05 19:59:34 -0300
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-04-05 19:59:47 -0300
commit7c28762f15f9935d5ca08ef87ee7ddfaf1df4815 (patch)
tree3b602d7fb867e91c202f262b7aaa215c8245856b /src/bin/eolian_mono/eolian/mono/klass.hh
parent1c22a3d8190fd85570418a076356547f3eda606f (diff)
efl-csharp: fix crash when events trigger after C# object `Dispose`
Summary: Rework general event handling to check individually each event call, if the object is not alive then the event will not be propagated. WeakReferences (and lambdas capturing those WeakRefs) are used to ensure this. Dispose methods in object now take care of checking if efl libraries are still initialized and thread-safely unregister each event before performing an efl_unref on the Eo object. Event handling in C# is now centered around a single dictionary inside the object: `EoEvents`. C# event triggers now properly trigger events on C too. Standardize C# event-triggering methods names (remove underscores). Some diminished use of static memory due events no longer requiring static key objects to be registered/unregistered. Some fixing of white space generation for generated events. Depends on D8431 Reviewers: lauromoura, felipealmeida, segfaultxavi Reviewed By: lauromoura Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8564
Diffstat (limited to 'src/bin/eolian_mono/eolian/mono/klass.hh')
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh215
1 files changed, 90 insertions, 125 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index 7973c7d..e34a126 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -223,7 +223,6 @@ struct klass
223 << scope_tab << "private " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n" 223 << scope_tab << "private " << concrete_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
224 << scope_tab << "{\n" 224 << scope_tab << "{\n"
225 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "") 225 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
226 << scope_tab << scope_tab << "RegisterEventProxies();\n"
227 << scope_tab << "}\n" 226 << scope_tab << "}\n"
228 ) 227 )
229 .generate(sink, attributes::unused, concrete_cxt)) 228 .generate(sink, attributes::unused, concrete_cxt))
@@ -238,9 +237,6 @@ struct klass
238 if (!generate_events(sink, cls, concrete_cxt)) 237 if (!generate_events(sink, cls, concrete_cxt))
239 return false; 238 return false;
240 239
241 if (!generate_events_registration(sink, cls, concrete_cxt))
242 return false;
243
244 // Parts 240 // Parts
245 if(!as_generator(*(part_definition)) 241 if(!as_generator(*(part_definition))
246 .generate(sink, cls.parts, concrete_cxt)) return false; 242 .generate(sink, cls.parts, concrete_cxt)) return false;
@@ -316,9 +312,6 @@ struct klass
316 if (!generate_events(sink, cls, inherit_cxt)) 312 if (!generate_events(sink, cls, inherit_cxt))
317 return false; 313 return false;
318 314
319 if (!generate_events_registration(sink, cls, inherit_cxt))
320 return false;
321
322 // Parts 315 // Parts
323 if(!as_generator(*(part_definition)) 316 if(!as_generator(*(part_definition))
324 .generate(sink, cls.parts, inherit_cxt)) return false; 317 .generate(sink, cls.parts, inherit_cxt)) return false;
@@ -459,7 +452,9 @@ struct klass
459 return true; 452 return true;
460 453
461 if (cls.get_all_events().size() > 0) 454 if (cls.get_all_events().size() > 0)
462 if (!as_generator(scope_tab << (is_inherit ? "protected " : "private ") << "EventHandlerList eventHandlers = new EventHandlerList();\n").generate(sink, attributes::unused, context)) 455 if (!as_generator(scope_tab << visibility << "Dictionary<(IntPtr desc, object evtDelegate), (IntPtr evtCallerPtr, Efl.EventCb evtCaller)> eoEvents = new Dictionary<(IntPtr desc, object evtDelegate), (IntPtr evtCallerPtr, Efl.EventCb evtCaller)>();\n"
456 << scope_tab << visibility << "readonly object eventLock = new object();\n")
457 .generate(sink, attributes::unused, context))
463 return false; 458 return false;
464 459
465 if (is_inherit) 460 if (is_inherit)
@@ -517,7 +512,6 @@ struct klass
517 << scope_tab << "protected " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n" 512 << scope_tab << "protected " << inherit_name << "(System.IntPtr raw)" << (root ? "" : " : base(raw)") << "\n"
518 << scope_tab << "{\n" 513 << scope_tab << "{\n"
519 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "") 514 << scope_tab << scope_tab << (root ? "handle = raw;\n" : "")
520 << scope_tab << scope_tab << "RegisterEventProxies();\n"
521 << scope_tab << "}\n" 515 << scope_tab << "}\n"
522 ).generate(sink, std::make_tuple(constructors, constructors, constructors), context)) 516 ).generate(sink, std::make_tuple(constructors, constructors, constructors), context))
523 return false; 517 return false;
@@ -560,7 +554,6 @@ struct klass
560 << scope_tab << scope_tab << scope_tab << "actual_klass = Efl.Eo.ClassRegister.GetInheritKlassOrRegister(base_klass, ((object)this).GetType());\n" 554 << scope_tab << scope_tab << scope_tab << "actual_klass = Efl.Eo.ClassRegister.GetInheritKlassOrRegister(base_klass, ((object)this).GetType());\n"
561 << scope_tab << scope_tab << "}\n" 555 << scope_tab << scope_tab << "}\n"
562 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n" 556 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_start(actual_klass, parent);\n"
563 << scope_tab << scope_tab << "RegisterEventProxies();\n"
564 << scope_tab << scope_tab << "if (inherited)\n" 557 << scope_tab << scope_tab << "if (inherited)\n"
565 << scope_tab << scope_tab << "{\n" 558 << scope_tab << scope_tab << "{\n"
566 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.PrivateDataSet(this);\n" 559 << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.PrivateDataSet(this);\n"
@@ -580,7 +573,6 @@ struct klass
580 template <typename OutputIterator, typename Context> 573 template <typename OutputIterator, typename Context>
581 bool generate_dispose_methods(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const 574 bool generate_dispose_methods(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
582 { 575 {
583 std::string name = join_namespaces(cls.namespaces, '.') + cls.eolian_name;
584 if (helpers::has_regular_ancestor(cls)) 576 if (helpers::has_regular_ancestor(cls))
585 return true; 577 return true;
586 578
@@ -588,93 +580,65 @@ struct klass
588 580
589 auto inherit_name = name_helpers::klass_concrete_name(cls); 581 auto inherit_name = name_helpers::klass_concrete_name(cls);
590 582
583 std::string events_gchandle;
584 if (cls.get_all_events().size() > 0)
585 {
586 auto events_gchandle_sink = std::back_inserter(events_gchandle);
587 if (!as_generator(scope_tab << scope_tab << scope_tab << "if (eoEvents.Count != 0)\n"
588 << scope_tab << scope_tab << scope_tab << "{\n"
589 << scope_tab << scope_tab << scope_tab << scope_tab << "GCHandle gcHandle = GCHandle.Alloc(eoEvents);\n"
590 << scope_tab << scope_tab << scope_tab << scope_tab << "gcHandlePtr = GCHandle.ToIntPtr(gcHandle);\n"
591 << scope_tab << scope_tab << scope_tab << "}\n\n")
592 .generate(events_gchandle_sink, attributes::unused, context))
593 return false;
594 }
595
591 return as_generator( 596 return as_generator(
592 597
593 scope_tab << "///<summary>Destructor.</summary>\n" 598 scope_tab << "///<summary>Destructor.</summary>\n"
594 << scope_tab << "~" << inherit_name << "()\n" 599 << scope_tab << "~" << inherit_name << "()\n"
595 << scope_tab << "{\n" 600 << scope_tab << "{\n"
596 << scope_tab << scope_tab << "Dispose(false);\n" 601 << scope_tab << scope_tab << "Dispose(false);\n"
597 << scope_tab << "}\n" 602 << scope_tab << "}\n\n"
598 603
599 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n" 604 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
600 << scope_tab << visibility << "void Dispose(bool disposing)\n" 605 << scope_tab << visibility << "void Dispose(bool disposing)\n"
601 << scope_tab << "{\n" 606 << scope_tab << "{\n"
602 << scope_tab << scope_tab << "if (handle != System.IntPtr.Zero) {\n" 607 << scope_tab << scope_tab << "if (handle != System.IntPtr.Zero)\n"
608 << scope_tab << scope_tab << "{\n"
609 << scope_tab << scope_tab << scope_tab << "IntPtr h = handle;\n"
610 << scope_tab << scope_tab << scope_tab << "handle = IntPtr.Zero;\n\n"
611
612 << scope_tab << scope_tab << scope_tab << "IntPtr gcHandlePtr = IntPtr.Zero;\n"
613 << events_gchandle
614
603 << scope_tab << scope_tab << scope_tab << "if (disposing)\n" 615 << scope_tab << scope_tab << scope_tab << "if (disposing)\n"
604 << scope_tab << scope_tab << scope_tab << "{\n" 616 << scope_tab << scope_tab << scope_tab << "{\n"
605 << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_unref(handle);\n" 617 << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_mono_native_dispose(h, gcHandlePtr);\n"
606 << scope_tab << scope_tab << scope_tab << "}\n" 618 << scope_tab << scope_tab << scope_tab << "}\n"
607 << scope_tab << scope_tab << scope_tab << "else\n" 619 << scope_tab << scope_tab << scope_tab << "else\n"
608 << scope_tab << scope_tab << scope_tab << "{\n" 620 << scope_tab << scope_tab << scope_tab << "{\n"
609 << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_mono_thread_safe_efl_unref(handle);\n" 621
622 << scope_tab << scope_tab << scope_tab << scope_tab << "Monitor.Enter(Efl.Eo.Config.InitLock);\n"
623 << scope_tab << scope_tab << scope_tab << scope_tab << "if (Efl.Eo.Config.Initialized)\n"
624 << scope_tab << scope_tab << scope_tab << scope_tab << "{\n"
625 << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.efl_mono_thread_safe_native_dispose(h, gcHandlePtr);\n"
626 << scope_tab << scope_tab << scope_tab << scope_tab << "}\n\n"
627 << scope_tab << scope_tab << scope_tab << scope_tab << "Monitor.Exit(Efl.Eo.Config.InitLock);\n"
610 << scope_tab << scope_tab << scope_tab << "}\n" 628 << scope_tab << scope_tab << scope_tab << "}\n"
611 << scope_tab << scope_tab << scope_tab << "handle = System.IntPtr.Zero;\n"
612 << scope_tab << scope_tab << "}\n" 629 << scope_tab << scope_tab << "}\n"
613 << scope_tab << "}\n" 630 << scope_tab << "}\n\n"
614 631
615 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n" 632 << scope_tab << "///<summary>Releases the underlying native instance.</summary>\n"
616 << scope_tab << "public void Dispose()\n" 633 << scope_tab << "public void Dispose()\n"
617 << scope_tab << "{\n" 634 << scope_tab << "{\n"
618 << scope_tab << scope_tab << "Dispose(true);\n" 635 << scope_tab << scope_tab << "Dispose(true);\n"
619 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n" 636 << scope_tab << scope_tab << "GC.SuppressFinalize(this);\n"
620 << scope_tab << "}\n" 637 << scope_tab << "}\n\n"
621 ).generate(sink, attributes::unused, context); 638 ).generate(sink, attributes::unused, context);
622 } 639 }
623 640
624 template <typename OutputIterator, typename Context> 641 template <typename OutputIterator, typename Context>
625 bool generate_events_registration(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
626 {
627 bool root = !helpers::has_regular_ancestor(cls);
628 std::string virtual_modifier = " ";
629
630 if (!root)
631 virtual_modifier = "override ";
632 else
633 {
634 if (is_inherit_context(context))
635 virtual_modifier = "virtual ";
636 }
637
638 // Event proxy registration
639 if (!as_generator(
640 scope_tab << "///<summary>Register the Eo event wrappers making the bridge to C# events. Internal usage only.</summary>\n"
641 << scope_tab << (is_inherit_context(context) || !root ? "protected " : "") << virtual_modifier << "void RegisterEventProxies()\n"
642 << scope_tab << "{\n"
643 )
644 .generate(sink, NULL, context))
645 return false;
646
647 // Generate event registrations here
648
649 if (!root)
650 if (!as_generator(scope_tab << scope_tab << "base.RegisterEventProxies();\n").generate(sink, NULL, context))
651 return false;
652
653 // Assigning the delegates
654 if (!as_generator(*(event_registration(cls, cls))).generate(sink, cls.events, context))
655 return false;
656
657 for (auto&& c : helpers::non_implemented_interfaces(cls, context))
658 {
659 // Only non-regular types (which declare events through interfaces) need to register them.
660 if (c.type == attributes::class_type::regular)
661 continue;
662
663 attributes::klass_def klass(get_klass(c, cls.unit), cls.unit);
664
665 if (!as_generator(*(event_registration(klass, cls))).generate(sink, klass.events, context))
666 return false;
667 }
668
669 if (!as_generator(
670 scope_tab << "}\n"
671 ).generate(sink, NULL, context))
672 return false;
673
674 return true;
675 }
676
677 template <typename OutputIterator, typename Context>
678 bool generate_events(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const 642 bool generate_events(OutputIterator sink, attributes::klass_def const& cls, Context const& context) const
679 { 643 {
680 644
@@ -685,69 +649,70 @@ struct klass
685 649
686 if (!helpers::has_regular_ancestor(cls)) 650 if (!helpers::has_regular_ancestor(cls))
687 { 651 {
688 if (!as_generator(scope_tab << visibility << "readonly object eventLock = new object();\n"
689 << scope_tab << visibility << "Dictionary<string, int> event_cb_count = new Dictionary<string, int>();\n")
690 .generate(sink, NULL, context))
691 return false;
692
693 // Callback registration functions 652 // Callback registration functions
694 if (!as_generator( 653 if (!as_generator(
695 scope_tab << "///<summary>Adds a new event handler, registering it to the native event. For internal use only.</summary>\n" 654 scope_tab << "///<summary>Adds a new event handler, registering it to the native event. For internal use only.</summary>\n"
696 << scope_tab << "///<param name=\"lib\">The name of the native library definining the event.</param>\n" 655 << scope_tab << "///<param name=\"lib\">The name of the native library definining the event.</param>\n"
697 << scope_tab << "///<param name=\"key\">The name of the native event.</param>\n" 656 << scope_tab << "///<param name=\"key\">The name of the native event.</param>\n"
698 << scope_tab << "///<param name=\"evt_delegate\">The delegate to be called on event raising.</param>\n" 657 << scope_tab << "///<param name=\"evtCaller\">Delegate to be called by native code on event raising.</param>\n"
699 << scope_tab << "///<returns>True if the delegate was successfully registered.</returns>\n" 658 << scope_tab << "///<param name=\"evtDelegate\">Managed delegate that will be called by evtCaller on event raising.</param>\n"
700 << scope_tab << visibility << "bool AddNativeEventHandler(string lib, string key, Efl.EventCb evt_delegate) {\n" 659 << scope_tab << visibility << "void AddNativeEventHandler(string lib, string key, Efl.EventCb evtCaller, object evtDelegate)\n"
701 << scope_tab << scope_tab << "int event_count = 0;\n" 660 << scope_tab << "{\n"
702 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n" 661
703 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n" 662 << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(lib, key);\n"
704 << scope_tab << scope_tab << "if (event_count == 0) {\n" 663 << scope_tab << scope_tab << "if (desc == IntPtr.Zero)\n"
705 664 << scope_tab << scope_tab << "{\n"
706 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(lib, key);\n" 665 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
707 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n" 666 << scope_tab << scope_tab << "}\n\n"
708 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n" 667
709 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 668 << scope_tab << scope_tab << "if (eoEvents.ContainsKey((desc, evtDelegate)))\n"
710 << scope_tab << scope_tab << scope_tab << "}\n" 669 << scope_tab << scope_tab << "{\n"
711 670 << scope_tab << scope_tab << scope_tab << "Eina.Log.Warning($\"Event proxy for event {key} already registered!\");\n"
712 << scope_tab << scope_tab << scope_tab << " bool result = Efl.Eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evt_delegate, System.IntPtr.Zero);\n" 671 << scope_tab << scope_tab << scope_tab << "return;\n"
713 << scope_tab << scope_tab << scope_tab << "if (!result) {\n" 672 << scope_tab << scope_tab << "}\n\n"
714 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to add event proxy for event {key}\");\n" 673
715 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 674 << scope_tab << scope_tab << "IntPtr evtCallerPtr = Marshal.GetFunctionPointerForDelegate(evtCaller);\n"
716 << scope_tab << scope_tab << scope_tab << "}\n" 675 << scope_tab << scope_tab << "if (!Efl.Eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evtCallerPtr, IntPtr.Zero))\n"
717 << scope_tab << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n" 676 << scope_tab << scope_tab << "{\n"
718 << scope_tab << scope_tab << "} \n" 677 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to add event proxy for event {key}\");\n"
719 << scope_tab << scope_tab << "event_cb_count[key]++;\n" 678 << scope_tab << scope_tab << scope_tab << "return;\n"
720 << scope_tab << scope_tab << "return true;\n" 679 << scope_tab << scope_tab << "}\n\n"
721 << scope_tab << "}\n" 680
681 << scope_tab << scope_tab << "eoEvents[(desc, evtDelegate)] = (evtCallerPtr, evtCaller);\n"
682 << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
683 << scope_tab << "}\n\n"
684
722 << scope_tab << "///<summary>Removes the given event handler for the given event. For internal use only.</summary>\n" 685 << scope_tab << "///<summary>Removes the given event handler for the given event. For internal use only.</summary>\n"
686 << scope_tab << "///<param name=\"lib\">The name of the native library definining the event.</param>\n"
723 << scope_tab << "///<param name=\"key\">The name of the native event.</param>\n" 687 << scope_tab << "///<param name=\"key\">The name of the native event.</param>\n"
724 << scope_tab << "///<param name=\"evt_delegate\">The delegate to be removed.</param>\n" 688 << scope_tab << "///<param name=\"evtDelegate\">The delegate to be removed.</param>\n"
725 << scope_tab << "///<returns>True if the delegate was successfully registered.</returns>\n" 689 << scope_tab << visibility << "void RemoveNativeEventHandler(string lib, string key, object evtDelegate)\n"
726 << scope_tab << visibility << "bool RemoveNativeEventHandler(string key, Efl.EventCb evt_delegate) {\n" 690 << scope_tab << "{\n"
727 << scope_tab << scope_tab << "int event_count = 0;\n" 691
728 << scope_tab << scope_tab << "if (!event_cb_count.TryGetValue(key, out event_count))\n" 692 << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(lib, key);\n"
729 << scope_tab << scope_tab << scope_tab << "event_cb_count[key] = event_count;\n" 693 << scope_tab << scope_tab << "if (desc == IntPtr.Zero)\n"
730 << scope_tab << scope_tab << "if (event_count == 1) {\n" 694 << scope_tab << scope_tab << "{\n"
731 695 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n"
732 << scope_tab << scope_tab << scope_tab << "IntPtr desc = Efl.EventDescription.GetNative(" 696 << scope_tab << scope_tab << scope_tab << "return;\n"
733 << context_find_tag<library_context>(context).actual_library_name(cls.filename) << ", key);\n" 697 << scope_tab << scope_tab << "}\n\n"
734 << scope_tab << scope_tab << scope_tab << "if (desc == IntPtr.Zero) {\n" 698
735 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to get native event {key}\");\n" 699 << scope_tab << scope_tab << "var evtPair = (desc, evtDelegate);\n"
736 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 700 << scope_tab << scope_tab << "if (eoEvents.TryGetValue(evtPair, out var caller))\n"
737 << scope_tab << scope_tab << scope_tab << "}\n" 701 << scope_tab << scope_tab << "{\n"
738 702
739 << scope_tab << scope_tab << scope_tab << "bool result = Efl.Eo.Globals.efl_event_callback_del(handle, desc, evt_delegate, System.IntPtr.Zero);\n" 703 << scope_tab << scope_tab << scope_tab << "if (!Efl.Eo.Globals.efl_event_callback_del(handle, desc, caller.evtCallerPtr, IntPtr.Zero))\n"
740 << scope_tab << scope_tab << scope_tab << "if (!result) {\n" 704 << scope_tab << scope_tab << scope_tab << "{\n"
741 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to remove event proxy for event {key}\");\n" 705 << scope_tab << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Failed to remove event proxy for event {key}\");\n"
742 << scope_tab << scope_tab << scope_tab << scope_tab << "return false;\n" 706 << scope_tab << scope_tab << scope_tab << scope_tab << "return;\n"
743 << scope_tab << scope_tab << scope_tab << "}\n" 707 << scope_tab << scope_tab << scope_tab << "}\n\n"
708
709 << scope_tab << scope_tab << scope_tab << "eoEvents.Remove(evtPair);\n"
744 << scope_tab << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n" 710 << scope_tab << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
745 << scope_tab << scope_tab << "} else if (event_count == 0) {\n" 711 << scope_tab << scope_tab << "}\n"
746 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Trying to remove proxy for event {key} when there is nothing registered.\");\n" 712 << scope_tab << scope_tab << "else\n"
747 << scope_tab << scope_tab << scope_tab << "return false;\n" 713 << scope_tab << scope_tab << "{\n"
748 << scope_tab << scope_tab << "} \n" 714 << scope_tab << scope_tab << scope_tab << "Eina.Log.Error($\"Trying to remove proxy for event {key} when it is nothing registered.\");\n"
749 << scope_tab << scope_tab << "event_cb_count[key]--;\n" 715 << scope_tab << scope_tab << "}\n"
750 << scope_tab << scope_tab << "return true;\n"
751 << scope_tab << "}\n" 716 << scope_tab << "}\n"
752 ) 717 )
753 .generate(sink, NULL, context)) 718 .generate(sink, NULL, context))