Skip to content
This repository has been archived by the owner on Dec 13, 2023. It is now read-only.

Commit

Permalink
Merge 9100db1 into 41af74d
Browse files Browse the repository at this point in the history
  • Loading branch information
Reselim committed May 4, 2019
2 parents 41af74d + 9100db1 commit f4e5b02
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/Binding.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ local function identity(value)
return value
end

--[[
Maps a table of bindings to their respective values. Used in Binding.join.
]]
local function mapBindingsToValues(bindings)
local values = {}

for key, binding in pairs(bindings) do
values[key] = binding:getValue()
end

return values
end

local Binding = {}

--[[
Expand Down Expand Up @@ -146,4 +159,33 @@ function Binding.create(initialValue)
return binding, setter
end

--[[
Creates a new binding which updates when any of the upstream bindings
updates, which can be further mapped into any value. This function will
be exposed to users of Roact.
]]
function Binding.join(bindings)
local joinedBinding, setter = Binding.create(mapBindingsToValues(bindings))
local internalData = joinedBinding[InternalData]

local upstreamConnections = {}
internalData.upstreamConnections = upstreamConnections

internalData.upstreamDisconnect = function()
for _, disconnect in pairs(upstreamConnections) do
disconnect()
end
end

local function updateBinding()
setter(mapBindingsToValues(bindings))
end

for key, binding in pairs(bindings) do
upstreamConnections[key] = Binding.subscribe(binding, updateBinding)
end

return joinedBinding
end

return Binding
41 changes: 41 additions & 0 deletions src/Binding.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,47 @@ return function()
end)
end)

describe("Binding.join", function()
it("should properly output values", function()
local binding1 = Binding.create(1)
local binding2 = Binding.create(2)

local joinedBinding = Binding.join({
binding1,
binding2,
})

local bindingValue = joinedBinding:getValue()
expect(bindingValue).to.be.a("table")
expect(bindingValue[1]).to.equal(1)
expect(bindingValue[2]).to.equal(2)
end)

it("should update when any one of the subscribed bindings updates", function()
local binding1, update1 = Binding.create(1)
local binding2, update2 = Binding.create(2)

local joinedBinding = Binding.join({
binding1,
binding2,
})

local spy = createSpy()
Binding.subscribe(joinedBinding, spy.value)

expect(spy.callCount).to.equal(0)
update1(3)
expect(spy.callCount).to.equal(1)
update2(4)
expect(spy.callCount).to.equal(2)

local bindingValue = spy.values[1]
expect(bindingValue).to.be.a("table")
expect(bindingValue[1]).to.equal(3)
expect(bindingValue[2]).to.equal(4)
end)
end)

describe("Binding object", function()
it("should provide a getter and setter", function()
local binding, update = Binding.create(1)
Expand Down
1 change: 1 addition & 0 deletions src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ local Roact = strict {
Portal = require(script.Portal),
createRef = require(script.createRef),
createBinding = Binding.create,
joinBindings = Binding.join,

Change = require(script.PropMarkers.Change),
Children = require(script.PropMarkers.Children),
Expand Down
1 change: 1 addition & 0 deletions src/init.spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ return function()
createFragment = "function",
createRef = "function",
createBinding = "function",
joinBindings = "function",
mount = "function",
unmount = "function",
update = "function",
Expand Down

0 comments on commit f4e5b02

Please sign in to comment.