- Home /
CSharpMessenger Extended generics work in flash 3.5 preview but not 4.0
I was using CSharpMessenger Extended, which I found [here][1], successfully with the export to flash preview in 3.5. But now that I have upgraded to 4.0 the same code converted with 4.0 no longer works when generics are used.
In the 4.0 version I get a null object reference error whenever trying to call any of the functions in any of the Messengers with any amount of generics.
The error looks like:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
Here is a snippet of the C# class that shoots an error whenever a function is called from it.
static public class Messenger<T>
{
private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable;
static public void AddListener(string eventType, Callback<T> handler)
{
MessengerInternal.OnListenerAdding(eventType, handler);
eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
}
static public void RemoveListener(string eventType, Callback<T> handler)
{
MessengerInternal.OnListenerRemoving(eventType, handler);
eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler;
MessengerInternal.OnListenerRemoved(eventType);
}
static public void Broadcast(string eventType, T arg1)
{
Broadcast(eventType, arg1, MessengerInternal.DEFAULT_MODE);
}
static public void Broadcast(string eventType, T arg1, MessengerMode mode)
{
MessengerInternal.OnBroadcasting(eventType, mode);
Delegate d;
if (eventTable.TryGetValue(eventType, out d))
{
Callback<T> callback = d as Callback<T>;
if (callback != null)
{
callback(arg1);
}
else
{
#if FALSE
throw MessengerInternal.CreateBroadcastSignatureException(eventType);
#endif
}
}
}
}
And here is what the AS3 of the converted class in the 3.5 FLASH PREVIEW:
package global {
import cil2as.ByRef;
import cil2as.DelegateOperations;
import System.CLIObject;
import System.Type;
import System.Collections.Generic.Dictionary$2;
public final class Messenger$1 extends CLIObject {
public static var eventTable: Dictionary$2 = MessengerInternal.eventTable;
public static function Messenger$1_AddListener_String_Callback$1($eventType: String, $handler: Function): void {
MessengerInternal.MessengerInternal_OnListenerAdding_String_Delegate($eventType, $handler);
eventTable.IDictionary$2_set_Item_TKey_TValue($eventType, DelegateOperations.Combine((eventTable.IDictionary$2_get_Item_TKey($eventType) as Function) as Function, $handler) as Function);
}
public static function Messenger$1_RemoveListener_String_Callback$1($eventType: String, $handler: Function): void {
MessengerInternal.MessengerInternal_OnListenerRemoving_String_Delegate($eventType, $handler);
eventTable.IDictionary$2_set_Item_TKey_TValue($eventType, DelegateOperations.Remove((eventTable.IDictionary$2_get_Item_TKey($eventType) as Function) as Function, $handler) as Function);
MessengerInternal.MessengerInternal_OnListenerRemoved_String($eventType);
}
public static function Messenger$1_Broadcast_String_T($eventType: String, $arg1: Object): void {
Messenger$1_Broadcast_String_T_MessengerMode($eventType, $arg1, MessengerInternal.DEFAULT_MODE);
}
public static function Messenger$1_Broadcast_String_T_MessengerMode($eventType: String, $arg1: Object, $mode: MessengerMode): void {
MessengerInternal.MessengerInternal_OnBroadcasting_String_MessengerMode($eventType, $mode);
var $delegate: Function;
if (eventTable.IDictionary$2_TryGetValue_TKey_TValueRef($eventType, new ByRef((function(): Object {
return $delegate;
}
), (function($value$: Object): void {
$delegate = $value$ as Function;
}
)))) {
var $callback: Function = $delegate as Function;
if ($callback != null) {
$callback($arg1);
}
}
}
public static function get $Type(): Type {
return _$Type != null ? _$Type : (_$Type = new Type(global.Messenger$1, {"AddListener" : "Messenger$1_AddListener_String_Callback$1", "RemoveListener" : "Messenger$1_RemoveListener_String_Callback$1", "Broadcast" : ["Messenger$1_Broadcast_String_T", "Messenger$1_Broadcast_String_T_MessengerMode"]}, CLIObject.$Type));
}
public static var _$Type: Type;
}
}
And finally, here is the AS3 of the converted class in the 4.0 FLASH EXPORT.
package global {
import cil2as.ByRef;
import cil2as.DelegateOperations;
import System.CLIArray;
import System.CLIArrayFactory;
import System.CLIObject;
import System.GenericTypeDefinition;
import System.GenericTypeParameter;
import System.Type;
import System.TypeLocalVariable;
import System.Collections.Generic.Dictionary$2;
import System.Reflection.FieldInfo;
import System.Reflection.MethodInfo;
import System.Reflection.ParameterInfo;
public final class Messenger$1 extends CLIObject {
public function Messenger$1(genericInstanceType: Type) {
this.$$genericInstanceType = genericInstanceType;
Messenger$1.eventTable = new TypeLocalVariable((function($$genericInstanceType: Type): Object {
return MessengerInternal.eventTable;
}
));
}
public static var eventTable: TypeLocalVariable;
public static function Messenger$1_AddListener_String_Callback$1($eventType: String, $handler: Function, $$genericInstanceType: Type): void {
MessengerInternal.MessengerInternal_OnListenerAdding_String_Delegate($eventType, $handler);
Dictionary$2(eventTable.ValueFor($Type.Type_MakeGenericType_TypeArray(CLIArrayFactory.NewArrayWithElements(Type.$Type, T.ValueFor($$genericInstanceType))))).IDictionary$2_set_Item_TKey_TValue($eventType, DelegateOperations.Combine((Dictionary$2(eventTable.ValueFor($Type.Type_MakeGenericType_TypeArray(CLIArrayFactory.NewArrayWithElements(Type.$Type, T.ValueFor($$genericInstanceType))))).IDictionary$2_get_Item_TKey($eventType) as Function) as Function, $handler) as Function);
}
public static function Messenger$1_RemoveListener_String_Callback$1($eventType: String, $handler: Function, $$genericInstanceType: Type): void {
MessengerInternal.MessengerInternal_OnListenerRemoving_String_Delegate($eventType, $handler);
Dictionary$2(eventTable.ValueFor($Type.Type_MakeGenericType_TypeArray(CLIArrayFactory.NewArrayWithElements(Type.$Type, T.ValueFor($$genericInstanceType))))).IDictionary$2_set_Item_TKey_TValue($eventType, DelegateOperations.Remove((Dictionary$2(eventTable.ValueFor($Type.Type_MakeGenericType_TypeArray(CLIArrayFactory.NewArrayWithElements(Type.$Type, T.ValueFor($$genericInstanceType))))).IDictionary$2_get_Item_TKey($eventType) as Function) as Function, $handler) as Function);
MessengerInternal.MessengerInternal_OnListenerRemoved_String($eventType);
}
public static function Messenger$1_Broadcast_String_T($eventType: String, $arg1: Object, $$genericInstanceType: Type): void {
Messenger$1_Broadcast_String_T_MessengerMode($eventType, $arg1, MessengerInternal.DEFAULT_MODE, $Type.Type_MakeGenericType_TypeArray(CLIArrayFactory.NewArrayWithElements(Type.$Type, T.ValueFor($$genericInstanceType))));
}
public static function Messenger$1_Broadcast_String_T_MessengerMode($eventType: String, $arg1: Object, $mode: MessengerMode, $$genericInstanceType: Type): void {
MessengerInternal.MessengerInternal_OnBroadcasting_String_MessengerMode($eventType, $mode);
var $delegate: Function;
if (Dictionary$2(eventTable.ValueFor($Type.Type_MakeGenericType_TypeArray(CLIArrayFactory.NewArrayWithElements(Type.$Type, T.ValueFor($$genericInstanceType))))).IDictionary$2_TryGetValue_TKey_TValueRef($eventType, new ByRef((function(): Object {
return $delegate;
}
), (function($value$: Object): void {
$delegate = $value$ as Function;
}
)))) {
var $callback: Function = $delegate as Function;
if ($callback != null) {
$callback($arg1);
}
}
}
private var $$genericInstanceType: Type;
private static var T: GenericTypeParameter = new GenericTypeParameter(0, "T");
override public function Object_GetType(): Type {
return this.$$genericInstanceType;
}
public static function $GenerateFieldInfo($t: Type): CLIArray {
return CLIArrayFactory.NewArrayWithElements(Type.ForClass(FieldInfo));
}
public static function $GenerateMethodInfo($t: Type): CLIArray {
return CLIArrayFactory.NewArrayWithElements(Type.ForClass(MethodInfo), new MethodInfo($t, "AddListener", CLIArrayFactory.NewArrayWithElements(Type.ForClass(ParameterInfo), new ParameterInfo(Type.ForClass(String)), new ParameterInfo(Type.ForClass(Object)))), new MethodInfo($t, "RemoveListener", CLIArrayFactory.NewArrayWithElements(Type.ForClass(ParameterInfo), new ParameterInfo(Type.ForClass(String)), new ParameterInfo(Type.ForClass(Object)))), new MethodInfo($t, "Broadcast", CLIArrayFactory.NewArrayWithElements(Type.ForClass(ParameterInfo), new ParameterInfo(Type.ForClass(String)), new ParameterInfo(Type.ForClass(Object)))), new MethodInfo($t, "Broadcast", CLIArrayFactory.NewArrayWithElements(Type.ForClass(ParameterInfo), new ParameterInfo(Type.ForClass(String)), new ParameterInfo(Type.ForClass(Object)), new ParameterInfo(Type.ForClass(MessengerMode)))));
}
public static function get $Type(): Type {
return _$Type != null ? _$Type : (_$Type = new GenericTypeDefinition(global.Messenger$1, {"AddListener" : "Messenger$1_AddListener_String_Callback$1", "RemoveListener" : "Messenger$1_RemoveListener_String_Callback$1", "Broadcast" : ["Messenger$1_Broadcast_String_T", "Messenger$1_Broadcast_String_T_MessengerMode"]}, (function(): Type {
return CLIObject.$Type;
}
), $GenerateFieldInfo, CLIArrayFactory.NewArrayWithElements(Type.ForClass(Type), T)));
}
public static var _$Type: Type;
}
}
I know this is a lot of uglyness to look at, but I'm completely stumped at how to solve this. I don't have very much AS3 knowledge, and I don't know where to being looking for a solution. [1]: http://wiki.unity3d.com/index.php/CSharpMessenger_Extended