Le Blog de SamsamTS

Event...Aille !

Malgré l'éventail d'implémentations des évènements en Flash, aucune ne m'a jamais vraiment convaincu. Bien entendu je n'ai pas pu tester toutes les (nombreuses) solutions déjà existantes, trop long. Alors je me suis mis à réfléchir, comment voudrai-je qu'ils soient ?
  • Facile d'utilisation
  • Facile d'implémentation au sein d'une classe
  • Clairement identifiables
  • Avec des arguments bien définis
  • Pas d'écouteur qui écoute tous les évènements d'un même objet

Facile à dire.

Voici donc ma proposition :
com.samsamts.Events.Event

Code :

/**
 * @author SamsamTS
 */

import com.samsamts.Events.*;

class com.samsamts.Events.Event
{
   //{ Author properties
   public static var className:String = "Event";
   public static var classPackage:String = "com.samsamts.Events";
   public static var version:String = "1.0.0";
   public static var author:String = "SamsamTS";
   public static var link:String = "http://www.samsamts.com/blog/";
   //}
   
   public function Event()
   {
      m_arrHandlers = new Array();
   }
   
   //{ Public
   /**
   * Add an EventHandler
   * @param   handler
   * @return   The event
   */

   public function Add(handler:EventHandler):Event
   {
      Remove(handler);
      m_arrHandlers.push(handler);
      return this;
   }
   /**
   * Remove an EventHandler
   * @param   handler
   * @return   The event
   */

   public function Remove(handler:EventHandler):Event
   {
      for (var i : Number = 0; i < m_arrHandlers.length; i++)
      {
         if(m_arrHandlers[i].Compare(handler))
         {
            m_arrHandlers.splice(i,1);
            return this;
         }
      }
      return this;
   }
   /**
   * Trigger the event (it calls all EventHandlers)
   * @param   sender Object sending the event
   * @param   arg EventArgs to be transmitted
   */

   public function Trigger(sender:Object, arg:EventArgs):Void
   {
      var arr:Array = m_arrHandlers.slice();
      for (var i:Number = 0; i < arr.length; i++)
      {
         if(!arr[i].Call(sender, arg))
            Remove(arr[i]);
      }   
   }
   
   public function toString():String
   {
      return "[Event]";
   }
   //}
   
   //{ Private
   private var m_arrHandlers:Array;
   //}
}

com.samsamts.Events.EventHandler

Code :

/**
 * @author SamsamTS
 */

import com.samsamts.Events.*;

class com.samsamts.Events.EventHandler
{
   //{ Author properties
   public static var className:String = "EventHandler";
   public static var classPackage:String = "com.samsamts.Events";
   public static var version:String = "1.0.0";
   public static var author:String = "SamsamTS";
   public static var link:String = "http://www.samsamts.com/blog/";
   //}
   
   /**
   * Constructor
   * @param   target Target on which to apply the function
   * @param   f The function to call
   * @param   ... Additional arguments to be transmitted
   */

   public function EventHandler(target:Object, f:Function)
   {
         m_function = f;
         m_target = target;
         m_arguments = arguments.slice(2);
   }
   
   //{ Public
   /**
   * Call the EventHandler
   * If the target doesn't exist the call fails
   * @param   sender The Object wich calls
   * @param   arg
   * @return   false if the call fails
   */

   public function Call(sender:Object, arg:EventArgs):Boolean
   {
         if(m_target == undefined)
            return false;
         m_function.apply(m_target, (new Array(sender, arg)).concat(m_arguments));
         return true;
   }
   /**
   * Compare two EventHandler
   * @param   handler EventHandler to be compared
   * @return   true if they are equal
   */

   public function Compare(handler:EventHandler):Boolean
   {
      return m_function == handler.m_function && m_target == handler.m_target;
   }
   
   public function toString():String
   {
      return "[EventHandler]";
   }
   //}

   //{ Private
   private var m_function:Function;
   private var m_target:Object;
   private var m_arguments:Array;
   //}
}

com.samsamts.Events.EventArgs

Code :

/**
 * Default empty EventArgs
 * Extend it to add your own properties
 * @author SamsamTS
 */

class com.samsamts.Events.EventArgs
{
   //{ Author properties
   public static var className:String = "EventArgs";
   public static var classPackage:String = "com.samsamts.Events";
   public static var version:String = "1.0.0";
   public static var author:String = "SamsamTS";
   public static var link:String = "http://www.samsamts.com/blog/";
   //}
      
   public function EventArgs()
   {
   }
      
   //{ Public
   public function toString():String
   {
      return "[EventArgs]";
   }
   //}
}

Utilisation

Code :

// Declare an event
var OnSomething:Event;

// Intitialize the event :
OnSomething = new Event();

// Add an EventHandler
OnSomething.Add(new EventHandler(myTarget, myFunction));

// Trigger the Event
OnSomething.Trigger(this, new EventArgs());

Voilà, je suis ouvert à toutes remarques/critiques du moment que c'est constructif ;)

Vos commentaires

Le vendredi 10 février 2006 à 22:27 , commentaire par Philippe :: #

 

C'est amusant, c'est à peu près exactement le système d'évènements que Itératif et moi avions discuté il y a pas longtemps.

J'ai gardé ma version pour moi, mais Itératif a bloggué la sienne :
iteratif.free.fr/blog/ind...
iteratif.free.fr/blog/ind...

Je suis tout à fait *pour* ce genre de modèle évènementiel :)

 

Le vendredi 10 février 2006 à 22:28 , commentaire par Philippe :: #

 

Mmmm. Les urls ne sont pas trop bien passées  :D

 

Le vendredi 10 février 2006 à 23:13 , commentaire par SamsamTS :: #

 

Merci pour les liens, ca y ressemble tout à fait, comme quoi je ne suis pas le seul à penser comme ca :)

Je suis également entrain de faire une classe qui ressemble à la classe SuperMovieClip d'Iteratif mais avec pas mal d'éléments en plus  8)

Pour la petite histoire je me suis inspiré des évènements en C# bien que ce ne soit pas possible de faire exactement pareil.

PS : J'ai corrigé les liens ;)

 

Le samedi 11 février 2006 à 17:09 , commentaire par Philippe :: #

 

C'est effectivement le modèle du C# qui a guidé Itératif  8)

Le problème de ce système c'est qu'il faut initialiser les propriétés Event. Si on commence à avoir énormément de propriétés à initialiser, ça perd un peu de son intérêt.

 

Ajouter un commentaire