Skip to content
Waldemar Derr edited this page Oct 16, 2019 · 39 revisions
  TAQ = class sealed (TAQBase)
  public
    class function Managed: TAQ;
    class function Unmanaged: TAQ;

    class function Take(...): TAQ;

    class function HasActiveActors(...): Boolean;

    class function GetUniqueID: Integer;

    class function Ease(...): TEaseFunction;
    class function EaseReal(...): Real;
    class function EaseInteger(...): Integer;
    class function EaseColor(...): TColor;
    class function EasePoint(...): TPoint; 
    class function EaseRect(...): TRect;
    class function EaseString(...): String;

  // Public instance related stuff
  public
    constructor Create; override;
    destructor Destroy; override;

    function Each(...): TAQ;
    function EachInterval(...): TAQ;
    function EachTimer(...): TAQ;
    function EachAnimation(...): TAQ;
    function EachDelay(Delay: Integer; Each: TEachFunction; ID: Integer = 0): TAQ;
    function EachRepeat(Times: Integer; EachFunction: TEachFunction): TAQ;

    function NewChain: TAQ;
    function EndChain: TAQ;

    function Die: TAQ;

    function Append(AObject: TObject): TAQ; overload;
    function Append(const Objects: TObjectArray): TAQ; overload;
    function Append(Objects: TObjectList): TAQ; overload;
    function AppendAQ(AQ: TAQ): TAQ;

    function ChildrenAppend(Recurse: Boolean = False; ChildrenFiller: TEachFunction = nil): TAQ;
    function ChildrenChain(Recurse: Boolean = False; ChildrenFiller: TEachFunction = nil): TAQ;
    function ParentsAppend(Recurse: Boolean = False; ParentsFiller: TEachFunction = nil): TAQ;
    function ParentsChain(Recurse: Boolean = False; ParentsFiller: TEachFunction = nil): TAQ;

    function MultiplexChain: TAQ;
    function DemultiplexChain: TAQ;

    function AnimationActorsChain(ID: Integer = 0; IncludeOrphans: Boolean = False): TAQ;
    function IntervalActorsChain(ID: Integer = 0; IncludeOrphans: Boolean = False): TAQ;
    function TimerActorsChain(ID: Integer = 0; IncludeOrphans: Boolean = False): TAQ;
    function DelayActorsChain(ID: Integer = 0; IncludeOrphans: Boolean = False): TAQ;

    function FinishAnimations(ID: Integer = 0): TAQ;
    function CancelAnimations(ID: Integer = 0): TAQ;
    function FinishTimers(ID: Integer = 0): TAQ;
    function CancelTimers(ID: Integer = 0): TAQ;
    function CancelDelays(ID: Integer = 0): TAQ;
    function CancelIntervals(ID: Integer = 0): TAQ;

    function FilterChain(ByClass: TClass): TAQ; overload;
    function FilterChain(FilterEach: TEachFunction): TAQ; overload;

    function ExcludeChain(ByClass: TClass): TAQ; overload;
    function ExcludeChain(AObject: TObject): TAQ; overload;
    function ExcludeChain(const Objects: TObjectArray): TAQ; overload;
    function ExcludeChain(Objects: TObjectList): TAQ; overload;
    function ExcludeChain(AQ: TAQ): TAQ; overload;
    function ExcludeChain(ExcludeEach: TEachFunction): TAQ; overload;

    function IfThen(Condition: Boolean): TAQ;
    function IfElse: TAQ;
    function IfEnd: TAQ;

    function IfAll(EachFunction: TEachFunction): TAQ;
    function IfAny(EachFunction: TEachFunction): TAQ;

    function IfContains(AObject: TObject): TAQ;

    function IfContainsAny(ByClass: TClass): TAQ; overload;
    function IfContainsAny(const Objects: TObjectArray): TAQ; overload;
    function IfContainsAny(Objects: TObjectList): TAQ; overload;
    function IfContainsAny(AQ: TAQ): TAQ; overload;

    function IfContainsAll(ByClass: TClass): TAQ; overload;
    function IfContainsAll(const Objects: TObjectArray): TAQ; overload;
    function IfContainsAll(Objects: TObjectList): TAQ; overload;
    function IfContainsAll(AQ: TAQ): TAQ; overload;

    function SliceChain(StartIndex: Integer; Count: Integer = 0): TAQ;

    function DebugMessage(HeadMessage: String = ''; Caption: String = ''): TAQ;

    function Plugin: T;

    function Contains(AObject: TObject): Boolean;
    procedure Clean;

    property CurrentInterval: TInterval read FCurrentInterval;
  end;

TAQ.Managed

class function TAQ.Managed: TAQ;

Returns a managed TAQ instance

Managed means, that you don't need to worry about memory leaks ;-) There is a simple (but maybe powerful) garbage collector implementation. By requesting for a managed instance it looks primary in the garabage for an died TAQ instance and in case returning it.

TAQ.Unmanaged

class function TAQ.Unmanaged: TAQ;

Returns a unmanaged TAQ instance

It's just the opposite of TAQ.Managed and it is the same as TAQ.Create

TAQ.Take

class function TAQ.Take(AObject: TObject): TAQ;
class function TAQ.Take(const Objects: TObjectArray): TAQ;
class function TAQ.Take(Objects: TObjectList): TAQ;
class function TAQ.Take<T: class>(Objects: TObjectList<T>): TAQ;

Creates a new or recycle an existing managed TAQ instance

There are several overloaded versions of the method. Each of them creates or retake an matching TAQ instance from the garbage collector. The returned TAQ instance contains the passed object(s) and you can work with them.

TAQ.HasActiveActors

class function TAQ.HasActiveActors(CheckActors: TActorRoles; AObject: TObject; 
  ID: Integer = 0): Boolean;

Determines, whether there are active actors for a specific object

Determines, whether there are active actors (running animation, delay...) for AObject in general or optional (if passed) for the actor with the specified ID.

Example

if not TAQ.HasActiveActors([arAnimation], MyButton, BoundsAnimationID) then
  Take(MyButton)
    .Plugin<TAQPControlAnimations>
    .BoundsAnimation(..., BoundsAnimationID);

TAQ.GetUniqueID

class function TAQ.GetUniqueID: Integer;

Returns a unique ID

The returned ID can be used to identify an animation, delay, timer, interval etc. It is recommended to save such IDs in class variables and fill them in an class constructor, see following example.

Example

TMyClass = class
private 
  class var MyAnimationID: Integer;
  class constructor Create;
end;

class constructor TMyClass.Create;
begin
  MyAnimationID := TAQ.GetUniqueID;
end;

TAQ.Ease

There are three overloaded versions of this method and each of them is a little bit special, so we list them separetly. The returned anonymous function of type TEaseFunction can be passed to the specific EaseX methods.

class function TAQ.Ease(EaseType: TEaseType;
  EaseModifier: TEaseModifier = emIn): TEaseFunction;

This method returns a TEaseFunction for the passed TEaseType, which can be optional modified with TEaseModifier

class function TAQ.Ease(const EaseTypes: array of TEaseType;
  EaseModifier: TEaseModifier = emIn): TEaseFunction;

This version creates a TEaseFunction which wraps more than one TEaseType. The returned function returns normalized and compiled values. Additionally you can optional pass a TEaseModifier.

class function TAQ.Ease(const EaseFunction: TEaseFunction = nil;
  EaseModifier: TEaseModifier = emIn): TEaseFunction;

This overloaded version takes any TEaseFunction and modify it with TEaseModifier. This is useful for custom TEaseFunctions.

TAQ.EaseReal

class function TAQ.EaseReal(StartValue, EndValue, Progress: Real; EaseType: TEaseType;
  EaseModifier: TEaseModifier = emIn): Real; 
class function TAQ.EaseReal(StartValue, EndValue, Progress: Real;
  const EaseFunction: TEaseFunction): Real; overload;

Interpolates between the start and end value for the Real type

EaseReal interpolates (easing) between the passed StartValue and EndValue. Progress is a value between 0 and 1. The concrete easing is defined whether by the passed TEaseType or a TEaseFunction.

TAQ.EaseInteger

class function TAQ.EaseInteger(StartValue, EndValue: Integer; Progress: Real; 
  EaseType: TEaseType; EaseModifier: TEaseModifier = emIn): Integer; overload;
class function TAQ.EaseInteger(StartValue, EndValue: Integer; Progress: Real;
  const EaseFunction: TEaseFunction): Integer; overload;

Interpolates between the start and end value for the Integer type

EaseInteger interpolates (easing) between the passed StartValue and EndValue. Progress is a value between 0 and 1. The concrete easing is defined whether by the passed TEaseType or a TEaseFunction.

TAQ.EaseColor

class function TAQ.EaseColor(StartColor, EndColor: TColor; Progress: Real; 
  EaseType: TEaseType; EaseModifier: TEaseModifier = emIn): TColor; overload;
class function TAQ.EaseColor(StartColor, EndColor: TColor; Progress: Real;
  const EaseFunction: TEaseFunction): TColor; overload;

Interpolates between the start and end color

EaseColor interpolates (easing) between the passed StartColor and EndColor. Progress is a value between 0 and 1. The concrete easing is defined whether by the passed TEaseType or a TEaseFunction.

TAQ.EasePoint

class function TAQ.EasePoint(StartPoint, EndPoint: TPoint; Progress: Real; 
  EaseType: TEaseType; EaseModifier: TEaseModifier = emIn): TPoint; overload;
class function TAQ.EasePoint(StartPoint, EndPoint: TPoint; Progress: Real;
  const EaseFunction: TEaseFunction): TPoint; overload;

Interpolates between the start and end point

EasePoint interpolates (easing) between the passed StartPoint and EndPoint. Progress is a value between 0 and 1. The concrete easing is defined whether by the passed TEaseType or a TEaseFunction.

TAQ.EaseRect

class function TAQ.EaseRect(StartRect, EndRect: TRect; Progress: Real; 
  EaseType: TEaseType; EaseModifier: TEaseModifier = emIn): TRect; overload;
class function TAQ.EaseRect(StartRect, EndRect: TRect; Progress: Real;
  const EaseFunction: TEaseFunction): TRect; overload;

Interpolates between the start and end rect

EaseRect interpolates (easing) between the passed StartRect and EndRect. Progress is a value between 0 and 1. The concrete easing is defined whether by the passed TEaseType or a TEaseFunction.

TAQ.EaseString

class function TAQ.EaseString(const StartString, EndString: String; Progress: Real; 
  EaseType: TEaseType; EaseModifier: TEaseModifier = emIn): String; overload;
class function TAQ.EaseString(const StartString, EndString: String; Progress: Real;
  const EaseFunction: TEaseFunction): String; overload;

Interpolates between the start and end string

EaseString interpolates (easing) between the passed StartString and EndString. Progress is a value between 0 and 1. The concrete easing is defined whether by the passed TEaseType or a TEaseFunction.

TAQ.Each

function TAQ.Each(const EachFunction: TEachFunction): TAQ;

Performs the passed method/closure on each in TAQ contained object

Each is the core method of AnyiQuack. Although its implementation looks simple, it is very powerful. The passed EachFunction gets as first paramater the processing TAQ instance (Self) and in the second parameter the subject object. You are able to break the Each from inside of EachFunction by returning False. Otherwise you have to return True for further/full processing.

If the current TAQ instance contains other TAQ instances (appended by TAQ.AppendAQ) and TAQ.Recurse is True (Default) EachFunction is also performed on them.

TAQ.EachInterval

function TAQ.EachInterval(Interval: Integer; const Each: TEachFunction; 
  ID: Integer = 0): TAQ;

Performs the passed method/closure on each in TAQ contained object each interval repeatedly

The passed method Each is called each Interval milliseconds, until you cancel it with TAQ.CancelIntervals. If you consider to perform several EachInterval's on the same objects, you should define an ID (see TAQ.GetUniqueID), so you'll be able to cancel only the specific intervaled Each.

TAQ.EachTimer

function TAQ.EachTimer(Duration: Integer; const Each: TEachFunction; 
  const LastEach: TEachFunction = nil; ID: Integer = 0): TAQ;

Calls the passed Each method periodically on each in TAQ contained object as long as the timer runs, the LastEach method will be called once when the timer expires

From the performing Each function you can access the associated interval with AQ.CurrentInterval and use further runtime specific informations e.g. AQ.CurrentInterval.Progress.

The passed Each method is called in high frequency, but in adapting manner.

Example

procedure TForm1.FormCreate(Sender: TObject);
begin
  Take(Sender)
    .EachTimer(5000,
      function(AQ: TAQ; O: TObject): Boolean
      begin
        with TForm(O) do
          Caption := Format('Left: %d; Top: %d; Width: %d; Height: %d; Progress: %.5f',
            [Left, Top, Width, Height, AQ.CurrentInterval.Progress]);
        Result := True;
      end,
      function(AQ: TAQ; O: TObject): Boolean
      begin
        TForm(O).Caption := 'Tracking of the form placement finished.';
        Result := True;
      end);
end;

TAQ.EachAnimation

function TAQ.EachAnimation(Duration: Integer; Each: TEachFunction; 
  LastEach: TEachFunction = nil; ID: Integer = 0): TAQ;

Performs an abstract animation on each in TAQ contained object

Internally there is no big difference between TAQ.EachAnimation and TAQ.EachTimer, but explicit entity so we can differ in flow logic.

Clone this wiki locally