Files
wolf_dart/packages/wolf_3d_renderer/lib/base_renderer.dart
Hans Kokx 3c6a4672f7 Refactor and enhance documentation across the Wolf3D project
- Updated library imports to use the correct package paths for consistency.
- Added detailed documentation comments to various classes and methods, improving code readability and maintainability.
- Refined the GameSelectScreen, SpriteGallery, and VgaGallery classes with clearer descriptions of their functionality.
- Enhanced the CliInput class to better explain the input handling process and its interaction with the engine.
- Improved the SixelRasterizer and Opl2Emulator classes with comprehensive comments on their operations and state management.
- Removed the deprecated wolf_3d.dart file and consolidated its functionality into wolf_3d_flutter.dart for a cleaner architecture.
- Updated the Wolf3dFlutterInput class to clarify its role in merging keyboard and pointer events.
- Enhanced the rendering classes to provide better context on their purpose and usage within the Flutter framework.

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
2026-03-18 10:01:12 +01:00

86 lines
2.1 KiB
Dart

/// Shared Flutter renderer shell for driving the Wolf3D engine from a widget tree.
library;
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
/// Base widget for renderers that present frames from a [WolfEngine].
abstract class BaseWolfRenderer extends StatefulWidget {
/// Engine instance that owns world state and the shared framebuffer.
final WolfEngine engine;
/// Creates a renderer bound to [engine].
const BaseWolfRenderer({
required this.engine,
super.key,
});
}
/// Base [State] implementation that provides a ticker-driven render loop.
abstract class BaseWolfRendererState<T extends BaseWolfRenderer>
extends State<T>
with SingleTickerProviderStateMixin {
/// Per-frame ticker used to advance the engine and request renders.
late final Ticker gameLoop;
/// Focus node used by the enclosing [KeyboardListener].
final FocusNode focusNode = FocusNode();
Duration _lastTick = Duration.zero;
@override
void initState() {
super.initState();
gameLoop = createTicker(_tick)..start();
focusNode.requestFocus();
}
void _tick(Duration elapsed) {
if (!widget.engine.isInitialized) return;
if (_lastTick == Duration.zero) {
_lastTick = elapsed;
return;
}
Duration delta = elapsed - _lastTick;
_lastTick = elapsed;
widget.engine.tick(delta);
performRender();
}
@override
void dispose() {
gameLoop.dispose();
focusNode.dispose();
super.dispose();
}
/// Renders the latest engine state into the concrete renderer's output type.
void performRender();
/// Builds the visible viewport widget for the latest rendered frame.
Widget buildViewport(BuildContext context);
/// Background color used by the surrounding scaffold.
Color get scaffoldColor;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: scaffoldColor,
body: KeyboardListener(
focusNode: focusNode,
autofocus: true,
onKeyEvent: (_) {},
child: Center(
child: buildViewport(context),
),
),
);
}
}