App constructor

App([
  1. AppConfig? config
])

Creates a new App instance.

  • config: Optional AppConfig to customize application behavior, such as the canvas element ID and graphics batch capacity. If null, default configuration is used.

The constructor initializes all core systems (graphics, input, audio, resources) and sets up the game loop. The onCreate method is called once initialization is complete.

Implementation

App([AppConfig? config]) {
  instance = this;

  _config = config ??= AppConfig();

  // Create platform backends via the conditional-import factory
  final factory = PlatformFactoryImpl();
  _windowBackend = factory.createWindow(_config);
  Platform.init(_windowBackend);

  loader = Loader();

  // Input backends
  final keyboardBackend = factory.createKeyboard(_windowBackend);
  final mouseBackend = factory.createMouse(_windowBackend);
  final gamepadBackend = factory.createGamepad();
  final accelBackend = factory.createAccelerometer();

  gamepad = Gamepad(gamepadBackend);
  keyboard = Keyboard(keyboardBackend);
  mouse = Mouse(mouseBackend);
  accel = Accelerometer(accelBackend, mouse, config.autoRequestAccelerometerPermission);

  // Audio backend
  final audioBackend = factory.createAudio();
  audio = Audio(audioBackend);

  // Renderer
  _renderer = factory.createRenderer(_windowBackend);
  _renderer.init();
  Texture.white = Texture.createWhite(_renderer);

  gfx = Graphics(
    _renderer,
    batchCapacityInBytes: _config.gfxBatchCapacityInBytes,
    width: _windowBackend.width,
    height: _windowBackend.height,
  );

  // Resource manager with all backends
  final imageLoader = factory.createImageLoader();
  final fileLoader = factory.createFileLoader();
  final fontRasterizer = factory.createFontRasterizer();
  final storageBackend = factory.createStorage();
  initFileBackend(fileLoader);
  LocalStorage.init(storageBackend);
  resources = ResourceManager(_renderer, imageLoader, fileLoader, fontRasterizer, audio, loader);

  _windowBackend.onFocus(() {
    if (!_config.autoSuspend || !_suspended) {
      return;
    }
    _suspended = false;
    audio.resume();
    onResume();
    _validateUpdateTimer();
  });

  _windowBackend.onBlur(() {
    if (!_config.autoSuspend || _suspended) {
      return;
    }
    _suspended = true;
    onSuspend();
    audio.suspend();
    keyboard.suspend();
    mouse.suspend();
    gamepad.suspend();
  });

  _windowBackend.focus();

  updateRate = 60;

  width = _windowBackend.width;
  height = _windowBackend.height;
  gfx.setViewport(0, 0, width, height);
  onCreate();
  onResize(width, height);
  _renderGame();
  _validateUpdateTimer();
}