From df4dfb0ba4605704749da646f602829be40ae51f Mon Sep 17 00:00:00 2001 From: skalogryz Date: Mon, 7 Dec 2015 04:04:01 +0000 Subject: [PATCH] iphonelazext: changing run simulator to apples instruments utility. Updated the frames to use resources files, instead of the old include files git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4401 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../environment_iphone_options.lfm | 127 ++++++++++----- .../environment_iphone_options.pas | 36 ++++- components/iphonelazext/ideext.pas | 27 +++- components/iphonelazext/iphoneextoptions.pas | 48 +++++- components/iphonelazext/iphonesimctrl.pas | 151 ++++++++++++++++++ .../iphonelazext/project_iphone_options.pas | 4 +- components/iphonelazext/tests/testlaunch.lpi | 76 +++++++++ components/iphonelazext/tests/testlaunch.lpr | 88 ++++++++++ 8 files changed, 507 insertions(+), 50 deletions(-) create mode 100644 components/iphonelazext/iphonesimctrl.pas create mode 100644 components/iphonelazext/tests/testlaunch.lpi create mode 100644 components/iphonelazext/tests/testlaunch.lpr diff --git a/components/iphonelazext/environment_iphone_options.lfm b/components/iphonelazext/environment_iphone_options.lfm index 613e95fdf..91986b5e0 100644 --- a/components/iphonelazext/environment_iphone_options.lfm +++ b/components/iphonelazext/environment_iphone_options.lfm @@ -1,27 +1,30 @@ -inherited iPhoneSpecificOptions: TiPhoneSpecificOptions +object iPhoneSpecificOptions: TiPhoneSpecificOptions + Left = 0 Height = 473 + Top = 0 Width = 487 ClientHeight = 473 ClientWidth = 487 - DesignLeft = 567 - DesignTop = 313 - object lblRTLUtils: TLabel[0] + TabOrder = 0 + DesignLeft = 373 + DesignTop = 176 + object lblRTLUtils: TLabel Left = 16 - Height = 18 + Height = 16 Top = 184 - Width = 92 + Width = 91 Caption = 'RTL units path' ParentColor = False end - object lblCompilerPath: TLabel[1] + object lblCompilerPath: TLabel Left = 16 - Height = 18 + Height = 16 Top = 152 - Width = 55 + Width = 57 Caption = 'Compiler' ParentColor = False end - object edtCompilerPath: TEdit[2] + object edtCompilerPath: TEdit Left = 136 Height = 22 Top = 152 @@ -30,16 +33,16 @@ inherited iPhoneSpecificOptions: TiPhoneSpecificOptions TabOrder = 0 Text = 'edtCompilerPath' end - object lblXCodeProject: TLabel[3] + object lblXCodeProject: TLabel Left = 16 - Height = 18 + Height = 16 Top = 128 - Width = 394 + Width = 389 Caption = 'Specific ARM compiler settings (for generated Xcode projects)' ParentColor = False ParentFont = False end - object edtRTLPath: TEdit[4] + object edtRTLPath: TEdit Left = 136 Height = 22 Top = 184 @@ -48,7 +51,7 @@ inherited iPhoneSpecificOptions: TiPhoneSpecificOptions TabOrder = 1 Text = 'edtRTLPath' end - object edtCompilerOptions: TEdit[5] + object edtCompilerOptions: TEdit Left = 136 Height = 22 Top = 216 @@ -58,26 +61,26 @@ inherited iPhoneSpecificOptions: TiPhoneSpecificOptions TabOrder = 2 Text = 'edtCompilerOptions' end - object lblCmpOptions: TLabel[6] + object lblCmpOptions: TLabel Left = 16 - Height = 18 + Height = 16 Top = 216 - Width = 106 + Width = 109 Caption = 'Compiler options' ParentColor = False ParentFont = False OnClick = lblCmpOptionsClick end - object Label5: TLabel[7] + object Label5: TLabel Left = 16 - Height = 18 + Height = 16 Top = 16 - Width = 97 + Width = 96 Caption = 'Platforms path:' ParentColor = False ParentFont = False end - object edtPlatformsPath: TEdit[8] + object edtPlatformsPath: TEdit Left = 125 Height = 22 Top = 16 @@ -86,67 +89,67 @@ inherited iPhoneSpecificOptions: TiPhoneSpecificOptions TabOrder = 3 Text = 'edtPlatformsPath' end - object lblSimSettings: TLabel[9] + object lblSimSettings: TLabel Left = 16 - Height = 18 + Height = 16 Top = 256 Width = 161 Caption = 'iPhone Simulator settings' ParentColor = False end - object edtSimBundle: TEdit[10] + object edtSimBundle: TEdit Left = 160 Height = 22 - Top = 286 + Top = 360 Width = 306 Anchors = [akTop, akLeft, akRight] TabOrder = 4 Text = 'edtSimBundle' end - object edtSimApps: TEdit[11] + object edtSimApps: TEdit Left = 160 Height = 22 - Top = 318 + Top = 392 Width = 306 Anchors = [akTop, akLeft, akRight] TabOrder = 5 Text = 'edtSimApps' end - object lblSimBundle: TLabel[12] + object lblSimBundle: TLabel Left = 16 - Height = 18 - Top = 287 - Width = 111 + Height = 16 + Top = 361 + Width = 113 Caption = 'iPhoneSim bundle' ParentColor = False end - object lblSimAppPath: TLabel[13] + object lblSimAppPath: TLabel Left = 16 - Height = 18 - Top = 318 - Width = 141 + Height = 16 + Top = 392 + Width = 142 Caption = 'Sim Applications path:' ParentColor = False end - object Button1: TButton[14] + object Button1: TButton Left = 16 Height = 20 Top = 56 - Width = 112 + Width = 115 AutoSize = True Caption = 'Scan for SDKs' OnClick = Button1Click TabOrder = 6 end - object Label1: TLabel[15] + object Label1: TLabel Left = 16 - Height = 18 + Height = 16 Top = 88 Width = 129 Caption = 'Default SDK version:' ParentColor = False end - object cmbDefaultSDK: TComboBox[16] + object cmbDefaultSDK: TComboBox Left = 152 Height = 20 Top = 88 @@ -155,4 +158,46 @@ inherited iPhoneSpecificOptions: TiPhoneSpecificOptions Style = csDropDownList TabOrder = 7 end + object ddPhoneSimType: TComboBox + Left = 160 + Height = 20 + Top = 288 + Width = 304 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 0 + ItemIndex = 0 + Items.Strings = ( + 'Simulator via instruments' + ) + Style = csDropDownList + TabOrder = 8 + Text = 'Simulator via instruments' + end + object lblSimType: TLabel + Left = 16 + Height = 16 + Top = 288 + Width = 95 + Caption = 'Simulator Type' + ParentColor = False + OnClick = lblSimTypeClick + end + object lblDefaultDevice: TLabel + Left = 16 + Height = 16 + Top = 323 + Width = 118 + Caption = 'Default Sim Device' + ParentColor = False + end + object ddSimDevice: TComboBox + Left = 160 + Height = 20 + Top = 323 + Width = 306 + Anchors = [akTop, akLeft, akRight] + ItemHeight = 0 + Style = csDropDownList + TabOrder = 9 + end end diff --git a/components/iphonelazext/environment_iphone_options.pas b/components/iphonelazext/environment_iphone_options.pas index ba256d80b..a7c049fab 100644 --- a/components/iphonelazext/environment_iphone_options.pas +++ b/components/iphonelazext/environment_iphone_options.pas @@ -21,7 +21,7 @@ interface uses Classes, SysUtils, FileUtil, LResources, Forms, StdCtrls, IDEOptionsIntf, ProjectIntf, - iPhoneExtOptions; + iPhoneExtOptions, iphonesimctrl; type @@ -30,6 +30,8 @@ type TiPhoneSpecificOptions = class(TAbstractIDEOptionsEditor) Button1: TButton; cmbDefaultSDK: TComboBox; + ddSimDevice: TComboBox; + ddPhoneSimType: TComboBox; edtCompilerPath: TEdit; edtRTLPath: TEdit; edtCompilerOptions: TEdit; @@ -37,6 +39,8 @@ type edtSimBundle: TEdit; edtSimApps: TEdit; Label1: TLabel; + lblDefaultDevice: TLabel; + lblSimType: TLabel; lblRTLUtils: TLabel; lblSimAppPath: TLabel; lblCompilerPath: TLabel; @@ -47,6 +51,7 @@ type lblSimBundle: TLabel; procedure Button1Click(Sender: TObject); procedure edtCompilerOptionsChange(Sender: TObject); + procedure lblSimTypeClick(Sender: TObject); procedure lblCmpOptionsClick(Sender: TObject); private { private declarations } @@ -61,6 +66,8 @@ type implementation +{$R *.lfm} + { TiPhoneSpecificOptions } procedure TiPhoneSpecificOptions.lblCmpOptionsClick(Sender: TObject); @@ -88,6 +95,11 @@ begin end; +procedure TiPhoneSpecificOptions.lblSimTypeClick(Sender: TObject); +begin + +end; + function TiPhoneSpecificOptions.GetTitle: String; begin Result:='Files'; @@ -101,6 +113,10 @@ end; procedure TiPhoneSpecificOptions.ReadSettings(AOptions: TAbstractIDEOptions); var opt : TiPhoneEnvironmentOptions; + idx : integer; + i : integer; + j : integer; + sd : TSimDevice; begin if not Assigned(AOptions) or not (AOptions is TiPhoneEnvironmentOptions) then Exit; opt:=TiPhoneEnvironmentOptions(AOptions); @@ -116,6 +132,21 @@ begin cmbDefaultSDK.Items.Clear; opt.GetSDKVersions(cmbDefaultSDK.Items); cmbDefaultSDK.ItemIndex:=cmbDefaultSDK.Items.IndexOf(opt.DefaultSDK); + + if EnvOptions.DeviceCount=0 then + EnvOptions.DeviceListReload; + idx:=-1; + ddSimDevice.Clear; + for i:=0 to EnvOptions.DeviceCount-1 do begin + sd:=EnvOptions.Device[i]; + if sd.isavail then begin + j:=ddSimDevice.Items.Add( sd.name ); + ddSimDevice.Items.Objects[j]:=sd; + if sd.id=EnvOptions.DefaultDeviceID then + idx:=j; + end; + end; + if idx>=0 then ddSimDevice.ItemIndex:=idx; end; procedure TiPhoneSpecificOptions.WriteSettings(AOptions: TAbstractIDEOptions); @@ -132,6 +163,8 @@ begin opt.SimBundle:=edtSimBundle.Text; opt.SimAppsPath:=edtSimApps.Text; + if ddSimDevice.ItemIndex>=0 then + opt.DefaultDeviceID:=TSimDevice(ddSimDevice.Items.Objects[ddSimDevice.ItemIndex]).id; opt.Save; end; @@ -141,7 +174,6 @@ begin end; initialization - {$I environment_iphone_options.lrs} RegisterIDEOptionsEditor(iPhoneEnvGroup, TiPhoneSpecificOptions, iPhoneEnvGroup+1); end. diff --git a/components/iphonelazext/ideext.pas b/components/iphonelazext/ideext.pas index c790cbfbf..f93e1e297 100644 --- a/components/iphonelazext/ideext.pas +++ b/components/iphonelazext/ideext.pas @@ -27,7 +27,7 @@ uses project_iphone_options, xcodetemplate, - iPhoneExtOptions, iPhoneExtStr, iPhoneBundle, lazfilesutils; + iPhoneExtOptions, iPhoneExtStr, iPhoneBundle, lazfilesutils, iphonesimctrl; procedure Register; @@ -456,14 +456,13 @@ begin IDEMessagesWindow.AddMsg(strXcodeUpdated, '', 0); end; -procedure TiPhoneExtension.SimRun(Sender: TObject); +procedure SimRunDirect; var t : TProcess; path : String; begin t :=TProcess.Create(nil); try - //ProjectBuilding(nil); path:=IncludeTrailingPathDelimiter(EnvOptions.SimBundle)+'Contents/MacOS/iPhone Simulator'; EnvOptions.SubstituteMacros(path); t.CommandLine:='"'+path+'"'; @@ -476,6 +475,28 @@ begin t.Free; end; +function SimRunInstruct(var err: string): Boolean; +begin + if EnvOptions.DefaultDeviceID='' then begin + err:='Device type is not specified'; + Result:=false; + Exit; + end; + Result:=true; + iphonesimctrl.RunSim( EnvOptions.DefaultDeviceID ); +end; + +procedure TiPhoneExtension.SimRun(Sender: TObject); +var + err : string; +begin + if not SimRunInstruct(err) then begin + ShowMessage('Unable to run Simulator. '+err); + Exit; + end; +end; + + {procedure TiPhoneExtension.isProjectClicked(Sender: TObject); begin if not Assigned(Sender) or not Assigned(LazarusIDE.ActiveProject) then Exit; diff --git a/components/iphonelazext/iphoneextoptions.pas b/components/iphonelazext/iphoneextoptions.pas index 360966ae3..06b99aa0a 100644 --- a/components/iphonelazext/iphoneextoptions.pas +++ b/components/iphonelazext/iphoneextoptions.pas @@ -21,7 +21,7 @@ interface uses Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, MacroIntf, - iPhoneBundle, DOM, XMLRead, XMLConf, XcodeUtils, FileUtil; + iPhoneBundle, XMLConf, XcodeUtils, FileUtil, iphonesimctrl; const DefaultResourceDir = 'Resources'; @@ -75,8 +75,13 @@ type fSimAppsPath : String; fSimBundle : String; fDefaultSDK : String; + fDefaultSimType : String; + fDefaultDeviceID : String; - fVersions : TStringList; + fVersions : TStringList; + fDeviceList : TList; + function GetDevice(i: integer): TSimDevice; + function GetDeviceCount: Integer; protected function XMLFileName: String; @@ -100,6 +105,9 @@ type procedure GetSDKVersions(Strings: TStrings); procedure RefreshVersions; + procedure DeviceListClear; + procedure DeviceListReload; + property PlatformsBaseDir: String read fPlatformsBaseDir write fPlatformsBaseDir; property CompilerPath: String read fCompilerPath write fCompilerPath; property BaseRTLPath: String read fBaseRTLPath write fBaseRTLPath; @@ -109,6 +117,12 @@ type property SimAppsPath: String read fSimAppsPath write fSimAppsPath; property DefaultSDK: String read fDefaultSDK write fDefaultSDK; + + property DefaultSimType: String read fDefaultSimType write fDefaultSimType; // it's currently Simulator via instruments + property DefaultDeviceID: String read fDefaultDeviceID write fDefaultDeviceID; + + property DeviceCount: Integer read GetDeviceCount; + property Device[i: integer]: TSimDevice read GetDevice; end; function EnvOptions: TiPhoneEnvironmentOptions; @@ -175,6 +189,17 @@ begin Result:=EnvOptions; end; +function TiPhoneEnvironmentOptions.GetDevice(i: integer): TSimDevice; +begin + if (i<0) and (i>=fDeviceList.Count) then Result:=nil + else Result:=TSimDevice(fDeviceList[i]); +end; + +function TiPhoneEnvironmentOptions.GetDeviceCount: Integer; +begin + Result:=fDeviceList.Count; +end; + function TiPhoneEnvironmentOptions.XMLFileName: String; begin Result:=IncludeTrailingPathDelimiter(LazarusIDE.GetPrimaryConfigPath)+DefaultXMLName; @@ -240,12 +265,15 @@ begin fSimBundle := GetDefaultSimBundlePath; fCompilerPath := '/usr/local/bin/fpc'; fVersions:=TStringList.Create; + fDeviceList:=TList.Create; end; destructor TiPhoneEnvironmentOptions.Destroy; begin ClearVersionsInfo; fVersions.Free; + DeviceListClear; + fDeviceList.Free; inherited Destroy; end; @@ -267,6 +295,7 @@ begin fSimBundle := UTF8Encode(xmlcfg.GetValue('SimBundle', fSimBundle)); fSimAppsPath := UTF8Encode(xmlcfg.GetValue('SimAppPath', fSimAppsPath)); fDefaultSDK := UTF8Encode(xmlcfg.GetValue('DefaultSDK', fDefaultSDK)); + fDefaultDeviceID := UTF8Encode(xmlcfg.GetValue('DefaultDevice', fDefaultDeviceID)); RefreshVersions; if (fDefaultSDK = '') and (fVersions.Count>0) then @@ -296,6 +325,7 @@ begin xmlcfg.SetValue('SimBundle', UTF8Decode(fSimBundle)); xmlcfg.SetValue('SimAppPath', UTF8Decode(fSimAppsPath)); xmlcfg.SetValue('DefaultSDK', UTF8Decode(fDefaultSDK)); + xmlcfg.SetValue('DefaultDevice', UTF8Decode(fDefaultDeviceID)); finally xmlcfg.Free; end; @@ -350,6 +380,20 @@ begin ScanForSDK(EnvOptions.PlatformsBaseDir, @FoundSDK); end; +procedure TiPhoneEnvironmentOptions.DeviceListClear; +var + i : integer; +begin + for i:=0 to fDeviceList.Count-1 do + TObject(fDeviceList[i]).Free; + fDeviceList.Clear; +end; + +procedure TiPhoneEnvironmentOptions.DeviceListReload; +begin + ListDevice(fDeviceList); +end; + { TiPhoneProjectOptions } procedure TiPhoneProjectOptions.Reset; diff --git a/components/iphonelazext/iphonesimctrl.pas b/components/iphonelazext/iphonesimctrl.pas new file mode 100644 index 000000000..639748347 --- /dev/null +++ b/components/iphonelazext/iphonesimctrl.pas @@ -0,0 +1,151 @@ +unit iphonesimctrl; + +{$mode delphi} + +interface + +uses + Classes, SysUtils, process + , jsonparser, fpjson + {$ifdef unix}, BaseUnix{$endif} // for StopProc() + ; + +procedure RunSim(const SimName: string); +function RunAppOnSim(const AppID, DeviceID: string; WaitDebugger: Boolean; var pid: Integer; var outstr: string): Boolean; +procedure StopProc(pid: Integer); + +type + TSimDevice = class(TObject) + public + sdk : string; + state : string; + isavail : Boolean; + name : string; + id : string; + end; + +function ListDevice(lst: TList): Boolean; + +implementation + +procedure RunSim(const SimName: string); +var + outstr: string; +begin + outstr:=''; + RunCommand('xcrun', ['instruments', '-w' ,SimName], outstr); +end; + +function RunAppOnSim(const AppID, DeviceID: string; WaitDebugger: Boolean; var pid: Integer; var outstr: string): Boolean; +var + devid: string; + err : Integer; + i : Integer; + j : Integer; +begin + if DeviceID='' then devid:='booted' + else devid:=DeviceID; + + if WaitDebugger then + Result:=RunCommand('xcrun', ['simctl', 'launch', '-w', devid, AppID], outstr) + else + Result:=RunCommand('xcrun', ['simctl', 'launch', devid, AppID], outstr); + + if Result and (length(outstr)>0) then begin + i:=length(outstr); + // skipping white spaces, if any + while (i>0) and not (outstr[i] in ['0'..'9']) do dec(i); + + j:=i; + while (i>0) and (outstr[i] in ['0'..'9']) do dec(i); + Val( copy(outstr, i+1, j-i), pid, err); + writeln('err = ', err); + if err>0 then pid:=0; + end; +end; + +procedure StopProc(pid: Integer); +begin + {$ifdef unix} + FpKill(pid, SIGTERM); + {$endif} +end; + +function JSStr(v: TJSONData): string; +begin + if not Assigned(v) then Result:='' + else Result:=v.AsString; +end; + +function JsonToSimDev(oj: TJsonObject): TSimDevice; +begin + Result:=nil; + if not Assigned(oj) or (oj.JSONType<>jtObject) then Exit; + Result:=TSimDevice.Create; + Result.state:=JSStr(oj.Find('state')); + Result.isavail:=JSStr(oj.Find('availability'))='(available)'; + Result.name:=JSStr(oj.Find('name')); + Result.id:=JSStr(oj.Find('udid')); +end; + +procedure CollectDevices(list: TJSONArray; const asdk: string; dst: TList); +var + oj : TJSONObject; + i : Integer; + d : TSimDevice; +begin + for i:=0 to list.Count-1 do begin + oj:=TJSONObject(list.Items[i]); + d:=JsonToSimDev(oj); + d.sdk:=asdk; + if Assigned(d) then + dst.Add(d); + end; +end; + +function ListDevice(lst: TList): Boolean; +var + s : string; + j : TJSONParser; + dt : TJSONData; + d : TJSONObject; + v : TJSONData; + i : Integer; +begin + s:=''; + RunCommand('xcrun', ['simctl', 'list', 'devices', '-j'], s); + try + dt:=nil; + j:=TJSONParser.Create(s, []); + try + dt:=j.Parse; + finally + j.Free; + end; + + try + Result:=false; + if not Assigned(dt) or (dt.JSONType<>jtObject) or (dt.Count=0) then Exit; + v:=TJSONObject(dt).Find('devices'); + if not Assigned(v) or (v.JSONType<>jtObject) then Exit; + d:=TJSONObject(v); + + for i:=0 to d.Count-1 do begin + if Pos('iOS', d.Names[i])=1 then begin + if (d.items[i].JSONType=jtArray) then + CollectDevices( TJSONArray(d.Items[i]), d.Names[i], lst); + end; + end; + + finally + dt.Free; + end; + + except + on e:exception do + writeln('error: ', e.message); + end; +end; + +end. + diff --git a/components/iphonelazext/project_iphone_options.pas b/components/iphonelazext/project_iphone_options.pas index 71f429feb..245eb71f3 100644 --- a/components/iphonelazext/project_iphone_options.pas +++ b/components/iphonelazext/project_iphone_options.pas @@ -91,6 +91,8 @@ type implementation +{$R *.lfm} + { TiPhoneProjectOptionsEditor } procedure TiPhoneProjectOptionsEditor.cmbSDKsChange(Sender: TObject); @@ -568,8 +570,6 @@ const iPhoneOptions = 10000; //todo: get it dynamically initialization - {$I project_iphone_options.lrs} - writeln('registering iPhone proj editor'); //RegisterIDEOptionsEditor(iPhonePrjGroup, TiPhoneProjectOptionsEditor, iPhoneOptions); RegisterIDEOptionsEditor(GroupProject, TiPhoneProjectOptionsEditor, iPhoneOptions); diff --git a/components/iphonelazext/tests/testlaunch.lpi b/components/iphonelazext/tests/testlaunch.lpi new file mode 100644 index 000000000..0c5acc9bc --- /dev/null +++ b/components/iphonelazext/tests/testlaunch.lpi @@ -0,0 +1,76 @@ + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <Units Count="1"> + <Unit0> + <Filename Value="testlaunch.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="testlaunch"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <OtherUnitFiles Value=".."/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <SyntaxMode Value="Delphi"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/iphonelazext/tests/testlaunch.lpr b/components/iphonelazext/tests/testlaunch.lpr new file mode 100644 index 000000000..c5b6aa2dc --- /dev/null +++ b/components/iphonelazext/tests/testlaunch.lpr @@ -0,0 +1,88 @@ +program testlaunch; + +{$mode delphi}{$H+} + +uses + {$IFDEF UNIX}cthreads,{$ENDIF} + Classes, iphonesimctrl; + +procedure PrintList; +var + lst : TList; + i : integer; + dev : TSimDevice; +begin + lst := TList.Create; + try + ListDevice(lst); + for i:=0 to lst.Count-1 do begin + dev := TSimDevice(lst[i]); + writeln(dev.id,' ',dev.isavail,' ',dev.sdk,' ', dev.name,' ',dev.state); + end; + finally + lst.Free; + end; +end; + +procedure RunDevice(const nm: string); +begin + RunSim(nm); +end; + +procedure RunApp(const appid: string); +var + res : string; + pid : Integer; +begin + res:=''; + if not RunAppOnSim(appid, '', False, pid, res) then begin + writeln('failed to run app'); + end else begin + writeln('launching!'); + writeln('pid = ', pid); + writeln('outstr: '); + writeln(res); + end; +end; + +procedure PrintHelp; +begin + writeln('testlaunch %action% [%parameters%]'); + writeln('action:'); + writeln(' list - list devices'); + writeln(' run %deviceid% - runs a simulator with specified id'); + writeln(' runapp %appid% - runs an application on booted device'); +end; + +var + act : string = ''; + +procedure ParseParam; +begin + if ParamCount=0 then Exit; + act:=ParamStr(1); + act:=lowercase(act); +end; + +begin + if ParamCount=0 then begin + PrintHelp; + exit; + end; + ParseParam; + if act='list' then PrintList + else if act='run' then begin + if ParamCount=1 then begin + writeln('Please specify deviceid'); + Exit; + end; + RunDevice(ParamStr(2)); + end else if act='runapp' then begin + if ParamCount=1 then begin + writeln('Please specify application id to run'); + Exit; + end; + RunApp(ParamStr(2)); + end; +end. +