[JS / ~CS] Signal

Cette section est destinée aux scripts partagés par la communauté. Chaque post est destiné à un script. Suivez bien les recommandations.
Avatar de l’utilisateur
spedy
Messages : 290
Inscription : 16 Nov 2010 16:32
Localisation : Aix en Provence

[JS / ~CS] Signal

Message par spedy » 26 Avr 2013 15:01

-NOM DU SCRIPT : Signal.js

-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 )
déconnecter un signal

Code : Tout sélectionner

Signal.disconnect( MaFunction, "MonSignal" )
déclencher un signal

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;
	}
}
SCRIPT : CS cette version ne prend pas encore en compte l'envoie de paramètre ( Work in progress )

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;
	}
}
Dernière édition par spedy le 29 Avr 2013 15:06, édité 1 fois.

Avatar de l’utilisateur
cayou66
Codeur
Codeur
Messages : 6450
Inscription : 30 Juin 2011 14:45
Localisation : Montréal

Re: [JS] Signal

Message par cayou66 » 26 Avr 2013 15:12

Bonne idée,
quelqu'un là où je bosse avait fait un système similaire, il venait aussi du monde AS3.
J'aurai bien aimé voir ça en C# par contre ;)

Perso je me sers pas d'un tel truc, références publiques et singletons me suffisent.

sephitoth
Messages : 495
Inscription : 06 Avr 2012 13:47
Localisation : toulouse

Re: [JS] Signal

Message par sephitoth » 26 Avr 2013 17:17

Les singletons aux pouvoir !!!!

personnellement, le jour ou j'ai découvert les design pattern, ça a changé ma vie !!!
J'étais athée jusqu’à ce que je découvre que j'étais dieu !

Avatar de l’utilisateur
krys64
Fondateur unity3d-france
Fondateur unity3d-france
Messages : 471
Inscription : 26 Nov 2009 00:08

Re: [JS] Signal

Message par krys64 » 26 Avr 2013 21:15

J'aurai bien aimé voir ça en C# par contre
Tu as le système évènementiel as3 reproduit en c# ici. Je m'en sers et c'est génial.
http://www.dustinandrew.me/blog/2012/10 ... nager.html

Avatar de l’utilisateur
cayou66
Codeur
Codeur
Messages : 6450
Inscription : 30 Juin 2011 14:45
Localisation : Montréal

Re: [JS] Signal

Message par cayou66 » 26 Avr 2013 21:29

sephitoth a écrit :Les singletons aux pouvoir !!!!

personnellement, le jour ou j'ai découvert les design pattern, ça a changé ma vie !!!
Tellement !

@Krys: Cool merci :)

Avatar de l’utilisateur
Titan
Messages : 582
Inscription : 12 Sep 2011 13:54
Contact :

Re: [JS] Signal

Message par Titan » 28 Avr 2013 15:19

vous reprochez quoi aux event ?
____________________________________________
Hop Boy

Avatar de l’utilisateur
ZJP
Messages : 5748
Inscription : 15 Déc 2009 06:00

Re: [JS] Signal

Message par ZJP » 28 Avr 2013 16:11

Titan a écrit :vous reprochez quoi aux event ?
Moi? Rien. :mrgreen:

Sinon, Notification Center, si vous avez 5$ a bien dépenser.

@Spedy.
Merci, même si comme Cayou une version C#....

@Krys.

Gaffe aux "SendMessage".

Avatar de l’utilisateur
cayou66
Codeur
Codeur
Messages : 6450
Inscription : 30 Juin 2011 14:45
Localisation : Montréal

Re: [JS] Signal

Message par cayou66 » 28 Avr 2013 16:22

Titan a écrit :vous reprochez quoi aux event ?
Rien, c'est juste que je fonctionne sans, et tout va bien :)

Avatar de l’utilisateur
Titan
Messages : 582
Inscription : 12 Sep 2011 13:54
Contact :

Re: [JS] Signal

Message par Titan » 28 Avr 2013 21:28

La question mal formulé, en fait, c'était: pourquoi vouloir ré-implémenter une fonctionnalité déjà intrinsèque au langage ?
http://msdn.microsoft.com/fr-fr/library ... s.80).aspx

Après j'avoue que je m'en sers presque jamais, à part récemment pour un puzzle game où tout les objets de la scène ont besoin de se faire notifier le début et l’arrêt de la simulation, dans ce cas ça évite juste d'utiliser une list. mais j'irai clairement pas lancer un sendMessage (ou équivalent) sur un objet spécifique comme les sample le préconise "gameObject.SendMessage ("ApplyDamage", 5.0);".
____________________________________________
Hop Boy

Avatar de l’utilisateur
giyomuSan
Messages : 1799
Inscription : 09 Déc 2009 14:52
Localisation : Japon

Re: [JS] Signal

Message par giyomuSan » 29 Avr 2013 03:19

le send message est tres pratique qd on connait pas forcement l object qui va etre traiter mais qui peut par exemple implementer une interface, dans certain cas de collision ca simplifie pas mal.

apres il est d origine plus lent qu'un event, mais si c'est pas utiliser dans un update ca va pas etre la mort non plus..meme sur mobile , les device tiennent la route maintenant.

en gros c'est un peu pkus simple a mettre en place, pas de listener ni a faire attention de le virer qd on quitte la scene a defaut d'avoir quelques soucis lors du reload de cette meme scene.

apres , cote events , si on prevoit un system des le depart pour son jeux , les Action, Func c relativement pratique ..plus besoin de s'emmerder a specifier du delegate pour creer un event ..plus rapide a ecrire du coup, moins de ligne :mrgreen:

Répondre

Revenir vers « Scripts »