Advertisement
Guest User

Untitled

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