Initial flame_lua_runtime package
This commit is contained in:
96
lib/runtime/packages/game_package.dart
Normal file
96
lib/runtime/packages/game_package.dart
Normal file
@@ -0,0 +1,96 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../game/runtime_options.dart';
|
||||
import 'game_package_manifest.dart';
|
||||
|
||||
class GamePackage {
|
||||
const GamePackage.asset({
|
||||
required this.rootPath,
|
||||
required this.manifest,
|
||||
this.runtimeLuaRoot = RuntimeOptions.defaultRuntimeLuaRoot,
|
||||
}) : source = GamePackageSource.asset;
|
||||
|
||||
static const runtimeLuaPrefix = 'runtime:';
|
||||
|
||||
const GamePackage.file({
|
||||
required this.rootPath,
|
||||
required this.manifest,
|
||||
this.runtimeLuaRoot = RuntimeOptions.defaultRuntimeLuaRoot,
|
||||
}) : source = GamePackageSource.file;
|
||||
|
||||
final String rootPath;
|
||||
final GamePackageSource source;
|
||||
final GamePackageManifest manifest;
|
||||
final String runtimeLuaRoot;
|
||||
|
||||
String get entryPath => _join(rootPath, manifest.entry);
|
||||
|
||||
bool get isAsset => source == GamePackageSource.asset;
|
||||
|
||||
Future<String> readText(String relativeOrAbsolutePath) async {
|
||||
final runtimePath = _resolveRuntimeLuaPath(relativeOrAbsolutePath);
|
||||
if (runtimePath != null) {
|
||||
return rootBundle.loadString(runtimePath);
|
||||
}
|
||||
|
||||
final path = _resolvePackagePath(relativeOrAbsolutePath);
|
||||
if (isAsset) {
|
||||
return rootBundle.loadString(path);
|
||||
}
|
||||
return File(path).readAsString();
|
||||
}
|
||||
|
||||
Future<ByteData> readBytes(String relativeOrAbsolutePath) async {
|
||||
final path = _resolvePackagePath(relativeOrAbsolutePath);
|
||||
if (isAsset) {
|
||||
return rootBundle.load(path);
|
||||
}
|
||||
final bytes = await File(path).readAsBytes();
|
||||
return ByteData.sublistView(bytes);
|
||||
}
|
||||
|
||||
String resolveResourcePath(String keyOrPath) {
|
||||
final resource = manifest.resources[keyOrPath];
|
||||
if (resource != null) {
|
||||
return _join(rootPath, resource.path);
|
||||
}
|
||||
|
||||
if (keyOrPath.startsWith(rootPath)) {
|
||||
return keyOrPath;
|
||||
}
|
||||
if (keyOrPath.contains('/')) {
|
||||
return _join(rootPath, keyOrPath);
|
||||
}
|
||||
return _join(_join(rootPath, manifest.assetsBase), keyOrPath);
|
||||
}
|
||||
|
||||
String _resolvePackagePath(String relativeOrAbsolutePath) {
|
||||
if (relativeOrAbsolutePath.startsWith(rootPath)) {
|
||||
return relativeOrAbsolutePath;
|
||||
}
|
||||
return _join(rootPath, relativeOrAbsolutePath);
|
||||
}
|
||||
|
||||
String? _resolveRuntimeLuaPath(String path) {
|
||||
if (!path.startsWith(runtimeLuaPrefix)) {
|
||||
return null;
|
||||
}
|
||||
final name = path.substring(runtimeLuaPrefix.length);
|
||||
if (name.isEmpty || name.contains('/') || name.contains('..')) {
|
||||
throw FormatException('Invalid runtime Lua module path: $path');
|
||||
}
|
||||
return _join(runtimeLuaRoot, name);
|
||||
}
|
||||
|
||||
String _join(String left, String right) {
|
||||
final normalizedLeft = left.endsWith('/')
|
||||
? left.substring(0, left.length - 1)
|
||||
: left;
|
||||
final normalizedRight = right.startsWith('/') ? right.substring(1) : right;
|
||||
return '$normalizedLeft/$normalizedRight';
|
||||
}
|
||||
}
|
||||
|
||||
enum GamePackageSource { asset, file }
|
||||
Reference in New Issue
Block a user