Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package matt.engine.rts;
- import java.lang.reflect.Method;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.NoSuchElementException;
- import matt.util.array.SyncList;
- import matt.util.Pair;
- public class Binding
- {
- final Object source;
- private Map<String, List<Callback>> eventToCallbacks;
- public Binding(Object source)
- {
- this.source = source;
- }
- public void listen(String event, Object target)
- {
- if (eventToCallbacks == null)
- this.eventToCallbacks = new HashMap<String, List<Callback>>();
- Method method = findMethodForEvent(this.source, target, event);
- List<Callback> callbacks = this.eventToCallbacks.get(event);
- if (callbacks == null)
- this.eventToCallbacks.put(event, callbacks = new SyncList<Callback>());
- callbacks.add(new Callback(target, method));
- }
- public void discard(String event, Object target)
- {
- List<Callback> callbacks = this.eventToCallbacks.get(event);
- if (callbacks == null)
- return;
- Callback match = null;
- for (Callback callback : callbacks)
- if (callback.target == target)
- match = callback;
- callbacks.remove(match);
- if (callbacks.isEmpty())
- this.eventToCallbacks.remove(event);
- if (this.eventToCallbacks.size() == 0)
- this.eventToCallbacks = null;
- }
- public void fire(String event)
- {
- List<Callback> callbacks = this.eventToCallbacks.get(event);
- if (callbacks != null) {
- ((SyncList<Callback>)callbacks).update();
- for (Callback callback : callbacks)
- callback.call();
- }
- }
- // callback
- private class Callback
- {
- final Object target;
- final Method method;
- public Callback(Object target, Method method)
- {
- this.target = target;
- this.method = method;
- }
- public void call()
- {
- try
- {
- this.method.invoke(this.target, new Object[] { Binding.this.source });
- }
- catch (Exception exc)
- {
- throw new RuntimeException(exc);
- }
- }
- }
- // utility methods
- private static Method findMethodForEvent(Object source, Object target, String event)
- {
- Pair<String, Class<?>> key = new Pair<String, Class<?>>(event, target.getClass());
- Method found = method_cache.get(key);
- if (found != null)
- return found;
- found = findMethodByName(source, target, fromEventToMethodname(source, event));
- method_cache.put(key, found);
- return found;
- }
- private static String fromEventToMethodname(Object source, String event)
- {
- String typeName = source.getClass().getSimpleName();
- String capitalizedEvent = event.substring(0, 1).toUpperCase() + event.substring(1);
- return "on" + typeName + capitalizedEvent;
- }
- private static Method findMethodByName(Object source, Object target, String methodName)
- {
- for (Method method : target.getClass().getMethods())
- {
- if (!method.getName().equals(methodName))
- continue;
- Class< ? >[] types = method.getParameterTypes();
- if (types.length != 1)
- throw new IllegalStateException("event handler must have 1 parameter");
- if (types[0] != source.getClass())
- throw new IllegalStateException("event handler must have 1 parameter type equal to the source type");
- method.setAccessible(true);
- return method;
- }
- throw new NoSuchElementException(methodName);
- }
- private static Map<Pair<String, Class<?>>, Method> method_cache = new HashMap<Pair<String, Class<?>>, Method>();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement