Newer
Older
exporter / Exporter.as
package
{
	import flash.display.*;
	import flash.net.*;
	import flash.events.*;
	import flash.desktop.*;
	import flash.errors.*;
	import flash.system.*;

	public class Exporter extends MovieClip
	{
		public static var Instance:Exporter = null;
		
		public static var DefaultPort:int = 7890;
		private var driver:Socket = null;
		public function Exporter()
		{
			Instance = this;
			
			try
			{
				NativeApplication.nativeApplication.addEventListener("invoke", ApplicationInvoked);
			}
			catch (e)
			{
				// not an air runtime app
				ConnectDriver(DefaultPort);	// try default port
			}
		}
		
		public function ApplicationInvoked(e)
		{
			if (e.arguments.length == 1)
			{
				ConnectDriver(parseInt(e.arguments[0]));
			}
			else
			{
				ConnectDriver(DefaultPort);
			}
		}
		
		private function ConnectDriver(port)
		{
			Trace("Attempting to connect to driver");
			try
			{
				var s:Socket = new Socket();
				s.addEventListener(IOErrorEvent.IO_ERROR, DriverError);
				s.addEventListener(Event.CONNECT, DriverConnected);
				s.connect("localhost", port);
			}
			catch (e)
			{
				Trace("Error establishing wrapper connection");
			}
		}
		
		private function DriverError(e)
		{
			Trace("  Failed to connect");
		}
		
		private function DriverConnected(e)
		{
			Trace("  Connected");
			driver = e.target as Socket;
			driver.addEventListener(ProgressEvent.SOCKET_DATA, DriverRecv);
		}
		
		private function Quit()
		{
			fscommand("quit");
			try
			{
				NativeApplication.nativeApplication.exit();
			} catch (e)
			{
				
			}
		}

		private var jobQueue:Array = new Array();
		private var activeJob:Job = null;
		private function QueueJob(jobParams)
		{
			var job:Job = new Job(jobParams);
			jobQueue.push(job);
			CheckNewJob();
		}
		
		private function CheckNewJob()
		{
			if (activeJob == null && jobQueue.length > 0)
			{
				activeJob = jobQueue.shift();
				activeJob.Go(JobComplete);
			}
		}
		
		private function JobComplete()
		{
			Trace("Done: " + activeJob.GetID());
			DriverCommand("done", activeJob.GetCompletedData());
			
			activeJob = null;
			CheckNewJob();
		}
		
		private function DispatchCommand(cmdData)
		{
			try
			{
				Trace("recv: " + typeof(cmdData) + " " + cmdData + " " + cmdData.hasOwnProperty("command"));
				if (cmdData.hasOwnProperty("command"))
				{
					var cmd = "" + cmdData.command;
					Trace("cmd: " + cmd);
					switch (cmd)
					{
						case "trace":
							Trace(cmdData.string);
						break;
						case "exit":
							Quit();
						break;
						case "job":
							QueueJob(cmdData);
						break;
						default:
							Trace("Recv: " + JSON.stringify(cmdData));
						break;
					}
				}
			} catch (e)
			{
				Print(e.toString());
			}
		}
		
		private function DriverRecv(e)
		{
			Trace("recv");
			try
			{
				Trace(e.target.bytesAvailable);
				var msg = driver.readUTF();
				Trace("msg: " + msg);
				Trace("avail: " + e.target.bytesAvailable);
				var cmdData = JSON.parse(msg);
				Trace("cmdData: " + cmdData + " " + typeof(cmdData));
				DispatchCommand(cmdData);
			}
			catch (eof:EOFError)
			{
				Trace("Waiting for more data... " + e.target.bytesAvailable);
				// wait for more data
			}
			catch (err:IOError)
			{
				Trace("Driver IO error");
			}
			catch (err)
			{
				Trace("Problem reading from driver");
			}
		}
		
		private function DriverCommand(cmd:String, data = null)
		{
			var obj = {command:cmd};
			if (data != null)
			{
				for (var k in data)
				{
					obj[k] = data[k];
				}
			}
			DriverSend(JSON.stringify(obj));
		}
		
		private function DriverSend(str:String)
		{
			if (driver != null)
			{
				Trace(str);
				driver.writeUTF(str);
				driver.flush();
			}
		}
		
		public function Trace(str:String)
		{
			traceText.x = 2;

			trace(str);
			traceText.width = stage.stageWidth - 4;
			traceText.height = stage.stageHeight - 4;
			if (traceText.text == "")
			{
				traceText.text = str;
			}
			else
			{
				traceText.appendText("\n" + str);
			}
			traceText.y = stage.height - traceText.textHeight - 2;
		}
		
		public function Print(str:String, localTrace:Boolean = true)
		{
			if (localTrace || driver == null)
			{
				Trace(str);
			}
			else
			{
				trace(str);
			}
			if (driver != null)
			{
				DriverCommand("print", {string:str});
			}
		}
	}
}