Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 4.33 KB | None | 0 0
  1. /*
  2.  * Created on Oct 24, 2010
  3.  */
  4.  
  5. package engine.rts;
  6.  
  7. import java.lang.reflect.InvocationTargetException;
  8. import java.lang.reflect.Method;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.NoSuchElementException;
  14.  
  15. import craterstudio.data.tuples.Pair;
  16.  
  17. public class Binding
  18. {
  19.    final Object                        source;
  20.    private Map<String, List<Callback>> eventToCallbacks;
  21.  
  22.    public Binding(Object source)
  23.    {
  24.       this.source = source;
  25.       this.eventToCallbacks = null;
  26.    }
  27.  
  28.    public void listen(String event, Object target)
  29.    {
  30.       Method method = findMethodForEvent(this.source, target, event);
  31.  
  32.       if (this.eventToCallbacks == null)
  33.          this.eventToCallbacks = new HashMap<String, List<Callback>>();
  34.       List<Callback> callbacks = this.eventToCallbacks.get(event);
  35.       if (callbacks == null)
  36.          this.eventToCallbacks.put(event, callbacks = new ArrayList<Callback>());
  37.       callbacks.add(new Callback(target, method));
  38.    }
  39.  
  40.    public void discard(String event, Object target)
  41.    {
  42.       if (this.eventToCallbacks == null)
  43.          throw new NoSuchElementException();
  44.       List<Callback> callbacks = this.eventToCallbacks.get(event);
  45.       if (callbacks == null)
  46.          throw new NoSuchElementException();
  47.  
  48.       Callback match = null;
  49.       for (Callback callback : callbacks)
  50.          if (callback.target == target)
  51.             match = callback;
  52.  
  53.       if (match == null)
  54.          throw new NoSuchElementException();
  55.       callbacks.remove(match);
  56.  
  57.       if (callbacks.isEmpty())
  58.       {
  59.          this.eventToCallbacks.remove(event);
  60.          if (this.eventToCallbacks.isEmpty())
  61.             this.eventToCallbacks = null;
  62.       }
  63.    }
  64.  
  65.    public void fire(String event)
  66.    {
  67.       if (this.eventToCallbacks == null)
  68.          return;
  69.       List<Callback> callbacks = this.eventToCallbacks.get(event);
  70.       if (callbacks != null)
  71.          for (Callback callback : callbacks.toArray(new Callback[callbacks.size()]))
  72.             callback.call();
  73.    }
  74.  
  75.    // callback
  76.  
  77.    private class Callback
  78.    {
  79.       final Object target;
  80.       final Method method;
  81.  
  82.       public Callback(Object target, Method method)
  83.       {
  84.          this.target = target;
  85.          this.method = method;
  86.       }
  87.  
  88.       public void call()
  89.       {
  90.          try
  91.          {
  92.             this.method.invoke(this.target, new Object[] { Binding.this.source });
  93.          }
  94.          catch (InvocationTargetException exc)
  95.          {
  96.             throw new RuntimeException(exc.getCause());
  97.          }
  98.          catch (Exception exc)
  99.          {
  100.             throw new RuntimeException(exc);
  101.          }
  102.       }
  103.    }
  104.  
  105.    // utility methods
  106.  
  107.    private static Method findMethodForEvent(Object source, Object target, String event)
  108.    {
  109.       Pair<String, Class< ? >> key = new Pair<String, Class< ? >>(event, target.getClass());
  110.       Method found = method_cache.get(key);
  111.       if (found != null)
  112.          return found;
  113.  
  114.       found = findMethodByName(source, target, fromEventToMethodname(source, event));
  115.       method_cache.put(key, found);
  116.       return found;
  117.    }
  118.  
  119.    private static String fromEventToMethodname(Object source, String event)
  120.    {
  121.       String typeName = source.getClass().getSimpleName();
  122.       String capitalizedEvent = event.substring(0, 1).toUpperCase() + event.substring(1);
  123.       return "on" + typeName + capitalizedEvent;
  124.    }
  125.  
  126.    private static Method findMethodByName(Object source, Object target, String methodName)
  127.    {
  128.       for (Method method : target.getClass().getDeclaredMethods())
  129.       {
  130.          if (!method.getName().equals(methodName))
  131.             continue;
  132.  
  133.          Class< ? >[] types = method.getParameterTypes();
  134.          if (types.length != 1)
  135.             throw new IllegalStateException("event handler must have 1 parameter");
  136.          if (types[0] != source.getClass())
  137.             throw new IllegalStateException("event handler must have 1 parameter type equal to the source type");
  138.  
  139.          method.setAccessible(true);
  140.          return method;
  141.       }
  142.       throw new NoSuchElementException(target.getClass().getSimpleName() + "." + methodName + "()");
  143.    }
  144.  
  145.    private static Map<Pair<String, Class< ? >>, Method> method_cache = new HashMap<Pair<String, Class< ? >>, Method>();
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement