Files
integration/Source/Integration/AnimQueue.h

209 lines
4.8 KiB
C
Raw Normal View History

2023-09-08 05:38:09 -04:00
#pragma once
#include "CoreMinimal.h"
#include "StringDecoder.h"
2023-09-15 00:01:41 -04:00
#include "Containers/Deque.h"
2023-09-08 05:38:09 -04:00
////////////////////////////////////////////////
//
// This is copied over from Luprex source. Not ideal.
//
////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
enum ElxAnimValueType {
2023-09-08 05:38:09 -04:00
T_STRING,
T_NUMBER,
T_BOOLEAN,
T_XYZ,
T_UNINITIALIZED
};
////////////////////////////////////////////////
//
// An single animation step.
//
2023-09-15 13:28:18 -04:00
// The body consists of a sequence of FlxAnimField
2023-09-08 05:38:09 -04:00
// records. The body is encoded, to read the
2023-09-15 13:28:18 -04:00
// FlxAnimField records you need an FlxAnimStepDecoder.
2023-09-15 00:01:41 -04:00
// This comes in two versions: the string version,
// and the string_view version.
2023-09-08 05:38:09 -04:00
//
////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
struct FlxAnimStep {
uint64 Hash;
2023-09-08 05:38:09 -04:00
std::string_view Body;
2023-09-15 00:01:41 -04:00
2023-09-15 13:28:18 -04:00
FlxAnimStep() : Hash(0), Body("") {}
FlxAnimStep(uint64 h, std::string_view b) : Hash(h), Body(b) {}
2023-09-15 00:01:41 -04:00
};
2023-09-15 13:28:18 -04:00
struct FlxAnimStoredStep {
2023-09-15 00:01:41 -04:00
uint64 Hash;
std::string Body;
2023-09-15 13:28:18 -04:00
FlxAnimStoredStep() : Hash(0), Body("") {}
FlxAnimStoredStep(uint64 h, std::string_view b) : Hash(h), Body(b) {}
2023-09-08 05:38:09 -04:00
};
////////////////////////////////////////////////
//
// A single animation field.
//
// A field consists of a variable name,
// a persistent flag, a type, and some fields
// to hold the values.
//
// If the value is boolean, it is stored in
// X, as either 1 or 0. If the value is double,
// it is stored in X.
//
////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
struct FlxAnimField {
2023-09-08 05:38:09 -04:00
std::string_view Name;
bool Persistent;
2023-09-15 13:28:18 -04:00
ElxAnimValueType Type;
2023-09-08 05:38:09 -04:00
double X, Y, Z;
std::string_view S;
};
////////////////////////////////////////////////
//
// An Animation Queue Decoder.
//
// This acts a lot like a stream reader,
// it reads one AnimEntry at a time from
// the animation queue until you reach
// 'end-of-file'.
//
////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
class FlxAnimQueueDecoder {
2023-09-08 05:38:09 -04:00
private:
2023-09-15 13:28:18 -04:00
FlxStringDecoder Decoder;
2023-09-08 05:38:09 -04:00
public:
2023-09-15 13:28:18 -04:00
// Initialize the FlxAnimQueueDecoder with the encoded animation queue.
2023-09-08 05:38:09 -04:00
//
2023-09-15 13:28:18 -04:00
FlxAnimQueueDecoder(std::string_view s) : Decoder(s) {}
2023-09-08 05:38:09 -04:00
// Return true if the parser has reached the end of the string.
//
bool AtEOF() { return Decoder.at_eof(); }
// Read one animation step.
//
2023-09-15 13:28:18 -04:00
FlxAnimStep ReadStep();
2023-09-08 05:38:09 -04:00
// Convert an AnimQueue to an FString.
//
static FString DebugString(std::string_view s);
};
////////////////////////////////////////////////
//
// An Animation Step Decoder.
//
// This acts a lot like a stream reader,
2023-09-15 13:28:18 -04:00
// it reads one FlxAnimField at a time from
2023-09-08 05:38:09 -04:00
// the animation queue until you reach
// 'end-of-file'.
//
////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
class FlxAnimStepDecoder {
2023-09-08 05:38:09 -04:00
private:
2023-09-15 13:28:18 -04:00
FlxStringDecoder Decoder;
2023-09-08 05:38:09 -04:00
public:
2023-09-15 13:28:18 -04:00
// Initialize the FlxAnimStepDecoder from the FlxAnimStep.
2023-09-08 05:38:09 -04:00
//
2023-09-15 13:28:18 -04:00
FlxAnimStepDecoder(const FlxAnimStep &step) : Decoder(step.Body) {}
FlxAnimStepDecoder(const FlxAnimStoredStep& step) : Decoder(step.Body) {}
2023-09-08 05:38:09 -04:00
// Return true if the parser has reached the end of the string.
//
bool AtEOF() { return Decoder.at_eof(); }
// Read one field.
//
2023-09-15 13:28:18 -04:00
FlxAnimField ReadField();
2023-09-08 05:38:09 -04:00
// Convert an AnimStep to an FString.
//
2023-09-15 13:28:18 -04:00
static FString DebugString(const FlxAnimStep &step);
2023-09-08 05:38:09 -04:00
};
2023-09-15 00:01:41 -04:00
////////////////////////////////////////////////
//
2023-09-15 13:28:18 -04:00
// FlxAnimTracker
2023-09-15 00:01:41 -04:00
//
// This class monitors the animation queue for a single
// tangible. It can identify when a new animation has
// appeared on the animation queue, and when animations have
// been removed from the animation queue. It also
// keeps track of which animations have been started.
//
////////////////////////////////////////////////
2023-09-15 13:28:18 -04:00
class FlxAnimTracker {
2023-09-15 00:01:41 -04:00
public:
// Our own copy of the animation queue. We only
// store the hashes, not the steps. The First element
// of the queue is the oldest item.
//
2023-09-15 13:28:18 -04:00
TDeque<FlxAnimStoredStep> AQ;
2023-09-15 00:01:41 -04:00
// The sequence number of the first item in AQ.
//
int32 FirstSeqno;
// Map from hash to sequence number.
//
TMap<uint64, int32> HashToSeqno;
// The sequence number of the first unstarted animation.
//
int32 UnstartedSeqno;
// Array of recently-aborted hash values.
TArray<uint64> AbortedHashes;
public:
// Construct a tracker.
//
// Initially, the tracker is in the empty (Clear) state.
//
2023-09-15 13:28:18 -04:00
FlxAnimTracker();
2023-09-15 00:01:41 -04:00
// Update from the specified animation queue.
//
// After the update is done, AQ will be a copy
// of the animation queue that is passed in.
//
void Update(std::string_view encqueue);
// Fetch the aborted hash values.
//
// This gets the array of aborted hashes and clears
// the stored array.
//
TArray<uint64> GetAborted();
// Return true if there are any unstarted animation steps.
//
bool AnyUnstarted();
// Get the next unstarted animation step.
//
// You may only call this if AnyUnstarted returns true.
//
2023-09-15 13:28:18 -04:00
FlxAnimStoredStep GetUnstarted();
2023-09-15 00:01:41 -04:00
// Declare that an animation has been started.
//
// After starting an animation, you should call this.
//
void Started(uint64 Hash);
};