PageRenderTime 79ms CodeModel.GetById 56ms app.highlight 14ms RepoModel.GetById 0ms app.codeStats 1ms

/SharedSlidesMobile/src/com/jxl/sharedslides/rl/models/NetworkModel.as

https://github.com/JesterXL/SharedSlideshow
ActionScript | 361 lines | 298 code | 54 blank | 9 comment | 29 complexity | 226a3a1ccbb81a4a3086703eb9110382 MD5 | raw file
  1package com.jxl.sharedslides.rl.models
  2{
  3	import com.adobe.crypto.MD5;
  4	import com.jxl.sharedslides.events.model.NetworkModelEvent;
  5	import com.jxl.shareslides.vo.SlideshowVO;
  6	import com.projectcocoon.p2p.LocalNetworkDiscovery;
  7	import com.projectcocoon.p2p.events.ClientEvent;
  8	import com.projectcocoon.p2p.events.GroupEvent;
  9	import com.projectcocoon.p2p.events.MessageEvent;
 10	import com.projectcocoon.p2p.events.ObjectEvent;
 11	import com.projectcocoon.p2p.vo.ObjectMetadataVO;
 12	
 13	import flash.events.Event;
 14	import flash.utils.ByteArray;
 15	import flash.utils.getTimer;
 16	
 17	import mx.collections.ArrayCollection;
 18	
 19	import org.robotlegs.mvcs.Actor;
 20	
 21	public class NetworkModel extends Actor
 22	{
 23		
 24		[Inject]
 25		public var localNetworkDiscovery:LocalNetworkDiscovery;
 26		
 27		private var _connected:Boolean = false;
 28		private var _currentSlide:int = 0;
 29		private var awaitingSlideshows:Object = {};
 30		
 31		public function get connected():Boolean { return _connected; }
 32		public function set connected(value:Boolean):void
 33		{
 34			_connected = value;
 35			if(_connected)
 36			{
 37				dispatch(new NetworkModelEvent(NetworkModelEvent.GROUP_CONNECTED));
 38			}
 39			else
 40			{
 41				dispatch(new NetworkModelEvent(NetworkModelEvent.GROUP_DISCONNECTED));
 42			}
 43		}
 44		
 45		public function get currentSlide():int { return _currentSlide; }
 46		public function set currentSlide(value:int):void
 47		{
 48			if(value !== _currentSlide)
 49			{
 50				_currentSlide = value;
 51				dispatch(new NetworkModelEvent(NetworkModelEvent.HOST_CURRENT_SLIDE_INDEX_CHANGED));
 52			}
 53		}
 54		
 55		[Bindable(event="clientsChange")]
 56		public function get clients():ArrayCollection { return localNetworkDiscovery.clients; }
 57		
 58		[Bindable(event="sharedObjectsChange")]
 59		public function get sharedObjects():ArrayCollection { return localNetworkDiscovery.sharedObjects; }
 60		
 61		[Bindable(event="receivedObjectsChange")]
 62		public function get receivedObjects():ArrayCollection { return localNetworkDiscovery.receivedObjects; }
 63		
 64		public var currentSlideshowHash:String;
 65		
 66		/*
 67		[Bindable(event="nearIDChanged")]
 68		public function get nearID():String { return localNetworkDiscovery.connection.nearID; }
 69		*/
 70		
 71		public function NetworkModel()
 72		{
 73			super();
 74		}
 75		
 76		[PostConstruct]
 77		public function connect():void
 78		{
 79			Debug.log("NetworkModel::init");
 80			
 81			localNetworkDiscovery.loopback = false;
 82			localNetworkDiscovery.groupName = "com.jxl.shareslides";
 83			localNetworkDiscovery.addEventListener(GroupEvent.GROUP_CONNECTED, onGroupConnected);
 84			localNetworkDiscovery.addEventListener(GroupEvent.GROUP_CLOSED, onGroupClosed);
 85			localNetworkDiscovery.addEventListener(ObjectEvent.OBJECT_ANNOUNCED, onObjectAnnounced);
 86			localNetworkDiscovery.addEventListener(ObjectEvent.OBJECT_PROGRESS, onObjectProgress);
 87			localNetworkDiscovery.addEventListener(ObjectEvent.OBJECT_COMPLETE, onObjectComplete);
 88			localNetworkDiscovery.addEventListener("sharedObjectsChange", onSharedObjectsChanged);
 89			//localNetworkDiscovery.addEventListener("receivedObjectsChange", onReceivedObjectsChanged);
 90			//localNetworkDiscovery.addEventListener("clientsConnectedChange", onClientsConnectedChanged);
 91			//localNetworkDiscovery.addEventListener("clientsChange", onClientsChanged);
 92			localNetworkDiscovery.addEventListener(ClientEvent.CLIENT_ADDED, onClientAdded);
 93			localNetworkDiscovery.addEventListener(ClientEvent.CLIENT_UPDATE, onClientUpdate);
 94			localNetworkDiscovery.addEventListener(ClientEvent.CLIENT_REMOVED, onClientRemoved);
 95			localNetworkDiscovery.addEventListener(MessageEvent.DATA_RECEIVED, onMessageEvent);
 96			
 97			if(localNetworkDiscovery.clientName == "" || localNetworkDiscovery.clientName == null)
 98				localNetworkDiscovery.clientName = "Default User";
 99			
100			Debug.log("NetworkModel::connect");
101			localNetworkDiscovery.connect();
102		}
103		
104		public function changeName(name:String):void
105		{
106			if(localNetworkDiscovery.clientName != name)
107				localNetworkDiscovery.clientName = name;
108		}
109		
110		public function shareSlideshow(slideshow:SlideshowVO):void
111		{
112			slideshow.updateHashIfNeeded();
113			localNetworkDiscovery.shareWithAll(slideshow, {name: slideshow.name, hash: slideshow.hash});
114		}
115		
116		public function setHostCurrentIndex(slideshowHash:String, index:int):void
117		{
118			localNetworkDiscovery.sendMessageToAll({message: "setCurrentSlide", currentSlide: index, slideshowHash: slideshowHash});
119		}
120		
121		private function onGroupConnected(event:GroupEvent):void
122		{
123			Debug.info("NetworkModel::onGroupConnected");
124			connected = true;
125			Debug.info("localNetworkDiscovery.clientName: " + localNetworkDiscovery.clientName + ", nearID: " + localNetworkDiscovery.connection.nearID);
126			
127		}
128		
129		private function onGroupClosed(event:GroupEvent):void
130		{
131			Debug.info("NetworkModel::onGroupClosed");
132			connected = false;
133		}
134		
135		private function onObjectAnnounced(event:ObjectEvent):void
136		{
137			Debug.info("NetworkModel::onObjectAnnounced, hash: " + event.metadata.info.hash);
138			if(awaitingSlideshows[event.metadata.info.hash] != null)
139			{
140				Debug.info("I was awaiting this slideshow, thank you, requesting...");
141				delete awaitingSlideshows[event.metadata.info.hash];
142				localNetworkDiscovery.requestObject(event.metadata);
143			}
144			else
145			{
146				// verify I don't have it
147				var len:int = localNetworkDiscovery.receivedObjects.length;
148				var om:ObjectMetadataVO;
149				var slideshow:SlideshowVO;
150				while(len--)
151				{
152					om = localNetworkDiscovery.receivedObjects[len];
153					if(om.info.hash == event.metadata.info.hash)
154					{
155						Debug.info("Thanks, I already have this slideshow in received.");
156						return;
157					}
158				}
159				
160				len = localNetworkDiscovery.sharedObjects.length;
161				while(len--)
162				{
163					om = localNetworkDiscovery.sharedObjects[len];
164					if(om.info.hash == event.metadata.info.hash)
165					{
166						Debug.info("Thanks, I already have this slideshow, I'm hosting it.");
167						return;
168					}
169				}
170				
171				Debug.info("I have no record of requesting this, so thanks, requesting it now!");
172				localNetworkDiscovery.requestObject(event.metadata);
173			}
174		}
175		
176		private function onObjectProgress(event:ObjectEvent):void
177		{
178			localNetworkDiscovery.receivedObjects.refresh();
179		}
180		
181		private function onObjectComplete(event:ObjectEvent):void
182		{
183			Debug.debug("NetworkModel::onObjectComplete");
184			// [jwarden 12.30.2011] HACK: My hashes aren't matching up... whether MD5 or SHA256.
185			Debug.debug("hash on info: "+ event.metadata.info.hash);
186			var slideshow:SlideshowVO = event.metadata.object as SlideshowVO;
187			slideshow.hash = event.metadata.info.hash;
188			localNetworkDiscovery.receivedObjects.refresh();
189		}
190		
191		private function onSharedObjectsChanged(event:Event):void
192		{
193			Debug.info("NetworkModel::onSharedObjectsChanged");
194			dispatch(new Event("sharedObjectsChange"));
195		}
196		
197		private function onClientAdded(event:ClientEvent):void
198		{
199			Debug.info("NetworkModel::onClientAdded, event.client.clientName: " + event.client.clientName);
200			if(event.client.isLocal)
201				return;
202			
203			var hash:Object = {};
204			var len:int = localNetworkDiscovery.receivedObjects.length;
205			var om:ObjectMetadataVO;
206			var slideshow:SlideshowVO;
207			while(len--)
208			{
209				om = localNetworkDiscovery.receivedObjects[len];
210				hash[om.info.hash] = om.info.hash;
211			}
212			
213			len = localNetworkDiscovery.sharedObjects.length;
214			while(len--)
215			{
216				om = localNetworkDiscovery.sharedObjects[len];
217				hash[om.info.hash] = om.info.hash;
218			}
219			
220			var hashes:Array = [];
221			for(var prop:String in hash)
222			{
223				hashes.push(prop);
224			}
225			
226			localNetworkDiscovery.sendMessageToClient({message: "doYouNeedSlideshow", hashes: hashes}, event.client.groupID);
227			
228			dispatch(new Event("clientAdded"));
229		}
230		
231		private function onClientUpdate(event:ClientEvent):void
232		{
233			Debug.info("NetworkModel::onClientUpdate, clientName:  " + event.client.clientName);
234			if(event.client.isLocal)
235				return;
236			
237			dispatch(new Event("clientUpdate"));
238		}
239		
240		private function onClientRemoved(event:ClientEvent):void
241		{
242			Debug.info("NetworkModel::onClientRemoved, clientName:  " + event.client.clientName);
243			if(event.client.isLocal)
244				return;
245			
246			dispatch(new Event("clientRemoved"));
247		}
248		
249		private function onMessageEvent(event:MessageEvent):void
250		{
251			Debug.info("NetworkModel::onMessageEvent");
252			if(event.message.data)
253				Debug.info("\tmessage: " + event.message.data.message);
254			
255			var networkModelEvent:NetworkModelEvent;
256			switch(event.message.data.message)
257			{
258				case "setCurrentSlide":
259					Debug.info("currentSlideshowHash: " + currentSlideshowHash);
260					Debug.info("event.message.data.slideshowHash: " + event.message.data.slideshowHash);
261					if(currentSlideshowHash == event.message.data.slideshowHash)
262						currentSlide = event.message.data.currentSlide;
263					break;
264				
265				case "doYouNeedSlideshow":
266					onVerifyIfINeedSlideshows(event);
267					break;
268				
269				case "doYouNeedSlideshowAck":
270					onSendNeededSlideshows(event);
271					break;
272				
273				
274			}
275		}
276		
277		private function onVerifyIfINeedSlideshows(messageEvent:MessageEvent):void
278		{
279			var hashes:Array = messageEvent.message.data.hashes as Array;
280			var missing:Array = [];
281			var len:int = hashes.length;
282			var hashObject:Object = {};
283			while(len--)
284			{
285				var hashString:String = hashes[len];
286				hashObject[hashString] = false;
287			}
288			
289			var om:ObjectMetadataVO;
290			var slideshow:SlideshowVO;
291			len = localNetworkDiscovery.receivedObjects.length;
292			while(len--)
293			{
294				om = localNetworkDiscovery.receivedObjects[len];
295				hashObject[om.info.hash] = true;
296			}
297			
298			len = localNetworkDiscovery.sharedObjects.length;
299			while(len--)
300			{
301				om = localNetworkDiscovery.sharedObjects[len];
302				slideshow = om.object as SlideshowVO;
303				slideshow.updateHashIfNeeded();
304				hashObject[slideshow.hash] = true;
305			}
306			
307			for(var prop:String in hashObject)
308			{
309				if(hashObject[prop] == false)
310				{
311					missing.push(prop);
312					awaitingSlideshows[prop] = prop;
313				}
314			}
315			
316			if(missing.length > 0)
317			{
318				localNetworkDiscovery.sendMessageToClient({message: "doYouNeedSlideshowAck", missing: missing}, messageEvent.message.client.groupID);
319			}
320		}
321		
322		private function onSendNeededSlideshows(event:MessageEvent):void
323		{
324			var missing:Array = event.message.data.missing as Array;
325			var missingHash:Object = {};
326			var len:int = missing.length;
327			var hash:String;
328			while(len--)
329			{
330				hash = missing[len] as String;
331				missingHash[hash] = true;
332			}
333			
334			len = localNetworkDiscovery.receivedObjects.length;
335			var om:ObjectMetadataVO;
336			var slideshow:SlideshowVO;
337			while(len--)
338			{
339				om = localNetworkDiscovery.receivedObjects[len];
340				slideshow = om.object as SlideshowVO;
341				if(missingHash[slideshow.hash] == true)
342				{
343					missingHash[slideshow.hash] = false;
344					localNetworkDiscovery.shareWithClient(slideshow, event.message.client.groupID, {name: slideshow.name, hash: slideshow.hash});
345				}
346			}
347			
348			len = localNetworkDiscovery.sharedObjects.length;
349			while(len--)
350			{
351				om = localNetworkDiscovery.sharedObjects[len];
352				slideshow = om.object as SlideshowVO;
353				if(missingHash[slideshow.hash] == true)
354				{
355					missingHash[slideshow.hash] = false;
356					localNetworkDiscovery.shareWithClient(slideshow, event.message.client.groupID, {name: slideshow.name, hash: slideshow.hash});
357				}
358			}
359		}
360	}
361}