-AUTEUR(S): Spedy
-DESCRIPTION : Habitué à utiliser ce type de signal en As3 j'ai voulu le porter en JS pour unity. Cela propose une alternative au SendMessage simple. On connect une function a un "channel" puis quand un signal est emis sur le "channel" la function est lancé, avec possibilité de lui passer un Object en param. Une fois la function connecté, le signal peut être émis de n'importe ou.
Des avis sont les bienvenus.
-UTILISATION :
connecter un signal
Code : Tout sélectionner
Signal.connect( MaFunction, "MonSignal", this )
Code : Tout sélectionner
Signal.disconnect( MaFunction, "MonSignal" )
Code : Tout sélectionner
Signal.emit( "MonSignal", param )
-SCRIPT : JS version complete
Code : Tout sélectionner
#pragma strict
import System.Collections.Generic;
private static var _dChannels : Dictionary.<String, List.<SignalListener> >;
/**
* function connect
*
* @param
* @return
*/
static function connect( f:Function, c:String, from:Object ) : boolean{
if( !_dChannels )
_dChannels = new Dictionary.<String, List.<SignalListener> >( );
if( isRegistered( f, c ) )
return false;
var vTmp : List.<SignalListener>;
if( hasChannel( c ) )
vTmp = _dChannels[ c ];
else
vTmp = new List.<SignalListener>( );
vTmp.Add( new SignalListener( f, c, from ) );
_dChannels[ c ] = vTmp;
return true;
}
/**
* function disconnect
*
* @param
* @return
*/
static function disconnect( f:Function, c:String ){
if( !hasChannel( c ) )
return false;
var vTmp : List.<SignalListener> = _dChannels[ c ];
var i : int = 0;
var l : int = vTmp.Count;
var s : SignalListener;
if( l == 0 )
return false;
for( i = 0; i < l; i++ ){
s = vTmp[ i ];
if( s.fRef == f && s.channel == c )
break;
s = null;
}
if( s == null )
return false;
vTmp.Remove( s );
_dChannels[ c ] = vTmp;
return true;
}
/**
* function hasChannel
*
* @param
* @return
*/
static function hasChannel( c:String ) : boolean{
if( !_dChannels )
_dChannels = new Dictionary.<String, List.<SignalListener> >( );
return _dChannels.ContainsKey( c );
}
/**
* function isRegistered
*
* @param
* @return
*/
static function isRegistered( f:Function, c:String ) : boolean{
if( !hasChannel( c ) )
return false;
var vTmp : List.<SignalListener> = _dChannels[ c ];
var l : int = vTmp.Count;
var i : int = 0;
var sl : SignalListener;
for( i = 0; i < l; i++ ){
sl = vTmp[ i ];
if( sl.fRef == f )
return true;
}
return false;
}
/**
* function emit
*
* @param
* @return
*/
static function emit( c:String, param:Object ):boolean {
if( !hasChannel( c ) ){
print( '|| ATTENTION || -Signal :: Aucun recepteur pour ::: ' + c );
return false;
}
var vTmp : List.<SignalListener> = _dChannels[ c ];
var l : int = vTmp.Count;
if( l == 0 )
return false;
var sl : SignalListener;
var vRem : List.<SignalListener> = new List.<SignalListener>( );
var i : int = 0;
for( i = 0; i < l; i++ ){
sl = vTmp[ i ];
if( param == null )
sl.fRef( );
else
sl.fRef( param );
}
return true;
}
class SignalListener{
public var from : Object;
public var channel : String;
public var fRef : Function;
public function SignalListener( f:Function, c:String, fr:Object ){
from = fr;
channel = c;
fRef = f;
}
}
Code : Tout sélectionner
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public delegate void FunctionPointer( );
internal class SignalListener{
public GameObject from;
public string channel;
public FunctionPointer fRef;
}
public class SignalC : MonoBehaviour {
private static Dictionary<string, List<SignalListener>> _dChannels;
public static bool connect( FunctionPointer f, string c, GameObject from ){
if( _dChannels == null )
_dChannels = new Dictionary<string, List<SignalListener>>();
if( isRegistered( f, c ) )
return false;
List<SignalListener> vTmp;
if( hasChannel( c ) )
vTmp = _dChannels[ c ];
else
vTmp = new List<SignalListener>( );
SignalListener sl = new SignalListener( );
sl.fRef = f;
sl.channel = c;
sl.from = from;
vTmp.Add( sl );
_dChannels[ c ] = vTmp;
return true;
}
public static bool disconnect( FunctionPointer f, string c ){
if( !hasChannel( c ) )
return false;
List<SignalListener> vTmp = _dChannels[ c ];
int i = 0;
int l = vTmp.Count;
SignalListener s = null;
if( l == 0 )
return false;
for( i = 0; i < l; i++ ){
s = vTmp[ i ];
if( s.fRef == f && s.channel == c )
break;
s = null;
}
if( s == null )
return false;
vTmp.Remove( s );
_dChannels[ c ] = vTmp;
return true;
}
public static bool hasChannel( string c ){
if( _dChannels == null )
_dChannels = new Dictionary<string, List<SignalListener>>( );
return _dChannels.ContainsKey( c );
}
public static bool isRegistered( FunctionPointer f, string c ){
if( !hasChannel( c ) )
return false;
List<SignalListener> vTmp = _dChannels[ c ];
int l = vTmp.Count;
int i = 0;
SignalListener sl;
for( i = 0; i < l; i++ ){
sl = vTmp[ i ];
if( sl.fRef == f )
return true;
}
return false;
}
public static bool emit( string c ){
if( !hasChannel( c ) ){
return false;
}
List<SignalListener> vTmp = _dChannels[ c ];
int l = vTmp.Count;
if( l == 0 )
return false;
SignalListener sl;
int i = 0;
for( i = 0; i < l; i++ ){
sl = vTmp[ i ];
if( sl.from == null ){
vTmp.Remove( sl );
return false;
}
sl.fRef( );
}
return true;
}
}