open method

Future<MCPUIRuntime> open(
  1. DashboardBundleRef ref,
  2. List<String> deviceIds
)

FR-DASH-001

Implementation

Future<MCPUIRuntime> open(
  DashboardBundleRef ref,
  List<String> deviceIds,
) async {
  if (_currentRuntime != null) {
    await close();
  }

  final bundle = await _bundleLoader.load(
    ref,
    connectedDevices: deviceIds,
  );

  final runtimeHandle = _runtimeHandle(bundle.id);
  final runtime = _runtime.getOrCreateRuntime(runtimeHandle);
  if (!runtime.isInitialized) {
    await runtime.initialize(bundle.mainLayout);
  }

  final metadataByDevice = <String, Map<String, dynamic>>{};
  for (final id in deviceIds) {
    final config = await _storage.getById(id);
    if (config?.metadata != null) {
      metadataByDevice[id] = config!.metadata!;
    }
  }

  List<SlotBinding> bindings;
  try {
    bindings = _binder.bind(
      slots: bundle.slots,
      deviceIds: deviceIds,
      deviceMetadata: metadataByDevice,
    );
  } catch (e) {
    rethrow;
  }

  for (final binding in bindings) {
    try {
      await _mountSlot(runtime, bundle, binding);
    } on AppPlayerException catch (e) {
      _logger.warn('Slot mount failed', {
        'slotId': binding.slotId,
        'deviceId': binding.deviceId,
      }, e);
      runtime.stateManager.set('slot.${binding.slotId}.error',
          e.toString());
    }
  }

  _currentRuntime = runtime;
  _currentBundle = bundle;
  return runtime;
}