diff --git a/src/net/JNet/Specific/JNetEventResult.cs b/src/net/JNet/Specific/JNetEventResult.cs
index 3c16df534a..1b3e65a773 100644
--- a/src/net/JNet/Specific/JNetEventResult.cs
+++ b/src/net/JNet/Specific/JNetEventResult.cs
@@ -55,7 +55,7 @@ public JNetEventResult(IJVMBridgeBaseInitializer initializer) : base(initializer
///
/// The to be returned to the JVM side
///
- public object ReturnData { get => IExecute("getReturnData"); set => IExecute("setReturnData", value); }
+ public object ReturnData { get => IExecute("getReturnData"); } // disabled since JVM side raise an exception in any case set => IExecute("setReturnData", value); }
///
/// Helper function to set both and
///
diff --git a/src/net/JNetReflector/InternalMethods.cs b/src/net/JNetReflector/InternalMethods.cs
index 4fd1c1b370..4d086d58d4 100644
--- a/src/net/JNetReflector/InternalMethods.cs
+++ b/src/net/JNetReflector/InternalMethods.cs
@@ -2020,6 +2020,7 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas
template = Template.GetTemplate(Template.SingleMethodTemplate);
singleMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.DECORATION, jDecoration.ToString())
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_EXECUTION, listenerHandlerType)
+ .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER, returnType == "void" ? string.Empty : AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER_FORMAT)
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_NAME, baseHandlerName)
.Replace(AllPackageClasses.ClassStub.MethodStub.MODIFIER, modifier)
.Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
@@ -2049,6 +2050,7 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas
template = Template.GetTemplate(Template.SingleMethodTemplate);
singleMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.DECORATION, jDecoration.ToString())
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_EXECUTION, listenerHandlerType)
+ .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER, returnType == "void" ? string.Empty : AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER_FORMAT)
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_NAME, baseHandlerName)
.Replace(AllPackageClasses.ClassStub.MethodStub.MODIFIER, modifier)
.Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
@@ -2078,6 +2080,7 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas
template = Template.GetTemplate(Template.SingleMethodTemplate);
singleMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.DECORATION, jDecoration.ToString())
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_EXECUTION, listenerHandlerType)
+ .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER, returnType == "void" ? string.Empty : AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER_FORMAT)
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_NAME, baseHandlerName)
.Replace(AllPackageClasses.ClassStub.MethodStub.MODIFIER, modifier)
.Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
@@ -2149,6 +2152,7 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas
{
singleMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.DECORATION, jDecoration.ToString())
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_EXECUTION, listenerHandlerType)
+ .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER, returnType == "void" ? string.Empty : AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER_FORMAT)
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_NAME, baseHandlerName)
.Replace(AllPackageClasses.ClassStub.MethodStub.MODIFIER, modifier)
.Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
@@ -2178,6 +2182,7 @@ static string AnalyzeMethods(this Class classDefinition, IEnumerable clas
singleMethod = template.Replace(AllPackageClasses.ClassStub.MethodStub.DECORATION, jDecoration.ToString())
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_EXECUTION, listenerHandlerType)
+ .Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER, returnType == "void" ? string.Empty : AllPackageClasses.ClassStub.MethodStub.LISTENER_DISPOSE_HANDLER_FORMAT)
.Replace(AllPackageClasses.ClassStub.MethodStub.LISTENER_HANDLER_NAME, baseHandlerName)
.Replace(AllPackageClasses.ClassStub.MethodStub.MODIFIER, modifier)
.Replace(AllPackageClasses.ClassStub.MethodStub.RETURNTYPE, returnType)
diff --git a/src/net/JNetReflector/Templates/AllPackageClassesStubClass.template b/src/net/JNetReflector/Templates/AllPackageClassesStubClass.template
index d3bf117fee..2aeccbe894 100644
--- a/src/net/JNetReflector/Templates/AllPackageClassesStubClass.template
+++ b/src/net/JNetReflector/Templates/AllPackageClassesStubClass.template
@@ -3,13 +3,15 @@ ALLPACKAGE_CLASSES_STUB_CLASS_DECORATION_PLACEHOLDER
public partial class ALLPACKAGE_CLASSES_STUB_CLASS_PLACEHOLDER : ALLPACKAGE_CLASSES_STUB_BASECLASS_PLACEHOLDERALLPACKAGE_CLASSES_STUB_WHERECLAUSES_PLACEHOLDER
{
const string _bridgeClassName = "ALLPACKAGE_CLASSES_STUB_JAVACLASS_PLACEHOLDER";
+
///
- /// Internal constructor: used internally from JCOBridge
+ /// Initializer used internally by JCOBridge. Do not use directly.
///
[global::System.Obsolete("This public initializer is needed for JCOBridge internal use, other uses can produce unidentible behaviors.")]
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(IJVMBridgeBaseInitializer initializer) : base(initializer) { }
+
///
- /// Generic constructor: it is useful for JCOBridge when there is a derived class which needs to pass arguments to the highest JVMBridgeBase class
+ /// Generic constructor used by JCOBridge when a derived class needs to forward arguments to the base JVMBridgeBase class.
///
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(params object[] args) : base(args) { }
diff --git a/src/net/JNetReflector/Templates/AllPackageClassesStubClassInterfaceOrAbstract.template b/src/net/JNetReflector/Templates/AllPackageClassesStubClassInterfaceOrAbstract.template
index f54c8b3c5c..edef42659f 100644
--- a/src/net/JNetReflector/Templates/AllPackageClassesStubClassInterfaceOrAbstract.template
+++ b/src/net/JNetReflector/Templates/AllPackageClassesStubClassInterfaceOrAbstract.template
@@ -3,14 +3,20 @@ ALLPACKAGE_CLASSES_STUB_CLASS_DECORATION_PLACEHOLDER
public partial class ALLPACKAGE_CLASSES_STUB_CLASS_PLACEHOLDER : ALLPACKAGE_CLASSES_STUB_BASECLASS_PLACEHOLDERALLPACKAGE_CLASSES_STUB_WHERECLAUSES_PLACEHOLDER
{
const string _bridgeClassName = "ALLPACKAGE_CLASSES_STUB_JAVACLASS_PLACEHOLDER";
+
///
- /// Internal constructor: used internally from JCOBridge
+ /// Initializer used internally by JCOBridge. Do not use directly.
///
[global::System.Obsolete("This public initializer is needed for JCOBridge internal use, other uses can produce unidentible behaviors.")]
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(IJVMBridgeBaseInitializer initializer) : base(initializer) { }
+
///
- /// Generic constructor: it is useful for JCOBridge when there is a derived class which needs to pass arguments to the highest JVMBridgeBase class
+ /// Generic constructor used by JCOBridge when a derived class needs to forward arguments to the base JVMBridgeBase class.
///
+ ///
+ /// represents a JVM interface or abstract class in .NET.
+ /// Instantiating it directly outside of JCOBridge infrastructure is not supported and may produce undefined behavior.
+ ///
[global::System.Obsolete("ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER class represents, in .NET, an instance of a JVM interface or abstract class. This public initializer is needed for JCOBridge internal use, other uses can produce unidentible behaviors.")]
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(params object[] args) : base(args) { }
diff --git a/src/net/JNetReflector/Templates/AllPackageClassesStubClassListener.template b/src/net/JNetReflector/Templates/AllPackageClassesStubClassListener.template
index bdd1843a46..80e7e61e87 100644
--- a/src/net/JNetReflector/Templates/AllPackageClassesStubClassListener.template
+++ b/src/net/JNetReflector/Templates/AllPackageClassesStubClassListener.template
@@ -3,16 +3,17 @@ ALLPACKAGE_CLASSES_STUB_CLASS_DECORATION_PLACEHOLDER
public partial class ALLPACKAGE_CLASSES_STUB_CLASS_PLACEHOLDER : ALLPACKAGE_CLASSES_STUB_BASECLASS_PLACEHOLDER
{
///
- /// Internal constructor: used internally from JCOBridge
+ /// Initializer used internally by JCOBridge. Do not use directly.
///
[global::System.Obsolete("This public initializer is needed for JCOBridge internal use, other uses can produce unidentible behaviors.")]
- public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(IJVMBridgeBaseInitializer initializer) : base(initializer)
+ public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(IJVMBridgeBaseInitializer initializer) : base(initializer)
{
- var listenerRuntimeType = GetType();
+ var listenerRuntimeType = GetType();
_hasALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDERSecondGate = MASES.JNet.Specific.JNetEventResult.GetMethodIsOverridden(listenerRuntimeType, nameof(ListenerShallManageEvent), typeof(int), typeof(object));
}
+
///
- /// Generic constructor: it is useful for JCOBridge when there is a derived class which needs to pass arguments to the highest JVMBridgeBase class
+ /// Generic constructor used by JCOBridge when a derived class needs to forward arguments to the base JVMBridgeBase class.
///
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(params object[] args) : base(args)
{
@@ -21,12 +22,27 @@ public partial class ALLPACKAGE_CLASSES_STUB_CLASS_PLACEHOLDER : ALLPACKAGE_CLAS
InitializeHandlers(listenerRuntimeType);
}
+ ///
+ /// if the user has overridden in a subclass.
+ /// Cached at construction to avoid per-event reflection cost. When , the first gate always
+ /// returns so that the second gate is reached regardless of whether individual event handlers are registered.
+ ///
readonly bool _hasALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDERSecondGate;
+
///
+ ///
+ /// Evaluated in order:
+ ///
+ /// - delegate — index-based, no string conversion, lowest overhead.
+ /// - delegate — name-based, resolves via .
+ /// - — returns if the specific event has a registered delegate or a virtual method override.
+ /// - — returns if the second gate is overridden, ensuring all events reach it.
+ ///
+ ///
protected override bool ListenerShallManageEvent(int eventIndex)
{
- if (ListenerShallManageEventIndex != null) return ListenerShallManageEventIndex(eventIndex); // test first gate base handler with index
- if (ListenerShallManageEventName != null) return ListenerShallManageEventName(ConvertListenerEventIndexToEventName(eventIndex)); // or test first gate base handler with name
+ if (ListenerShallManageEventIndex != null) return ListenerShallManageEventIndex(eventIndex);
+ if (ListenerShallManageEventName != null) return ListenerShallManageEventName(ConvertListenerEventIndexToEventName(eventIndex));
if (ListenerShallManageEventHandlers(eventIndex)) return true;
return _hasALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDERSecondGate;
}
@@ -40,28 +56,40 @@ ALLPACKAGE_CLASSES_STUB_LISTENER_CLASS_PLACEHOLDER
#region ALLPACKAGE_CLASSES_STUB_CLASS_DIRECT_PLACEHOLDER declaration
///
-/// Direct override of or its generic type if there is one
+/// Concrete CLR representation of returned by the JVM.
///
+///
+/// When the JVM returns an instance of this listener type, JCOBridge needs a concrete CLR class to wrap it.
+/// A full listener implementation cannot be used in this scenario because it would require user-provided handler code
+/// that is not available at the point of construction. This class provides a minimal, handler-free wrapper:
+/// is a no-op, unconditionally
+/// returns discarding all events immediately, and is
+/// to prevent automatic JVM-side registration.
+/// Do not use this class directly to register event handlers — use instead.
+///
public partial class ALLPACKAGE_CLASSES_STUB_CLASS_DIRECT_PLACEHOLDER : ALLPACKAGE_CLASSES_STUB_CLASS_PLACEHOLDER
{
///
- /// Internal constructor: used internally from JCOBridge
+ /// Initializer used internally by JCOBridge. Do not use directly.
///
[global::System.Obsolete("This public initializer is needed for JCOBridge internal use, other uses can produce unidentible behaviors.")]
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDERDirect(IJVMBridgeBaseInitializer initializer) : base(initializer) { }
+
///
- /// Generic constructor: it is useful for JCOBridge when there is a derived class which needs to pass arguments to the highest JVMBridgeBase class
+ /// Generic constructor used by JCOBridge when a derived class needs to forward arguments to the base JVMBridgeBase class.
///
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDERDirect(params object[] args) : base(args) { }
///
public override bool AutoInit => false;
- ///
+ ///
+ /// No handlers are registered in this direct override — initialization is intentionally skipped.
protected override void InitializeHandlers(global::System.Type _) { }
///
- protected override bool ListenerShallManageEvent(int _) { return false; } // early discard since no handlers are registered
+ /// Always returns — all events are discarded at the first gate without reading any JVM argument data.
+ protected override bool ListenerShallManageEvent(int _) => false;
const string _bridgeClassName = "ALLPACKAGE_CLASSES_STUB_JAVACLASS_DIRECT_PLACEHOLDER";
private static readonly global::System.Exception _LocalBridgeClazzException = null;
diff --git a/src/net/JNetReflector/Templates/SingleListenerJavaFile.template b/src/net/JNetReflector/Templates/SingleListenerJavaFile.template
index 97086a90c8..fdda4f7ac6 100644
--- a/src/net/JNetReflector/Templates/SingleListenerJavaFile.template
+++ b/src/net/JNetReflector/Templates/SingleListenerJavaFile.template
@@ -9,63 +9,134 @@ package ALLPACKAGE_PACKAGE_PLACEHOLDER;
public final class ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER ALLPACKAGE_CLASSES_STUB_EXTEND_JAVACLASS_PLACEHOLDERimplements org.mases.jcobridge.IJCListenerALLPACKAGE_CLASSES_STUB_JAVACLASS_PLACEHOLDER {
final org.mases.jcobridge.JCListener _internalListener;
+ /**
+ * Constructs the listener and registers it with the JCOBridge runtime using the provided key.
+ * @param key the registration key used by JCOBridge to identify this listener instance on the CLR side.
+ * @throws org.mases.jcobridge.JCNativeException if the native bridge initialization fails.
+ */
public ALLPACKAGE_CLASSES_STUB_SIMPLECLASS_PLACEHOLDER(String key) throws org.mases.jcobridge.JCNativeExceptionCONSTRUCTOR_STUB_CONSTRUCTOR_EXTEND_EXCEPTIONS_PLACEHOLDER {
super();
_internalListener = new org.mases.jcobridge.JCListener(key);
}
+ /**
+ * Releases the resources held by this listener and unregisters it from the JCOBridge runtime.
+ */
public synchronized void release() {
_internalListener.release();
}
+ /**
+ * Returns the numeric index associated with the given event name.
+ * The index is used by the CLR side for zero-cost index-based event filtering.
+ * @param eventName the name of the event as registered on the CLR side.
+ * @return the numeric index of the event.
+ */
public synchronized int getEventIndex(String eventName) {
return _internalListener.getEventIndex(eventName);
}
-
+
+ /**
+ * Raises the named event on the CLR side with no associated data.
+ * @param eventName the name of the event to raise.
+ */
public synchronized void raiseEvent(String eventName) {
_internalListener.raiseEvent(eventName);
}
+ /**
+ * Raises the event identified by index on the CLR side with no associated data.
+ * @param eventIndex the numeric index of the event to raise.
+ */
public synchronized void raiseEvent(int eventIndex) {
_internalListener.raiseEvent(eventIndex);
}
-
+
+ /**
+ * Raises the named event on the CLR side, passing a single data object.
+ * @param eventName the name of the event to raise.
+ * @param e the data object associated with the event.
+ */
public synchronized void raiseEvent(String eventName, Object e) {
_internalListener.raiseEvent(eventName, e);
}
+ /**
+ * Raises the event identified by index on the CLR side, passing a single data object.
+ * @param eventIndex the numeric index of the event to raise.
+ * @param e the data object associated with the event.
+ */
public synchronized void raiseEvent(int eventIndex, Object e) {
_internalListener.raiseEvent(eventIndex, e);
}
-
+
+ /**
+ * Raises the named event on the CLR side, passing a primary data object and additional arguments.
+ * @param eventName the name of the event to raise.
+ * @param e the primary data object associated with the event.
+ * @param objects additional arguments forwarded to the CLR handler.
+ */
public synchronized void raiseEvent(String eventName, Object e, Object... objects) {
_internalListener.raiseEvent(eventName, e, objects);
}
+ /**
+ * Raises the event identified by index on the CLR side, passing a primary data object and additional arguments.
+ * @param eventIndex the numeric index of the event to raise.
+ * @param e the primary data object associated with the event.
+ * @param objects additional arguments forwarded to the CLR handler.
+ */
public synchronized void raiseEvent(int eventIndex, Object e, Object... objects) {
_internalListener.raiseEvent(eventIndex, e, objects);
}
-
+
+ /**
+ * Returns the data object sent by the CLR side for the current event, if any.
+ * @return the event data object, or {@code null} if none was provided.
+ */
public Object getEventData() {
return _internalListener.getEventData();
}
-
+
+ /**
+ * Returns {@code true} if the current event has additional arguments beyond the primary data object.
+ * @return {@code true} if extra data is available.
+ */
public boolean hasExtraData() {
return _internalListener.hasExtraData();
}
-
+
+ /**
+ * Returns the number of additional arguments associated with the current event.
+ * @return the length of the extra data array.
+ */
public int extraDataLength() {
return _internalListener.extraDataLength();
}
-
+
+ /**
+ * Returns the additional arguments associated with the current event.
+ * @return an array of extra data objects, or an empty array if none are present.
+ */
public Object[] extraData() {
return _internalListener.extraData();
}
-
+
+ /**
+ * Returns the return value set by the CLR handler for the current event.
+ * Used when the JVM interface method has a non-void return type and the CLR side
+ * must supply the value via {@link #setReturnData(Object)}.
+ * @return the return value, or {@code null} if not set.
+ */
public Object getReturnData() {
return _internalListener.getReturnData();
}
-
+
+ /**
+ * Sets the return value that the JVM interface method will return to its caller.
+ * Must be called by the CLR handler before control returns to the JVM for non-void interface methods.
+ * @param retData the value to return to the JVM caller.
+ */
public void setReturnData(Object retData) {
_internalListener.setReturnData(retData);
}
diff --git a/src/net/JNetReflector/Templates/SingleListenerMethod.template b/src/net/JNetReflector/Templates/SingleListenerMethod.template
index d2ae932850..835eaaa425 100644
--- a/src/net/JNetReflector/Templates/SingleListenerMethod.template
+++ b/src/net/JNetReflector/Templates/SingleListenerMethod.template
@@ -2,18 +2,29 @@
///
/// Handler for METHOD_STUB_METHOD_HELP_PLACEHOLDER
///
-/// If has a value it takes precedence over corresponding class method
+///
+/// Assign a delegate to handle the event without subclassing. If both this handler and a virtual method override are present,
+/// the delegate takes precedence. Set to to delegate to the virtual method.
+///
public METHOD_STUB_LISTENER_EXECUTION_TYPE_PLACEHOLDER OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER { get; set; } = null;
+METHOD_STUB_LISTENER_DISPOSE_HANDLER_PLACEHOLDER
+/// Index assigned by for the event. Used for zero-cost index-based filtering in .
+int _METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandlerIndex = 0;
-int METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandlerIndex = 0;
+/// if the user has overridden in a subclass. Cached at construction to avoid per-event reflection.
bool _hasOverrideMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER;
+
+/// Returns if this event has an active handler — either a delegate assignment or a virtual method override. Used by to discard events with no registered handler without reading JVM argument data.
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
bool METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden() => _hasOverrideMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER || OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER != null;
+
void METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandler(object sender, CLRListenerEventArgs> data)
{
- if (!METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden()) // can be omitted however it is a protection against an user override of ListenerShallManageEvent
+ if (!METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden()) // guard: no handler registered — return without reading data.
+ // Normally unreachable if ListenerShallManageEvent filtered correctly,
+ // but protects against user overrides of ListenerShallManageEvent that bypass the check.
{
- // returns immediately without analyze anything, data.EventData.TypedEventData.HasOverride is false by default
+ // data.EventData.TypedEventData.HasOverride is false by default — JVM receives no return value.
return;
}
METHOD_STUB_LISTENER_HANDLER_EXECUTION_PLACEHOLDER
diff --git a/src/net/JNetReflector/Templates/Templates.cs b/src/net/JNetReflector/Templates/Templates.cs
index 07848edb62..b915d87f02 100644
--- a/src/net/JNetReflector/Templates/Templates.cs
+++ b/src/net/JNetReflector/Templates/Templates.cs
@@ -212,9 +212,10 @@ public class MethodStub
public const string LISTENER_PARAMETERS_TYPES = "METHOD_STUB_LISTENER_PARAMETERS_TYPES_PLACEHOLDER";
public const string LISTENER_HANDLER_EXECUTION = "METHOD_STUB_LISTENER_HANDLER_EXECUTION_PLACEHOLDER";
public const string LISTENER_HANDLER_NAME = "METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER";
- public static string SINGLE_LISTENER_HANDLER_FORMAT = " METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandlerIndex = AddEventHandler(\"{0}\", new global::System.EventHandler>>(METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandler));" + Environment.NewLine // removed OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER = METHOD_STUB_METHOD_NAME_PLACEHOLDER;";
+ public const string LISTENER_DISPOSE_HANDLER = "METHOD_STUB_LISTENER_DISPOSE_HANDLER_PLACEHOLDER";
+ public static string SINGLE_LISTENER_HANDLER_FORMAT = " _METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandlerIndex = AddEventHandler(\"{0}\", new global::System.EventHandler>>(METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandler));" + Environment.NewLine // removed OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER = METHOD_STUB_METHOD_NAME_PLACEHOLDER;";
+ " _hasOverrideMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER = MASES.JNet.Specific.JNetEventResult.GetMethodIsOverridden(listenerRuntimeType, nameof(METHOD_STUB_METHOD_NAME_PLACEHOLDER)METHOD_STUB_LISTENER_PARAMETERS_TYPES_PLACEHOLDER);";
- public const string SINGLE_LISTENER_FIRST_GATE_FORMAT = " if (eventIndex == METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandlerIndex) return METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden();";
+ public const string SINGLE_LISTENER_FIRST_GATE_FORMAT = " if (eventIndex == _METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventHandlerIndex) return METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden();";
public const string EXECUTION_FORMAT = "{0}{1}{2}(\"{3}\"{4}{5});";
public const string SINGLE_ARRAY_EXECUTION_FORMAT = "new object[] {{ {0} }}";
public const string STATIC_EXECUTION_FORMAT = "{0}{1}{2}(LocalBridgeClazz, \"{3}\"{4}{5});";
@@ -238,12 +239,25 @@ public class MethodStub
public const string INSTANCE_EXECUTE = "IExecute";
public const string SIGNATURE_EXECUTE_TRAILER = "WithSignature";
+ public static readonly string LISTENER_DISPOSE_HANDLER_FORMAT = "" + Environment.NewLine
+ + "/// " + Environment.NewLine
+ + "/// Optional handler invoked after the event handler returns, to dispose the JVM object returned by this event." + Environment.NewLine
+ + "/// " + Environment.NewLine
+ + "/// Set when the event handler returns a JVM-backed object" + Environment.NewLine
+ + "/// that is no longer needed after the call. The handler receives the return value and is responsible for calling" + Environment.NewLine
+ + "/// on it, releasing the underlying JVM global reference immediately" + Environment.NewLine
+ + "/// instead of waiting for the .NET garbage collector to finalize it." + Environment.NewLine
+ + "/// If not set, the return value is not disposed automatically." + Environment.NewLine
+ + "public global::System.Action OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDERDispose { get; set; } = null;" + Environment.NewLine
+ + "";
+
public static readonly string ACTION_LISTENER_EXECUTION_HANDLER_FORMAT = " var methodToExecute = (OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER != null) ? OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER : METHOD_STUB_METHOD_NAME_PLACEHOLDER;" + Environment.NewLine
+ " methodToExecute.Invoke(METHOD_STUB_LISTENER_EXECUTION_PLACEHOLDER);" + Environment.NewLine
+ " data.EventData.TypedEventData.HasOverride = METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden();";
public static readonly string FUNC_LISTENER_EXECUTION_HANDLER_FORMAT = " var methodToExecute = (OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER != null) ? OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDER : METHOD_STUB_METHOD_NAME_PLACEHOLDER;" + Environment.NewLine
+ " var executionResult = methodToExecute.Invoke(METHOD_STUB_LISTENER_EXECUTION_PLACEHOLDER);" + Environment.NewLine
- + " data.EventData.TypedEventData.SetReturnData(METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden(), executionResult);";
+ + " data.EventData.TypedEventData.SetReturnData(METHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDEREventOverridden(), executionResult);" + Environment.NewLine
+ + " OnMETHOD_STUB_LISTENER_HANDLER_NAME_PLACEHOLDERDispose?.Invoke(executionResult);";
public static readonly string BLOCK_LISTENER_HANDLER_FORMAT = "/// " + Environment.NewLine
+ "/// Handlers initializer for " + Environment.NewLine