diff --git a/PSBT.txt b/PSBT.txt index ae6ad1b..519c1bd 100644 --- a/PSBT.txt +++ b/PSBT.txt @@ -16,7 +16,9 @@ core/PSBT_Media.lua core/PSBT_Constants.lua ## helpers +helpers/PSBT_AnimationPool.lua helpers/PSBT_Parabola.lua +helpers/PSBT_Fade.lua ## core modules core/PSBT_Module.lua @@ -32,7 +34,6 @@ modules/PSBT_LowSomething.lua modules/PSBT_Ultimate.lua ## core -core/PSBT_Fifo.lua core/PSBT_Label.lua core/PSBT_ScrollArea.lua core/PSBT.lua diff --git a/core/PSBT.lua b/core/PSBT.lua index 3defc25..a17542b 100644 --- a/core/PSBT.lua +++ b/core/PSBT.lua @@ -34,6 +34,10 @@ local PSBT = ZO_ObjectPool:Subclass() PSBT._modules = {} PSBT._areas = {} PSBT._events = {} +PSBT.__DEBUG_UPDATE = 0 +PSBT.__DEBUG = false + +local PSBT_Fade = PSBT_Fade local CBM = CALLBACK_MANAGER local PSBT_ScrollArea = PSBT_ScrollArea @@ -76,16 +80,31 @@ function PSBT:OnLoaded( addon ) print( 'Loading PSBT' ) CBM:FireCallbacks( PSBT_EVENTS.LOADED, self ) - self._areas[ PSBT_AREAS.INCOMING ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.INCOMING, self:GetSetting( PSBT_AREAS.INCOMING ) ) - self._areas[ PSBT_AREAS.OUTGOING ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.OUTGOING, self:GetSetting( PSBT_AREAS.OUTGOING ) ) - self._areas[ PSBT_AREAS.STATIC ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.STATIC, self:GetSetting( PSBT_AREAS.STATIC ) ) - self._areas[ PSBT_AREAS.NOTIFICATION ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.NOTIFICATION, self:GetSetting( PSBT_AREAS.NOTIFICATION ) ) + self._fadeIn = PSBT_Fade:New( 1.0, 0.0 ) + self._fadeOut = PSBT_Fade:New( 0.0, 1,0 ) + + self._areas[ PSBT_AREAS.INCOMING ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.INCOMING, self:GetSetting( PSBT_AREAS.INCOMING ), self._fadeIn, self._fadeOut ) + self._areas[ PSBT_AREAS.OUTGOING ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.OUTGOING, self:GetSetting( PSBT_AREAS.OUTGOING ), self._fadeIn, self._fadeOut ) + self._areas[ PSBT_AREAS.STATIC ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.STATIC, self:GetSetting( PSBT_AREAS.STATIC ), self._fadeIn, self._fadeOut ) + self._areas[ PSBT_AREAS.NOTIFICATION ] = PSBT_ScrollArea:New( self.control, PSBT_AREAS.NOTIFICATION, self:GetSetting( PSBT_AREAS.NOTIFICATION ), self._fadeIn, self._fadeOut ) CBM:RegisterCallback( PSBT_EVENTS.CONFIG, function( ... ) self:SetConfigurationMode( ... ) end ) self.control:SetHandler( 'OnUpdate', function( _, frameTime ) self:OnUpdate( frameTime ) end ) end function PSBT:OnUpdate( frameTime ) + if ( self.__DEBUG ) then + if ( frameTime - self.__DEBUG_UPDATE > 2 ) then + self.__DEBUG_UPDATE = frameTime + d( '-------------- PSBT_DEBUG_UPDATE --------------') + d( 'LABELS total = ' .. self:GetTotalObjectCount() .. ', active = ' .. self:GetActiveObjectCount() .. ', inactive = ' .. self:GetFreeObjectCount() ) + d( 'FADEIN total = ' .. self._fadeIn:GetTotalObjectCount() .. ', active = ' .. self._fadeIn:GetActiveObjectCount() .. ', inactive = ' .. self._fadeIn:GetFreeObjectCount() ) + d( 'FADEOUT total = ' .. self._fadeOut:GetTotalObjectCount() .. ', active = ' .. self._fadeOut:GetActiveObjectCount() .. ', inactive = ' .. self._fadeOut:GetFreeObjectCount() ) + d( 'INCOMING PARABOLAS total = ' .. self._areas[ PSBT_AREAS.INCOMING ]._parabola:GetTotalObjectCount() ) + d( 'OUTGOING PARABOLAS total = ' .. self._areas[ PSBT_AREAS.OUTGOING ]._parabola:GetTotalObjectCount() ) + end + end + for k,label in pairs( self:GetActiveObjects() ) do if ( label:IsExpired( frameTime ) ) then self:ReleaseObject( k ) @@ -228,4 +247,6 @@ end -- LEAVE ME THE FUARK ALONE function Initialized( control ) _G.PSBT = PSBT:New( control ) + + SLASH_COMMANDS['/psbtdebug'] = function() _G.PSBT.__DEBUG = not _G.PSBT.__DEBUG end end diff --git a/core/PSBT_Fifo.lua b/core/PSBT_Fifo.lua deleted file mode 100644 index 702e7a9..0000000 --- a/core/PSBT_Fifo.lua +++ /dev/null @@ -1,87 +0,0 @@ ------- --- First in First Out container --- reference: --- https://github.com/daurnimator/lomp2/blob/master/fifo.lua ------- - -local select , setmetatable = select , setmetatable - -PSBT_Fifo = {} -local mt = -{ - __index = PSBT_Fifo, - __newindex = function( f, k, v ) - if ( type( k ) == 'number' ) then - return rawset( f, k, v ) - end - end, -} - -function PSBT_Fifo.New( ... ) - return setmetatable( { head = 1, tail = select( '#', ... ), ... }, mt ) -end - -function PSBT_Fifo:Size() - return self.tail - self.head + 1 -end - -function PSBT_Fifo:Peek() - return self[ self.head ] -end - -function PSBT_Fifo:Push( value ) - self.tail = self.tail + 1 - self[ self.tail ] = value -end - -function PSBT_Fifo:Pop() - local head, tail = self.head, self.tail - if ( head > tail ) then - return nil - end - - local value = self[ head ] - self[ head ] = nil - self.head = head + 1 - return value -end - -function PSBT_Fifo:Remove( index ) - local head, tail = self.head, self.tail - - if head + index > tail then - return - end - - local position = head + index - 1 - local value = self[ position ] - - if ( position <= (head + tail) * 0.5 ) then - for i = position, head, -1 do - self[ i ] = self[ i - 1 ] - end - self.head = head + 1 - else - for i = position, tail do - self[ i ] = self[ i + 1 ] - end - self.tail = tail - 1 - end - - return value -end - -local iterator = function( fifo, previous ) - local i = fifo.head + previous - if ( i > fifo.tail ) then - return nil - end - - return previous + 1, fifo[ i ] -end - -function PSBT_Fifo:Iterator() - return iterator, self, 0 -end - -mt.__len = PSBT_Fifo.Size \ No newline at end of file diff --git a/core/PSBT_Label.lua b/core/PSBT_Label.lua index 3e4fea0..f76e47e 100644 --- a/core/PSBT_Label.lua +++ b/core/PSBT_Label.lua @@ -19,8 +19,6 @@ function PSBT_Label:Initialize( objectPool ) self.moving = false self.direction = PSBT_SCROLL_DIRECTIONS.UP self.iconPos = PSBT_ICON_SIDE.LEFT - - self.control:SetAlpha( 0.0 ) end function PSBT_Label:SetMoving( set ) @@ -61,6 +59,7 @@ function PSBT_Label:Finalize() self:SetExpire( 0 ) self:SetMoving( false ) self.control:ClearAnchors() + self.control:SetScale( 1.0 ) end function PSBT_Label:SetText( text ) diff --git a/core/PSBT_ScrollArea.lua b/core/PSBT_ScrollArea.lua index d1ad9bf..e87efe9 100644 --- a/core/PSBT_ScrollArea.lua +++ b/core/PSBT_ScrollArea.lua @@ -1,19 +1,15 @@ -local LibAnim = LibStub( 'LibAnimation-1.0' ) -if ( not LibAnim ) then return end - PSBT_ScrollArea = ZO_Object:Subclass() + local CBM = CALLBACK_MANAGER local tinsert = table.insert local tremove = table.remove local NUM_STICKY = 4 - -local PSBT_Fifo = PSBT_Fifo local CENTER = CENTER local BOTTOM = BOTTOM local TOP = TOP - local PSBT_EVENTS = PSBT_EVENTS local PSBT_SCROLL_DIRECTIONS = PSBT_SCROLL_DIRECTIONS +local PSBT_Parabola = PSBT_Parabola function PSBT_ScrollArea:New( ... ) local result = ZO_Object.New( self ) @@ -21,61 +17,37 @@ function PSBT_ScrollArea:New( ... ) return result end -function PSBT_ScrollArea:Initialize( super, areaName, settings ) +function PSBT_ScrollArea:Initialize( super, areaName, settings, fadeIn, fadeOut ) self.name = areaName self.control = super:GetNamedChild( areaName ) self.background = self.control:GetNamedChild( '_BG' ) self.label = self.control:GetNamedChild( '_Name' ) self._newSticky = false self._height = self.control:GetHeight() - self._sticky = PSBT_Fifo.New() - self._pendingSticky = PSBT_Fifo.New() + self._sticky = {} + self._pendingSticky = {} self._normal = {} - self._pendingNormal = PSBT_Fifo.New() - self._direction = settings.dir - self._iconSide = settings.icon - - self._parabolaPoints = PSBT_Parabola:Calculate( self.control:GetHeight(), settings.arc, 50, self._direction ) + self._pendingNormal = {} + self._fadeIn = fadeIn + self._fadeOut = fadeOut - self:Position( settings ) + self:SetSettings( settings ) self:SetConfigurationMode( false ) self.control:SetHandler( 'OnUpdate', function( event, ... ) self:OnUpdate( ... ) end ) CBM:RegisterCallback( PSBT_EVENTS.CONFIG, function( ... ) self:SetConfigurationMode( ... ) end ) end -function PSBT_ScrollArea:InitParabolaAnim( control ) - local anim = LibAnim:New( control ) - - local points = self._parabolaPoints - local x, y = points[1].x, points[1].y - local point = nil - - local duration = 3000 / #points - - for i=1,#points do - point = points[ i ] - anim:TranslateToFrom( x, y, point.x, point.y, duration, (i - 1) * duration ) - - x = point.x - y = point.y - end - - return anim -end - function PSBT_ScrollArea:SetConfigurationMode( enable ) self.control:SetMovable( enable ) self.control:SetMouseEnabled( enable ) self.label:SetHidden( not enable ) if ( enable ) then - local enter = LibAnim:New( self.background ) - enter:AlphaTo( 1.0, 500 ) - enter:Play() + local anim = self._fadeIn:Apply( self.background ) + anim:Play() else - local exit = LibAnim:New( self.background ) - exit:AlphaTo( 0.0, 500 ) - exit:Play() + local anim = self._fadeOut:Apply( self.background ) + anim:Play() end end @@ -103,126 +75,105 @@ function PSBT_ScrollArea:Push( entry, sticky ) entry:SetIconPosition( self._iconSide ) if ( sticky ) then - self._pendingSticky:Push( entry ) + tinsert( self._pendingSticky, entry ) else - self._pendingNormal:Push( entry ) + tinsert( self._pendingNormal, entry ) end end function PSBT_ScrollArea:SetSettings( settings ) - self._iconSide = settings.icon - self._direction = settings.dir - self._parabolaPoints = PSBT_Parabola:Calculate( self.control:GetHeight(), settings.arc, 50, self._direction ) + self._iconSide = settings.icon + self._direction = settings.dir + self._parabola = PSBT_Parabola:New( self.control:GetHeight(), settings.arc, 50, self._direction ) + self:Position( settings ) end function PSBT_ScrollArea:OnUpdate( frameTime ) - if ( not self._sticky:Size() and + if ( not #self._sticky and not #self._normal and - not self._pendingNormal:Size() and - not self._pendingSticky:Size() ) then + not #self._pendingNormal and + not #self._pendingSticky ) then return end - while ( self._sticky:Size() > NUM_STICKY ) do - local old = self._sticky:Pop() - local anim = LibAnim:New( old.control ) - anim:AlphaTo( 0.0, 200 ) - anim:Play() - + while ( #self._sticky > NUM_STICKY ) do + local old = tremove( self._sticky, 1 ) old:SetMoving( false ) old:SetExpire( frameTime + 2 ) self._newSticky = true end - repeat - local entry = self._sticky:Peek() - if ( entry and entry:WillExpire( frameTime + 2 ) ) then - local anim = LibAnim:New( entry.control ) - anim:AlphaTo( 0.0, 200 ) - - local ypos = 0 - if ( self._direction == PSBT_SCROLL_DIRECTIONS.UP ) then - ypos = -100 - elseif ( self._direction == PSBT_SCROLL_DIRECTIONS.DOWN ) then - ypos = 100 - end - - anim:TranslateTo( 0, ypos, 200 ) - anim:ScaleTo( 0.5, 200 ) - anim:Play() - - entry:SetMoving( false ) - - self._sticky:Pop() - self._newSticky = true - end - until( not entry or not entry:WillExpire( frameTime + 2 ) ) - - if ( self._pendingNormal:Size() ) then - local newEntry = self._pendingNormal:Pop() + if ( #self._pendingNormal ) then + local newEntry = tremove( self._pendingNormal, 1 ) if ( newEntry ) then - newEntry:SetExpire( frameTime + 5 ) - local anim = LibAnim:New( newEntry.control ) - anim:AlphaTo( 1.0, 200 ) + newEntry:SetExpire( frameTime + 3 ) + + local anim = self._fadeIn:Apply( newEntry.control ) anim:Play() tinsert( self._normal, newEntry ) end end - if ( self._pendingSticky:Size() ) then - local newEntry = self._pendingSticky:Pop() + if ( #self._pendingSticky ) then + local newEntry = tremove( self._pendingSticky, 1 ) if ( newEntry ) then newEntry:SetExpire( frameTime + 5 ) - newEntry.control:SetScale( 0.5 ) - - local anim = LibAnim:New( newEntry.control ) - anim:AlphaTo( 1.0, 200 ) - anim:ScaleTo( 1.0, 200 ) + local anim = self._fadeIn:Apply( newEntry.control ) anim:Play() - self._sticky:Push( newEntry ) + tinsert( self._sticky, newEntry ) self._newSticky = true end end local i = 1 + local entry = nil + while ( i <= #self._normal ) do - local entry = self._normal[ i ] + entry = self._normal[ i ] - if ( entry:WillExpire( frameTime + 2 ) ) then - local anim = LibAnim:New( entry.control ) - anim:AlphaTo( 0.0, 200, nil, nil, ZO_EaseInOutQuadratic ) + if ( entry:WillExpire( frameTime + 0.5 ) ) then + local anim = self._fadeOut:Apply( entry.control ) anim:Play() entry:SetMoving( false ) - tremove( self._normal, i ) else if ( not entry:IsMoving() ) then - local anim = self:InitParabolaAnim( entry.control ) - anim:ScaleTo( 1.25, 1500 ) - anim:ScaleToFrom( 1.25, 1.0, 1500, 1500 ) + local anim = self._parabola:Apply( entry.control ) anim:Play() - entry:SetMoving( true ) end i = i + 1 end end - local top = 0 - for i, entry in self._sticky:Iterator() do - if ( self._newSticky ) then - local anim = LibAnim:New( entry.control ) - anim:TranslateTo( 0, top, 200 ) - anim:Play() + + i = 1 + local top = 0 - entry:SetMoving( true ) + while ( i <= #self._sticky ) do + entry = self._sticky[ i ] + if ( entry:WillExpire( frameTime + 0.5 ) ) then + local anim = self._fadeOut:Apply( entry.control ) + anim:Play() - top = top + entry:GetHeight() + tremove( self._sticky, i ) + self._newSticky = true + else + if ( self._newSticky ) then + entry.control:SetAnchor( CENTER, self.control, CENTER, 0, top ) + + if ( self._direction == PSBT_SCROLL_DIRECTIONS.UP ) then + top = top - entry:GetHeight() + else + top = top + entry:GetHeight() + end + end + i = i + 1 end end diff --git a/helpers/PSBT_AnimationPool.lua b/helpers/PSBT_AnimationPool.lua new file mode 100644 index 0000000..27860ab --- /dev/null +++ b/helpers/PSBT_AnimationPool.lua @@ -0,0 +1,28 @@ +local ZO_ObjectPool = ZO_ObjectPool +local LibAnim = LibStub( 'LibAnimation-1.0' ) + +PSBT_AnimationPool = ZO_ObjectPool:Subclass() + +function PSBT_AnimationPool:New( create, reset ) + return ZO_ObjectPool.New( self, self.Create, function( ... ) self:Reset( ... ) end ) +end + +function PSBT_AnimationPool:Create() + return LibAnim:New() +end + +function PSBT_AnimationPool:Reset( animation ) + animation:Stop() +end + +function PSBT_AnimationPool:Apply( control ) + local anim, key = self:AcquireObject() + anim:SetUserData( key ) + anim:Apply( control ) + anim:SetHandler( 'OnStop', + function( animation ) + self:ReleaseObject( anim:GetUserData() ) + end ) + + return anim +end \ No newline at end of file diff --git a/helpers/PSBT_Fade.lua b/helpers/PSBT_Fade.lua new file mode 100644 index 0000000..b4cc9d6 --- /dev/null +++ b/helpers/PSBT_Fade.lua @@ -0,0 +1,19 @@ +local PSBT_AnimationPool = PSBT_AnimationPool +PSBT_Fade = PSBT_AnimationPool:Subclass() + +function PSBT_Fade:New( to, from ) + local result = PSBT_AnimationPool.New( self ) + result:Initialize( to, from ) + return result +end + +function PSBT_Fade:Initialize( to, from ) + self._target = to + self._from = from +end + +function PSBT_Fade:Create() + local anim = PSBT_AnimationPool.Create( self ) + anim:AlphaToFrom( self._from, self._target, 200 ) + return anim +end \ No newline at end of file diff --git a/helpers/PSBT_Parabola.lua b/helpers/PSBT_Parabola.lua index a0365ee..f30b456 100644 --- a/helpers/PSBT_Parabola.lua +++ b/helpers/PSBT_Parabola.lua @@ -1,4 +1,5 @@ -PSBT_Parabola = {} +local PSBT_AnimationPool = PSBT_AnimationPool +PSBT_Parabola = PSBT_AnimationPool:Subclass() local PSBT_SCROLL_DIRECTIONS = PSBT_SCROLL_DIRECTIONS @@ -10,24 +11,48 @@ local function _UP( height, progress ) return height - _DOWN( height, progress ) end -function PSBT_Parabola:Calculate( height, width, points, direction ) - local result = {} - local midpoint = height * 0.5 - local fourA = ( midpoint * midpoint ) / width - local fn = nil - if ( direction == PSBT_SCROLL_DIRECTIONS.UP ) then - fn = _UP - else - fn = _DOWN - end - - for i=1,points do - result[ i ] = { x = 0, y = 0 } - result[ i ].y = fn( height, i / points ) - - local y = result[ i ].y - midpoint - result[ i ].x = ( y * y ) / fourA - end - - return result +function PSBT_Parabola:New( height, width, points, direction ) + local result = PSBT_AnimationPool.New( self ) + result:Initialize( height, width, points, direction ) + return result end + +function PSBT_Parabola:Initialize( height, width, points, direction ) + self._parabolaPoints = {} + + local midpoint = height * 0.5 + local fourA = ( midpoint * midpoint ) / width + local fn = nil + if ( direction == PSBT_SCROLL_DIRECTIONS.UP ) then + fn = _UP + else + fn = _DOWN + end + + for i=1,points do + self._parabolaPoints[ i ] = { x = 0, y = 0 } + self._parabolaPoints[ i ].y = fn( height, i / points ) + + local y = self._parabolaPoints[ i ].y - midpoint + self._parabolaPoints[ i ].x = ( y * y ) / fourA + end +end + +function PSBT_Parabola:Create() + local anim = PSBT_AnimationPool.Create( self ) + + local points = self._parabolaPoints + local x, y = points[1].x, points[1].y + local point = nil + local duration = 3000 / #points + + for i=1,#points do + point = points[ i ] + anim:TranslateToFrom( x, y, point.x, point.y, duration, (i - 1) * duration ) + + x = point.x + y = point.y + end + + return anim +end \ No newline at end of file diff --git a/libs/LibAnimation-1.0/LibAnimation.lua b/libs/LibAnimation-1.0/LibAnimation.lua index dd2d5c9..16323dd 100644 --- a/libs/LibAnimation-1.0/LibAnimation.lua +++ b/libs/LibAnimation-1.0/LibAnimation.lua @@ -30,8 +30,8 @@ THE SOFTWARE. ---------------------------------------------------- if ( not LibStub ) then return end -local kName, kVersion = 'LibAnimation-1.0', 2.0 -local LibAnimation = LibStub:NewLibrary( kName, kVersion ) +local kName, kVersion = 'LibAnimation-1.0', 2.1 +local LibAnimation = LibStub:NewLibrary( kName, kVersion ) if ( not LibAnimation ) then return end local AnimationMgr = ANIMATION_MANAGER @@ -44,7 +44,7 @@ local ANIMATION_ALPHA = ANIMATION_ALPHA local _ --- Create a new animation for control --- @tparam table control the gui element to animate +-- @tparam table control (optional) -- @tparam number playbackType (optional) -- @tparam number loopCount (optional) -- @treturn LibAnimation object @@ -66,7 +66,7 @@ function LibAnimation:New( control, playbackType, loopCount ) end --- Animation Constructor --- @tparam table control +-- @tparam table control (optional) -- @tparam number playbackType (optional) -- @tparam number loopCount (optional) function LibAnimation:Initialize( control, playbackType, loopCount ) @@ -75,6 +75,14 @@ function LibAnimation:Initialize( control, playbackType, loopCount ) self.timeline:SetPlaybackType( playbackType, loopCount ) end +function LibAnimation:Apply( control ) + self.timeline:ApplyAllAnimationsToControl( control ) +end + +function LibAnimation:SetHandler( ... ) + self.timeline:SetHandler( ... ) +end + --- Allows you to add a callback at a certain point in the timeline -- @tparam function fn -- @tparam number delay how long to wait before calling @@ -109,12 +117,21 @@ function LibAnimation:Backward() self.timeline:PlayBackward() end +function LibAnimation:SetUserData( data ) + self._udata = data +end + +function LibAnimation:GetUserData() + return self._udata +end + --- Get's the existing animation or creates a new one -- @tparam number animType -- @tparam number delay (optional) -- @tresult animation function LibAnimation:Insert( animType, duration, delay, anchorIndex, fn ) local anim = self.timeline:InsertAnimation( animType, self.control, delay or 0 ) + anim:SetDuration( duration or 1 ) anim:SetEasingFunction( fn or defaultEase )