Skip to content

Commit

Permalink
Merge pull request #417 from Quenty/users/quenty/improvements
Browse files Browse the repository at this point in the history
Users/quenty/improvements
  • Loading branch information
Quenty authored Oct 11, 2023
2 parents 299cf25 + 052e8ba commit 589a15c
Show file tree
Hide file tree
Showing 93 changed files with 1,839 additions and 402 deletions.
1 change: 1 addition & 0 deletions games/integration/modules/Server/GameServiceServer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function GameServiceServer:Init(serviceBag)
self._serviceBag:GetService(require("IKService"))

-- Internal
self._serviceBag:GetService(require("GameTranslator"))
self._serviceBag:GetService(require("GameBindersServer"))
end

Expand Down
71 changes: 62 additions & 9 deletions src/animations/src/Shared/AnimationSlotPlayer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local AnimationUtils = require("AnimationUtils")
local ValueObject = require("ValueObject")
local Maid = require("Maid")
local EnumUtils = require("EnumUtils")
local RbxAssetUtils = require("RbxAssetUtils")

local AnimationSlotPlayer = setmetatable({}, BaseObject)
AnimationSlotPlayer.ClassName = "AnimationSlotPlayer"
Expand All @@ -17,14 +18,10 @@ AnimationSlotPlayer.__index = AnimationSlotPlayer
function AnimationSlotPlayer.new(animationTarget)
local self = setmetatable(BaseObject.new(), AnimationSlotPlayer)

self._animationTarget = ValueObject.new(nil)
self._maid:GiveTask(self._animationTarget)

self._defaultFadeTime = ValueObject.new(0.1, "number")
self._maid:GiveTask(self._defaultFadeTime)

self._defaultAnimationPriority = ValueObject.new(nil)
self._maid:GiveTask(self._defaultAnimationPriority)
self._animationTarget = self._maid:Add(ValueObject.new(nil))
self._defaultFadeTime = self._maid:Add(ValueObject.new(0.1, "number"))
self._defaultAnimationPriority = self._maid:Add(ValueObject.new(nil))
self._currentAnimationTrackData = self._maid:Add(ValueObject.new(nil))

if animationTarget then
self:SetAnimationTarget(animationTarget)
Expand All @@ -47,13 +44,54 @@ function AnimationSlotPlayer:SetAnimationTarget(animationTarget)
self._animationTarget:Mount(animationTarget)
end

function AnimationSlotPlayer:AdjustSpeed(id, speed)
assert(RbxAssetUtils.isConvertableToRbxAsset(id), "Bad id")
assert(type(speed) == "number", "Bad number")

local animationId = RbxAssetUtils.toRbxAssetId(id)

local topMaid = Maid.new()

topMaid:GiveTask(self._currentAnimationTrackData:ObserveBrio(function(data)
return data and data.animationId == animationId
end):Subscribe(function(brio)
if brio:IsDead() then
return
end

local data = brio:GetValue()
local maid = brio:ToMaid()

data.track:AdjustSpeed(speed)

-- TODO: Use stack here?
-- TODO: Probably need rogue property mechanisms
maid:GiveTask(function()
if math.abs(data.track.Speed - speed) <= 1e-3 then
data.track:AdjustSpeed(data.originalSpeed)
end
end)
end))

-- TODO: Probably per-a-track instead of global like this
self._maid._currentSpeedAdjustment = topMaid

return function()
if self._maid._currentSpeedAdjustment == topMaid then
self._maid._currentSpeedAdjustment = nil
end
end
end

function AnimationSlotPlayer:Play(id, fadeTime, weight, speed, priority)
fadeTime = fadeTime or self._defaultFadeTime.Value
priority = priority or self._defaultAnimationPriority.Value
weight = weight or 1 -- We need to explicitly adjust the weight here

local topMaid = Maid.new()

local animationId = RbxAssetUtils.toRbxAssetId(id)

topMaid:GiveTask(self._animationTarget:ObserveBrio(function(target)
return target ~= nil
end):Subscribe(function(brio)
Expand All @@ -64,8 +102,23 @@ function AnimationSlotPlayer:Play(id, fadeTime, weight, speed, priority)
local animationTarget = brio:GetValue()
local maid = brio:ToMaid()

local track = AnimationUtils.playAnimation(animationTarget, id, fadeTime, weight, speed, priority)
local track = AnimationUtils.playAnimation(animationTarget, animationId, fadeTime, weight, speed, priority)
if track then
local data = {
animationId = animationId;
track = track;
originalSpeed = speed;
originalWeight = weight;
originalPriority = priority;
}

self._currentAnimationTrackData.Value = data
maid:GiveTask(function()
if self._currentAnimationTrackData.Value == data then
self._currentAnimationTrackData.Value = nil
end
end)

maid:GiveTask(function()
track:AdjustWeight(0, fadeTime or self._defaultFadeTime.Value)
end)
Expand Down
4 changes: 4 additions & 0 deletions src/binder/src/Shared/Binder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ function Binder.new(tagName, constructor, ...)
self._defaultClassType = "Folder"
self.ServiceName = self._tagName .. "Binder"

if Binder.isBinder(self._constructor) then
error("Cannot make a binder that constructs another binder")
end

if select("#", ...) > 0 then
self._args = { ... }
end
Expand Down
130 changes: 108 additions & 22 deletions src/blend/src/Shared/Blend/Blend.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ local StepUtils = require("StepUtils")
local ValueBaseUtils = require("ValueBaseUtils")
local ValueObject = require("ValueObject")
local ValueObjectUtils = require("ValueObjectUtils")
local RxBrioUtils = require("RxBrioUtils")

local Blend = {}

Expand Down Expand Up @@ -624,6 +625,54 @@ function Blend.Children(parent, value)
end
end

--[=[
Allows you to add [CollectionService] tags to a Blend object.
```lua
Blend.New "ScreenGui" {
[Blend.Tags] = { "Hide", "ScreenGui" };
};
```
@param parent Instance
@param value any
@return Observable
]=]
function Blend.Tags(parent, value)
assert(typeof(parent) == "Instance", "Bad parent")

local observe = Blend._observeTags(value, parent)

if observe then
return observe:Pipe({
Rx.tap(function(tag)
if type(tag) == "string" then
parent:AddTag(tag)
else
error("Bad tag")
end
end);
})
else
return Rx.EMPTY
end
end


function Blend._observeTags(tags)
if type(tags) == "string" then
return Rx.of(tags)
elseif type(tags) == "table" then
if Observable.isObservable(tags) then
return tags
else
error("Bad tags")
end
else
error("Bad tags")
end
end

--[=[
Mounts Blend objects into an existing instance.
Expand All @@ -647,56 +696,92 @@ end
maid:GiveTask(Blend.mount(frame, {
Size = UDim2.new(0.5, 0, 0.5, 0);
Blend.Find "MyUIScaleName" {
Blend.Find "UIScale" {
Scale = 2;
};
}))
```
@param name string
:::tip
:::
@param className string
@return function
]=]
function Blend.Find(name)
assert(type(name) == "string", "Bad name")
function Blend.Find(className)
assert(type(className) == "string", "Bad className")

return function(props)
assert(type(props) == "table", "Bad props")
assert(type(props.Name) == "string", "No props.Name")

local mountProps = props
local className
if props.ClassName then
className = props.ClassName
mountProps = table.clone(props)
mountProps.ClassName = nil
else
className = "Instance"
end
-- Return observable and assume we're being used in anexternal context
-- TODO: Maybe not this
if props.Parent then
local propertyObservable = Blend.toPropertyObservable(props.Parent) or Rx.of(props.Parent)

return function(parent)
return RxInstanceUtils.observeChildrenOfNameBrio(parent, className, name):Pipe({
return propertyObservable:Pipe({
RxBrioUtils.toBrio();
RxBrioUtils.where(function(parent)
return parent ~= nil
end);
RxBrioUtils.switchMapBrio(function(parent)
assert(typeof(parent) == "Instance", "Bad parent retrieved during find spec")

return RxInstanceUtils.observeChildrenOfNameBrio(parent, className, props.Name)
end);
Rx.flatMap(function(brio)
if brio:IsDead() then
return
end

local maid = brio:ToMaid()
local instance = brio:GetValue()
maid:GiveTask(Blend.mount(instance, mountProps))
maid:GiveTask(Blend.mount(instance, props))

-- Dead after mounting? Clean up...
-- Probably caused by name change.
if brio:IsDead() then
maid:DoCleaning()
end

-- Avoid emitting anything else so we don't get cleaned up
return Rx.EMPTY
-- Emit back found value (we're used in property scenario)
return Rx.of(instance)
end);
})
end

-- Return callback
return function(parent)
-- TODO: Swap based upon name
-- TODO: Avoid assigning name
return RxInstanceUtils.observeChildrenOfNameBrio(parent, className, props.Name):Pipe({
Blend._mountToFinding(props);
})
end
end
end

function Blend._mountToFinding(props)
return Rx.flatMap(function(brio)
if brio:IsDead() then
return
end

local maid = brio:ToMaid()
local instance = brio:GetValue()
maid:GiveTask(Blend.mount(instance, props))

-- Dead after mounting? Clean up...
-- Probably caused by name change.
if brio:IsDead() then
maid:DoCleaning()
end

-- Avoid emitting anything else so we don't get cleaned up
return Rx.EMPTY
end);
end

--[=[
An event emitter that emits the instance that was actually created. This is
useful for a variety of things.
Expand Down Expand Up @@ -1018,8 +1103,9 @@ end
maid:GiveTask(Blend.mount(frame, {
BackgroundTransparency = 1;
-- All items named InventoryItem
Blend.Find "InventoryItem" {
-- All items named InventoryFrame
Blend.Find "Frame" {
Name = "InventoryFrame"
-- Apply the following properties
Blend.New "UIScale" {
Expand Down
8 changes: 5 additions & 3 deletions src/blend/src/Shared/Test/BlendFind.story.lua
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ return function(target)
CornerRadius = UDim.new(0.05, 0);
};

Blend.Find "CenterFrame" {
Blend.Find "MyUIScale" {
ClassName = "UIScale";
Blend.Find "Frame" {
Name = "CenterFrame";

Blend.Find "UIScale" {
Name = "MyUIScale";

Scale = Blend.Computed(percentVisible, function(percent)
return 0.8 + 0.2*percent
Expand Down
22 changes: 22 additions & 0 deletions src/brio/src/Shared/RxBrioUtils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@ local Rx = require("Rx")

local RxBrioUtils = {}

--[=[
Creates a new observable wrapping the brio
@param callback function
@return Observable<Brio>
]=]
function RxBrioUtils.ofBrio(callback)
return Observable.new(function(sub)
local maid = Maid.new()

if type(callback) == "function" then
local brio = maid:Add(Brio.new(callback(maid)))
sub:Fire(brio)
else
local brio = maid:Add(Brio.new(callback))
sub:Fire(brio)
end

return maid
end)
end

--[=[
Takes a result and converts it to a brio if it is not one.
Expand Down
Loading

0 comments on commit 589a15c

Please sign in to comment.