mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-14 19:25:16 -05:00
Merge 76dede8d19
into 0d8e4a5330
This commit is contained in:
commit
8bcd27533e
2 changed files with 179 additions and 0 deletions
|
@ -6,6 +6,7 @@ import flixel.math.FlxMath;
|
||||||
import funkin.data.song.SongData.SongTimeChange;
|
import funkin.data.song.SongData.SongTimeChange;
|
||||||
import funkin.data.song.SongDataUtils;
|
import funkin.data.song.SongDataUtils;
|
||||||
import funkin.save.Save;
|
import funkin.save.Save;
|
||||||
|
import funkin.util.TimerUtil.SongSequence;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
import flixel.sound.FlxSound;
|
import flixel.sound.FlxSound;
|
||||||
|
|
||||||
|
@ -492,6 +493,8 @@ class Conductor
|
||||||
prevTime = this.songPosition;
|
prevTime = this.songPosition;
|
||||||
prevTimestamp = Std.int(Timer.stamp() * 1000);
|
prevTimestamp = Std.int(Timer.stamp() * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this == Conductor.instance) SongSequence.update.dispatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package funkin.util;
|
package funkin.util;
|
||||||
|
|
||||||
|
import flixel.util.FlxTimer;
|
||||||
|
import funkin.Conductor;
|
||||||
import funkin.util.tools.FloatTools;
|
import funkin.util.tools.FloatTools;
|
||||||
import haxe.Timer;
|
import haxe.Timer;
|
||||||
|
|
||||||
|
@ -47,3 +49,177 @@ class TimerUtil
|
||||||
return '${seconds * 1000} ms';
|
return '${seconds * 1000} ms';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef SequenceEvent =
|
||||||
|
{
|
||||||
|
time: Float,
|
||||||
|
callback: ()->Void
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A timer sequence based on FlxTimers.
|
||||||
|
*/
|
||||||
|
class Sequence
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new timer sequence.
|
||||||
|
* @param events A list of function callbacks along with their corresponding call times, in seconds.
|
||||||
|
* @param mult Optional multiplier for callback times. Great for frame-based or music-based timing.
|
||||||
|
* @param start Whether or not to immediately start the sequence.
|
||||||
|
*/
|
||||||
|
public function new(events:Array<SequenceEvent>, mult:Float = 1, start:Bool = true)
|
||||||
|
{
|
||||||
|
for (event in events)
|
||||||
|
{
|
||||||
|
timers.push(new FlxTimer().start(
|
||||||
|
event.time * mult,
|
||||||
|
function(timer:FlxTimer)
|
||||||
|
{
|
||||||
|
event.callback();
|
||||||
|
timers.remove(timer);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
running = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of uncompleted timers.
|
||||||
|
*/
|
||||||
|
private final timers:Array<FlxTimer> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether the timers in this sequence are active or not.
|
||||||
|
*/
|
||||||
|
public var running(get, set):Bool;
|
||||||
|
private var _running:Bool = true;
|
||||||
|
|
||||||
|
@:noCompletion public function get_running():Bool
|
||||||
|
{
|
||||||
|
return completed ? false : _running;
|
||||||
|
}
|
||||||
|
|
||||||
|
@:noCompletion public function set_running(v:Bool):Bool
|
||||||
|
{
|
||||||
|
for (timer in timers) timer.active = v;
|
||||||
|
return _running = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether all timers in this sequence have completed or not.
|
||||||
|
*/
|
||||||
|
public var completed(get, never);
|
||||||
|
|
||||||
|
@:noCompletion public function get_completed():Bool
|
||||||
|
{
|
||||||
|
return timers.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up and destroy this sequence.
|
||||||
|
*/
|
||||||
|
public function destroy():Void
|
||||||
|
{
|
||||||
|
for (timer in timers)
|
||||||
|
{
|
||||||
|
timer.cancel();
|
||||||
|
timer.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!completed) timers.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A timer sequence based on songPosition.
|
||||||
|
*/
|
||||||
|
class SongSequence
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Signal dispatched by Conductor.instance.update.
|
||||||
|
*/
|
||||||
|
public static final update(default, null):FlxSignal = new FlxSignal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new timer sequence (follows Conductor).
|
||||||
|
* @param events A list of function callbacks along with their corresponding call times, in seconds.
|
||||||
|
* @param mult Optional multiplier for callback times. Great for frame-based or music-based timing.
|
||||||
|
* @param start Whether or not to immediately start the sequence.
|
||||||
|
*/
|
||||||
|
public function new(events:Array<SequenceEvent>, mult:Float = 1, start:Bool = true)
|
||||||
|
{
|
||||||
|
for (event in events) timers.push(event);
|
||||||
|
|
||||||
|
startTime = Conductor.instance.songPosition;
|
||||||
|
running = start;
|
||||||
|
update.add(onUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of the time this sequence started, or the relative time if it was previously stopped.
|
||||||
|
*/
|
||||||
|
private var startTime:Float;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of uncompleted timers.
|
||||||
|
*/
|
||||||
|
private final timers:Array<SequenceEvent> = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update function invoked by the update signal.
|
||||||
|
*/
|
||||||
|
private function onUpdate():Void
|
||||||
|
{
|
||||||
|
if (!running) return;
|
||||||
|
|
||||||
|
var len:Int = timers.length;
|
||||||
|
for (i in 0...len)
|
||||||
|
{
|
||||||
|
var timer:SequenceEvent = timers[len - 1 - i];
|
||||||
|
if (timer.time + startTime > Conductor.instance.songPosition)
|
||||||
|
{
|
||||||
|
timer.callback();
|
||||||
|
timers.remove(timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completed) destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether the timers in this sequence are active or not.
|
||||||
|
*/
|
||||||
|
public var running(get, set):Bool;
|
||||||
|
private var _running:Bool = true;
|
||||||
|
|
||||||
|
@:noCompletion public function get_running():Bool
|
||||||
|
{
|
||||||
|
return completed ? false : _running;
|
||||||
|
}
|
||||||
|
|
||||||
|
@:noCompletion public function set_running(v:Bool):Bool
|
||||||
|
{
|
||||||
|
if (v != _running) startTime = Conductor.instance.songPosition - startTime; // it works trust me
|
||||||
|
return _running = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether all timers in this sequence have completed or not.
|
||||||
|
*/
|
||||||
|
public var completed(get, never);
|
||||||
|
|
||||||
|
@:noCompletion public function get_completed():Bool
|
||||||
|
{
|
||||||
|
return timers.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up and destroy this sequence.
|
||||||
|
*/
|
||||||
|
public function destroy():Void
|
||||||
|
{
|
||||||
|
update.remove(onUpdate);
|
||||||
|
while (!completed) timers.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue