The foreach
loop seems ridiculously lengthy and I am trying to get rid of it altogether is possible. But there are a lot of things happening in there which I need to know in order to update the UI and create other values. For examples, variables mappedRuntimeName
, mappedDeviceName
are used for updating the UI and also for creating the RuntimeDetails
object. The DownloadApplications
function also seems to have a lot of parameters.
Does anyone have any suggestions on how to improve the shown OnStartApplicationsCommand
function?
public bool? OnStartApplicationsCommand()
{
var runCommandSuccessful = true;
//get all the services for download begin
ResolveAndUpdateDependencies();
CancelOperationCommand = new AsyncDelegateCommand(StartApplicationsCommand.Cancel, () => !StartApplicationsCommand.CanExecute(null));
ProjectCommands.CancelOperation.RegisterCommand(CancelOperationCommand);
_eventAggregator.GetEvent<OutputWindowSourceChangedEvent>().Publish(OutputWindowSourceType.Run);
var activeConfiguration = _configurationService.GetActiveConfiguration();
// Message: >>>>>> Downloading and running applications...
PostOutputMessage(string.Format(ForteDownloadMessages.Default.download_level1_info,
_projectManagerService.GetProjectName(),
_configurationService.GetActiveConfiguration().Name),
OutputWindowMessageType.Info);
var count = 1; //application count
RuntimeDetails lastRuntimeDetails = null; //remember (for disconnecting) where the last application was downloaded to
DownloadedApplications.RemoveAll(application => true); //just remove all
foreach (var application in activeConfiguration.Applications)
{
if (StartApplicationsCommand.CancellationRequested)
{
ProjectCommands.CancelOperation.UnregisterCommand(CancelOperationCommand);
return null;
}
//retreive the fully qualified runtime name of the form deviceName.runtimeName from the application
var fullRuntimeName = application.MappedRuntimeName;
Debug.Assert(fullRuntimeName != string.Empty, "fullRuntimeName != string.Empty");
var mappedDeviceName = fullRuntimeName.Split('.').First();
var mappedRuntimeName = fullRuntimeName.Split('.').Last();
var matchedConfigurationDeviceModel = _configurationModelProvider.
GetConfigurationDeviceModelFromFullRuntimeName(fullRuntimeName);
var ipAddress = matchedConfigurationDeviceModel.IPAddress;
//retrieve the device model from the device service
var mappedDeviceModel =
_componentModelProvider.GetDeviceModelFromDeviceType(matchedConfigurationDeviceModel.Type);
//retrieve the mapped runtime from the device model
var matchedConfigurationRuntimeModel =
_configurationModelProvider.GetConfigurationRuntimeModelFromFullRuntimeName(fullRuntimeName);
var port = Convert.ToInt32(matchedConfigurationRuntimeModel.Port);
var runtimeDetails = new RuntimeDetails()
{
DeviceName = matchedConfigurationDeviceModel.Name,
Platform = mappedDeviceModel.Platform,
RuntimeType = matchedConfigurationRuntimeModel.Type,
RuntimeName = matchedConfigurationRuntimeModel.Name,
Ip = ipAddress,
Port = port
};
var applicationInstance = _componentModelProvider.GetApplicationModelFromApplicationType(application.Type);
//need to close connection when switching runtimes
//Do this before assigning the request executor so that disconnect is not skipped when runtimes
//are switched
if (lastRuntimeDetails != null) //at least one application was already downloaded
if (lastRuntimeDetails.Ip != runtimeDetails.Ip ||
lastRuntimeDetails.Port != runtimeDetails.Port)
_requestExecutor?.Disconnect();
Resource resourceInstance = null;
switch (matchedConfigurationRuntimeModel.Type)
{
case RuntimeType.FORTE:
resourceInstance = _resourceProvider.GetEmbeddedResource(application.Name + "_EMB_RES");
_requestExecutor = _forteRequestExecutor;
break;
case RuntimeType.FBRT:
resourceInstance = _resourceProvider.GetPanelResource(application.Name + "_PANEL_RESOURCE");
_requestExecutor = _fbrtRequestExecutor;
break;
case RuntimeType.FZRTE:
break;
default:
break;
}
var appSettings = application.Settings;
//Message: >>> Downloading application: ...
PostOutputMessage(string.Format(ForteDownloadMessages.Default.download_level2_info,
application.Name,
mappedDeviceName,
mappedRuntimeName,
resourceInstance?.Name ?? "default"),
OutputWindowMessageType.Info);
//first stop monitoring
Dependency.Resolve<IForteMonitoringService>().MonitoringOn = false;
//try { _requestExecutor.Disconnect(); } //without disconnect doesn't seem to work on rpi
//catch { /*swallow: no commhanlder present yet*/ };
var downloadSuccessful = DownloadApplication(application.Name, applicationInstance, appSettings,
matchedConfigurationRuntimeModel, resourceInstance, runtimeDetails);
//_requestExecutor.Disconnect();
lastRuntimeDetails = runtimeDetails;
if (downloadSuccessful == false)
runCommandSuccessful = false;
if (downloadSuccessful == null) //if cancellation requested return null and end
return null;
DownloadedApplications.Add(new DownloadedApplication()
{
Application = application,
Device = matchedConfigurationDeviceModel,
RuntimeDetails = runtimeDetails,
Resource = resourceInstance,
Running = (bool) downloadSuccessful
});
//publish application running event with applications that are running
_eventAggregator.GetEvent<RunningApplicationStatusChangedEvent>().Publish(DownloadedApplications);
count += 1; //application count
}
_requestExecutor?.Disconnect(); //disconnect from the last runtime
return runCommandSuccessful;
}
RuntimeDetails
class? Just to hold values? \$\endgroup\$DownloadApplication
function...for e.g. it is passed to the socket communication layer when a request is sent. \$\endgroup\$DownloadedApplications
have aClear
method? \$\endgroup\$