chore: Add null safety to PlayState and LoadingState

This commit is contained in:
Hyper_
2025-08-05 01:18:53 +08:00
committed by Hundrec
parent 1d8679941e
commit 34ce13c5df
6 changed files with 337 additions and 247 deletions
+6 -6
View File
@@ -162,7 +162,7 @@ class GameOverSubState extends MusicBeatSubState
if ((parentPlayState?.isMinimalMode ?? true)) {}
else
{
boyfriend = parentPlayState?.currentStage.getBoyfriend(true);
boyfriend = parentPlayState?.currentStage?.getBoyfriend(true);
if (boyfriend != null)
{
boyfriend.canPlayOtherAnims = true;
@@ -193,10 +193,9 @@ class GameOverSubState extends MusicBeatSubState
});
}
@:nullSafety(Off)
function setCameraTarget():Void
{
if ((parentPlayState?.isMinimalMode ?? true) || boyfriend == null) return;
if (parentPlayState == null || parentPlayState.isMinimalMode || boyfriend == null) return;
// Assign a camera follow point to the boyfriend's position.
cameraFollowPoint = new FlxObject(parentPlayState.cameraFollowPoint.x, parentPlayState.cameraFollowPoint.y, 1, 1);
@@ -207,6 +206,7 @@ class GameOverSubState extends MusicBeatSubState
cameraFollowPoint.y += offsets[1];
add(cameraFollowPoint);
@:nullSafety(Off)
FlxG.camera.target = null;
FlxG.camera.follow(cameraFollowPoint, LOCKON, Constants.DEFAULT_CAMERA_FOLLOW_RATE / 2);
targetCameraZoom = (parentPlayState?.currentStage?.camZoom ?? 1.0) * boyfriend.getDeathCameraZoom();
@@ -394,7 +394,7 @@ class GameOverSubState extends MusicBeatSubState
// Readd Boyfriend to the stage.
boyfriend.isDead = false;
remove(boyfriend);
parentPlayState?.currentStage.addCharacter(boyfriend, BF);
parentPlayState?.currentStage?.addCharacter(boyfriend, BF);
}
// Snap reset the camera which may have changed because of the player character data.
@@ -564,11 +564,11 @@ class GameOverSubState extends MusicBeatSubState
PlayStatePlaylist.reset();
}
var stickerPackId:Null<String> = parentPlayState?.currentChart.stickerPack;
var stickerPackId:Null<String> = parentPlayState?.currentChart?.stickerPack;
if (stickerPackId == null)
{
var playerCharacterId:Null<String> = PlayerRegistry.instance.getCharacterOwnerId(parentPlayState?.currentChart.characters.player);
var playerCharacterId:Null<String> = PlayerRegistry.instance.getCharacterOwnerId(parentPlayState?.currentChart?.characters.player);
var playerCharacter:Null<PlayableCharacter> = PlayerRegistry.instance.fetchEntry(playerCharacterId ?? Constants.DEFAULT_CHARACTER);
if (playerCharacter != null)
+2 -2
View File
@@ -18,9 +18,9 @@ class GitarooPause extends MusicBeatState
var replaySelect:Bool = false;
var previousParams:PlayStateParams;
var previousParams:Null<PlayStateParams>;
public function new(previousParams:PlayStateParams):Void
public function new(?previousParams:PlayStateParams):Void
{
super();
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -151,10 +151,12 @@ class HealthIcon extends FunkinSprite
*/
public function toggleOldIcon():Void
{
final playState:Null<PlayState> = PlayState.instance;
if (playState == null || playState.currentStage == null) return;
if (characterId == 'bf-old')
{
isPixel = PlayState.instance.currentStage.getBoyfriend().isPixel;
PlayState.instance.currentStage.getBoyfriend().initHealthIcon(false);
isPixel = playState.currentStage.getBoyfriend()?.isPixel ?? false;
playState.currentStage.getBoyfriend()?.initHealthIcon(false);
}
else
{
+4 -4
View File
@@ -97,9 +97,9 @@ class Strumline extends FlxSpriteGroup
/**
* Reset the scroll speed to the current chart's scroll speed.
*/
public function resetScrollSpeed():Void
public function resetScrollSpeed(?newScrollSpeed:Float):Void
{
scrollSpeed = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0;
scrollSpeed = newScrollSpeed ?? PlayState.instance?.currentChart?.scrollSpeed ?? 1.0;
}
var _conductorInUse:Null<Conductor>;
@@ -184,7 +184,7 @@ class Strumline extends FlxSpriteGroup
static final BACKGROUND_PAD:Int = 16;
public function new(noteStyle:NoteStyle, isPlayer:Bool)
public function new(noteStyle:NoteStyle, isPlayer:Bool, ?scrollSpeed:Float)
{
super();
@@ -243,7 +243,7 @@ class Strumline extends FlxSpriteGroup
this.refresh();
this.onNoteIncoming = new FlxTypedSignal<NoteSprite->Void>();
resetScrollSpeed();
resetScrollSpeed(scrollSpeed);
for (i in 0...KEY_COUNT)
{
+33 -21
View File
@@ -12,6 +12,7 @@ import funkin.graphics.shaders.ScreenWipeShader;
import funkin.play.PlayState;
import funkin.play.PlayStatePlaylist;
import funkin.play.song.Song.SongDifficulty;
import funkin.play.stage.Stage;
import haxe.io.Path;
import lime.app.Future;
import lime.app.Promise;
@@ -21,6 +22,7 @@ import lime.utils.Assets as LimeAssets;
import openfl.filters.ShaderFilter;
import openfl.utils.Assets as OpenFLAssets;
@:nullSafety
class LoadingState extends MusicBeatSubState
{
inline static var MIN_TIME = 1.0;
@@ -30,18 +32,21 @@ class LoadingState extends MusicBeatSubState
var target:NextState;
var playParams:Null<PlayStateParams>;
var stopMusic:Bool = false;
var callbacks:MultiCallback;
var callbacks:Null<MultiCallback>;
var danceLeft:Bool = false;
var loadBar:FlxSprite;
var funkay:FlxSprite;
function new(target:NextState, stopMusic:Bool, playParams:Null<PlayStateParams> = null)
function new(target:NextState, stopMusic:Bool, ?playParams:PlayStateParams)
{
super();
this.target = target;
this.playParams = playParams;
this.stopMusic = stopMusic;
this.loadBar = new FunkinSprite(0, FlxG.height - 20).makeSolidColor(0, 10, 0xFFff16d2);
this.funkay = FunkinSprite.create('funkay');
}
override function create():Void
@@ -49,14 +54,12 @@ class LoadingState extends MusicBeatSubState
var bg:FunkinSprite = new FunkinSprite().makeSolidColor(FlxG.width, FlxG.height, 0xFFcaff4d);
add(bg);
funkay = FunkinSprite.create('funkay');
funkay.setGraphicSize(0, FlxG.height);
funkay.updateHitbox();
add(funkay);
funkay.scrollFactor.set();
funkay.screenCenter();
loadBar = new FunkinSprite(0, FlxG.height - 20).makeSolidColor(0, 10, 0xFFff16d2);
add(loadBar);
initSongsManifest().onComplete(function(lib) {
@@ -66,15 +69,21 @@ class LoadingState extends MusicBeatSubState
if (playParams != null)
{
// Load and cache the song's charts.
if (playParams.targetSong != null)
if (playParams.targetSong == null)
{
playParams.targetSong.cacheCharts(true);
throw 'Invalid parameter: Target song should not be null';
}
playParams.targetSong.cacheCharts(true);
// Preload the song for the play state.
var difficulty:String = playParams.targetDifficulty ?? Constants.DEFAULT_DIFFICULTY;
var variation:String = playParams.targetVariation ?? Constants.DEFAULT_VARIATION;
var targetChart:SongDifficulty = playParams.targetSong?.getDifficulty(difficulty, variation);
var targetChart:Null<SongDifficulty> = playParams.targetSong.getDifficulty(difficulty, variation);
if (targetChart == null)
{
throw 'Couldn\'t retrieve chart data for song "${playParams.targetSong.songName}" on difficulty "$difficulty" and variation "$variation"';
}
var instPath:String = targetChart.getInstPath(playParams.targetInstrumental);
var voicesPaths:Array<String> = targetChart.buildVoiceList();
@@ -105,9 +114,9 @@ class LoadingState extends MusicBeatSubState
// library.types.set(symbolPath, SOUND);
// @:privateAccess
// library.pathGroups.set(symbolPath, [library.__cacheBreak(symbolPath)]);
var callback = callbacks.add('song:' + path);
var callback = callbacks?.add('song:' + path);
Assets.loadSound(path).onComplete(function(_) {
callback();
if (callback != null) callback();
});
}
}
@@ -120,9 +129,9 @@ class LoadingState extends MusicBeatSubState
@:privateAccess
if (!LimeAssets.libraryPaths.exists(library)) throw 'Missing library: ' + library;
var callback = callbacks.add('library:' + library);
var callback = callbacks?.add('library:' + library);
Assets.loadLibrary(library).onComplete(function(_) {
callback();
if (callback != null) callback();
});
}
}
@@ -177,6 +186,7 @@ class LoadingState extends MusicBeatSubState
function onLoad():Void
{
// Stop the instrumental.
@:nullSafety(Off)
if (stopMusic && FlxG.sound.music != null)
{
FlxG.sound.music.destroy();
@@ -197,7 +207,7 @@ class LoadingState extends MusicBeatSubState
static function getSongPath():String
{
return Paths.inst(PlayState.instance.currentSong.id);
return Paths.inst(PlayState.instance?.currentSong.id ?? throw 'Cannot retrieve song path');
}
static var stageDirectory:String = "shared";
@@ -211,10 +221,10 @@ class LoadingState extends MusicBeatSubState
*/
public static function loadPlayState(params:PlayStateParams, shouldStopMusic = false, asSubState = false, ?onConstruct:PlayState->Void):Void
{
var daChart:Null<SongDifficulty> = params.targetSong.getDifficulty(params.targetDifficulty ?? Constants.DEFAULT_DIFFICULTY,
var daChart:Null<SongDifficulty> = params.targetSong?.getDifficulty(params.targetDifficulty ?? Constants.DEFAULT_DIFFICULTY,
params.targetVariation ?? Constants.DEFAULT_VARIATION);
var daStage = funkin.data.stage.StageRegistry.instance.fetchEntry(daChart?.stage ?? Constants.DEFAULT_STAGE);
var daStage:Null<Stage> = funkin.data.stage.StageRegistry.instance.fetchEntry(daChart?.stage ?? Constants.DEFAULT_STAGE);
stageDirectory = daStage?._data?.directory ?? "shared";
Paths.setCurrentLevel(stageDirectory);
@@ -249,6 +259,7 @@ class LoadingState extends MusicBeatSubState
}
#else
// All assets preloaded, switch directly to play state (defualt on other targets).
@:nullSafety(Off)
if (shouldStopMusic && FlxG.sound.music != null)
{
FlxG.sound.music.destroy();
@@ -257,7 +268,7 @@ class LoadingState extends MusicBeatSubState
// Load and cache the song's charts.
// Don't do this if we already provided the music and charts.
if (params?.targetSong != null && !params.overrideMusic)
if (!(params.overrideMusic ?? false))
{
params.targetSong.cacheCharts(true);
}
@@ -272,7 +283,8 @@ class LoadingState extends MusicBeatSubState
var songDifficulty = params.targetSong.getDifficulty(params.targetDifficulty, params.targetVariation);
if (songDifficulty != null)
{
var noteStyle = NoteStyleRegistry.instance.fetchEntry(songDifficulty.noteStyle);
var noteStyle = NoteStyleRegistry.instance.fetchEntry(songDifficulty.noteStyle ?? '');
if (noteStyle == null) noteStyle = NoteStyleRegistry.instance.fetchDefault();
FunkinMemory.cacheNoteStyle(noteStyle);
}
@@ -439,7 +451,7 @@ class LoadingState extends MusicBeatSubState
var libraryPaths = LimeAssets.libraryPaths;
if (libraryPaths.exists(id))
{
path = libraryPaths[id];
path = libraryPaths[id] ?? path;
rootPath = Path.directory(path);
}
else
@@ -490,17 +502,18 @@ class LoadingState extends MusicBeatSubState
}
}
@:nullSafety
class MultiCallback
{
public var callback:Void->Void;
public var logId:String = null;
public var logId:Null<String>;
public var length(default, null) = 0;
public var numRemaining(default, null) = 0;
var unfired = new Map<String, Void->Void>();
var fired = new Array<String>();
public function new(callback:Void->Void, logId:String = null)
public function new(callback:Void->Void, ?logId:String)
{
this.callback = callback;
this.logId = logId;
@@ -511,8 +524,7 @@ class MultiCallback
id = '$length:$id';
length++;
numRemaining++;
var func:Void->Void = null;
func = function() {
var func:Void->Void = function() {
if (unfired.exists(id))
{
unfired.remove(id);