All pastes #550981 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-06-08 16:23 UTC
rendered paste body
package events;

interface EventDispatcher {
	public var id (default, null) : String;
	public var broadcaster : Broadcaster;
}

class Event<T> {
	public var type(default,null) : EventType<T>;
	
	public function new( t ) {
		type = t;
	}
}

class EventType<T> {
	public var name(default,null) :String;
	public function new( name:String ) {
		this.name = name;
	}
	public function toString() {
		return name;
	}
}



private class EventRegistration<T> {
	var previous : EventRegistration;
	var next : EventRegistration;
	
	var handler : Event<T> -> Void;
	
	public var type (default, null) : EventType<T>;

	public function new ( type : EventType<T>, handler : Event<T> -> Void ) {
		this.dispatcher = dispatcher;
		this.type = type;
		this.handler = handler;
	}
	
	public function dispatch ( event : Event<T> ) : Void {
		handler( event );
		if( next != null ) {
			next.dispatch( event );
		}
	}
	
	public function remove () : Void {
		previous.next = next;

		if( next != null ) {
			next.previous = previous;
		}
	}
}


private class EventRegistrationChain<T> extends EventRegistration<T> {
	public function new () {
		//
	}
	
	public function dispatch ( event : Event<T> ) : Void {
		if( next != null ) {
			next.dispatch( event );
		}
	}
	
	public function add ( registration : EventRegistration<T> ) : Void {
		if( next != null ) {
			registration.next = next;
			next.previous = registration;
		}
		next = registration;
	}
}

private class Dispatcher<T> {
	var list : EventRegistrationChain<T>;
	
	public function new () {
		list = new EventRegistrationChain<T>();
	}
	
	public function dispatch ( e : Event<T> ) : Void {
		list.dispatch( e );
	}
	
	public function subscribe ( registration : EventRegistration<T> ) : Void {
		list.add( registration );
	}
}

class Broadcaster {
	var dispatchers : Hash<Dispatcher<Dynamic>>;
	
	public function new () {
		dispatchers = new Hash<Dispatcher<Dynamic>>();
	}
	
	public function subscribe ( handler : Event<T> -> Void, type : EventType<T> ) : EventRegistration<T> {
		var dispatcher = dispatchers.get( type.toString() );
		if( dispatcher == null ) {
			dispatcher = new Dispatcher<T>();
			dispatchers.set( type.toString(), dispatcher );
		}
		
		var registration = new EventRegistration<T>( type, handler );
		
		dispatcher.subscribe( registration );
		
		return registration;
	}
	
	public function dispatch ( event : Event<Dynamic> ) : Void {
		dispatchers.get( event.type.toString() ).dispatch( event );
	}
}

class SubscriptionManager {
	var subscriptions : Hash<Hash<EventRegistration>>
	
	public function new () {
		subscriptions = new Hash<Hash<EventRegistration>>();
	}
	
	public function subscribe ( handler : Event<T> -> Void, dispatcher : EventDispatcher, type : EventType<T> ) {
		var subscriptionsOfEvent = subscriptions.get( type.toString() );
		if( subscriptionsOfEvent == null ) {
			subscriptionsOfEvent = new Hash<EventRegistration>();
			subscriptions.set( type.toString(), subscriptionsOfEvent );
		}
		if( !subscriptionsOfEvent.exists( dispatcher.id ) ) {
			subscriptionsOfEvent.set( dispatcher.id, dispatcher.broadcaster.subscribe( handler, type ) );
		}
	}
	
	public function unsubscribe ( type : EventType, ?dispatcher : EventDispatcher ) : Void {
		var subscriptionsOfEvent = subscriptions.get( type.toString() );
		if( dispatcher != null ) {
			subscriptionsOfEvent.get( dispatcher.id ).remove();
			subscriptionsOfEvent.remove( dispatcher.id );
		} else {
			for( var registration in subscriptionsOfEvent ) {
				registration.remove();
			}
		}
	}
	
	public function disable ( type : EventType ) : Void {
		var subscriptionsOfEvent = subscriptions.get( type.toString() );
		for( var registration in subscriptionsOfEvent ) {
			registration.disable();
		}
	}
	
	public function enable ( type : EventType ) : Void {
		var subscriptionsOfEvent = subscriptions.get( type.toString() );
		for( var registration in subscriptionsOfEvent ) {
			registration.enable();
		}
	}
}