Skip to content

ModuleConnectionConfigurator breaking the infinite loop

Ondina D.F. edited this page Jul 26, 2013 · 3 revisions
//------------------------------------------------------------------------------
//  Copyright (c) 2009-2013 the original author or authors. All Rights Reserved. 
// 
//  NOTICE: You are permitted to use, modify, and distribute this file 
//  in accordance with the terms of the license agreement accompanying it. 
//------------------------------------------------------------------------------

package robotlegs.bender.extensions.modularity.impl
{
	import flash.events.IEventDispatcher;

	import robotlegs.bender.extensions.eventDispatcher.impl.EventRelay;
	import robotlegs.bender.extensions.modularity.dsl.IModuleConnectionAction;
	import robotlegs.bender.framework.api.IContext;

	/**
	 * @private
	 */
	public class ModuleConnectionConfigurator implements IModuleConnectionAction
	{

		/*============================================================================*/
		/* Private Properties                                                         */
		/*============================================================================*/

		//I'd rename _channelToLocalRelay.
		private var _channelToLocalRelay:EventRelay;

		private var _localToChannelRelay:EventRelay;

		private var _localDispatcher:IEventDispatcher;
		private var _channelDispatcher:IEventDispatcher;

		private var _types:Array;

		/*============================================================================*/
		/* Constructor                                                                */
		/*============================================================================*/

		/**
		 * @private
		 */
		public function ModuleConnectionConfigurator(localDispatcher:IEventDispatcher, channelDispatcher:IEventDispatcher)
		{
			_types = [];

			_localDispatcher = localDispatcher;
			_channelDispatcher = channelDispatcher;

			_localToChannelRelay = new EventRelay(localDispatcher, channelDispatcher).start();
			_channelToLocalRelay = new EventRelay(channelDispatcher, localDispatcher).start();
		}

		/*============================================================================*/
		/* Public Functions                                                           */
		/*============================================================================*/

		/**
		 * @inheritDoc
		 */
		public function relayEvent(eventType:String):IModuleConnectionAction
		{
			addInternalListeners(_localDispatcher, eventType);
			_localToChannelRelay.addType(eventType);
			return this;
		}

		/**
		 * @inheritDoc
		 */
		public function receiveEvent(eventType:String):IModuleConnectionAction
		{
			addInternalListeners(_channelDispatcher, eventType);
			_channelToLocalRelay.addType(eventType);
			return this;
		}

		//============================================================================
		// Adds event listeners to the dispatchers
		//============================================================================
		private function addInternalListeners(dispatcher:IEventDispatcher, type:String):void
		{
			_types.push(type);
			dispatcher.addEventListener(type, onEventDispatched);
		}

		//============================================================================
		// Removes the listeners 
		//============================================================================
		private function removeInternalListeners():void
		{
			for each (var type:String in _types)
			{
				_channelDispatcher.removeEventListener(type, onEventDispatched);
				_localDispatcher.removeEventListener(type, onEventDispatched);
			}
		}

		//============================================================================
		// After the _channelDispatcher dispatches an event, remove the listener from
		// the _localDispatcher, so it won't relay it again and again
		//============================================================================
		public function onEventDispatched(event:*):void
		{
			if (_channelDispatcher == event.target)
				_localToChannelRelay.removeType(event.type);
			else
				_localToChannelRelay.addType(event.type);
		}

		/*public function onEventDispatched(event:*):void
		{
			if (_channelDispatcher == event.target)
			{
				_localDispatcher.removeEventListener(event.type, _channelDispatcher.dispatchEvent);
			}
			else
			{
				_localDispatcher.addEventListener(event.type, _channelDispatcher.dispatchEvent);
			}
		}*/

		/**
		 * @inheritDoc
		 */
		public function suspend():void
		{
			_channelToLocalRelay.stop();
			_localToChannelRelay.stop();
		}

		/**
		 * @inheritDoc
		 */
		public function resume():void
		{
			_channelToLocalRelay.start();
			_localToChannelRelay.start();
		}

		/**
		 * @private
		 */
		public function destroy():void
		{
			removeInternalListeners();
			_channelDispatcher = null;
			_localDispatcher = null;
			_types = [];

			_localToChannelRelay.stop();
			_localToChannelRelay = null;
			_channelToLocalRelay.stop();
			_channelToLocalRelay = null;
		}
	}
}

Clone this wiki locally