From 91307509d368eaafc7194cadd214278cb4c9d83a Mon Sep 17 00:00:00 2001 From: OverHash <46231745+OverHash@users.noreply.github.com> Date: Mon, 13 Jul 2020 23:12:14 +1200 Subject: [PATCH 1/5] Make didChange.lua --- src/didChange.lua | 50 +++++++++++++++++++++ src/didChange.spec.lua | 99 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/didChange.lua create mode 100644 src/didChange.spec.lua diff --git a/src/didChange.lua b/src/didChange.lua new file mode 100644 index 0000000..0f6b5aa --- /dev/null +++ b/src/didChange.lua @@ -0,0 +1,50 @@ +--[[ + A function that can be used to determine if a new value is equal to the old + value, recursively +]] + +local didChange + +didChange = function(original, new) + -- if both original and new aren't tables, compare + if not (type(original) == 'table' and type(new) == 'table') then + return original ~= new + end + + print(new, type(new), original, type(original)) + + -- compare new to old + for key, value in pairs(new) do + -- check for changed keys + print(key, value, original[key], original[key] ~= value) + if not (type(original[key]) == 'table' and type(value) == 'table') then + if original[key] ~= value then + return true + end + end + + -- repeat for children + if type(value) == 'table' then + return didChange(original[key], value) + end + end + + -- compare old to new + for key, value in pairs(original) do + -- check for changed keys + if not (type(value) == 'table' and type(new[key]) == 'table') then + if value ~= new[key] then + return true + end + end + + -- repeat for children + if type(value) == 'table' then + return didChange(value, new[key]) + end + end + + return false +end + +return didChange diff --git a/src/didChange.spec.lua b/src/didChange.spec.lua new file mode 100644 index 0000000..a85563c --- /dev/null +++ b/src/didChange.spec.lua @@ -0,0 +1,99 @@ +return function() + local didChange = require(script.Parent.didChange) + + it("should return true for changed non-table to non-table values", function() + local original = "hello" + local new = "world" + + local isDifferent = didChange(original, new) + expect(isDifferent).to.equal(true) + end) + + it("should return false for not-changed non-table to non-table values", function() + local original = "hello world" + local new = "hello world" + + local isDifferent = didChange(original, new) + expect(isDifferent).to.equal(false) + end) + + it("should return true for changed table to table values", function() + -- check same key change + local original = { + key = "hello" + } + local new = { + key = "world" + } + + local isDifferent = didChange(original, new) + print('isDiff?', isDifferent) + expect(isDifferent).to.equal(true) + + -- check new key added + original = { + key = "hello" + } + new = { + key = "hello", + otherKey = "world" + } + + isDifferent = didChange(original, new) + print('isDiff2?', isDifferent) + expect(isDifferent).to.equal(true) + + -- check key removed + original = { + key = "hello" + } + new = {} + + isDifferent = didChange(original, new) + print('isDiff3?', isDifferent) + expect(isDifferent).to.equal(true) + + -- check recursive + original = { + data = { + key = "hello" + } + } + new = { + data = { + key = "world" + } + } + + isDifferent = didChange(original, new) + print('isDiff4?', isDifferent) + expect(isDifferent).to.equal(true) + end) + + it("should return false for not changed table to table values", function() + local original = { + key = "hello world" + } + local new = { + key = "hello world" + } + + local isDifferent = didChange(original, new) + expect(isDifferent).to.equal(false) + + -- check recursive + original = { + data = { + key = "hello world" + } + } + new = { + data = { + key = "hello world" + } + } + + isDifferent = didChange(original, new) + expect(isDifferent).to.equal(false) + end) +end From bb57baf2e29733beb3e84de3e3ebf9d2c12b542f Mon Sep 17 00:00:00 2001 From: OverHash <46231745+OverHash@users.noreply.github.com> Date: Mon, 13 Jul 2020 23:12:42 +1200 Subject: [PATCH 2/5] Create spec for not fire changed event on no change --- src/Store.spec.lua | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Store.spec.lua b/src/Store.spec.lua index 5e7a5fd..5e030fa 100644 --- a/src/Store.spec.lua +++ b/src/Store.spec.lua @@ -313,8 +313,13 @@ return function() describe("flush", function() it("should not fire a changed event if there were no dispatches", function() - local store = Store.new(function() - end) + local store = Store.new(function(state, action) + if action.type == 'increment' then + return state + 1 + end + + return state + end, 0) local count = 0 store.changed:connect(function() @@ -338,5 +343,31 @@ return function() store:destruct() end) + + it("should not fire a changed event if the state did not change", function() + local store = Store.new(function(state, action) + return { + state = "non-changed state" + } + end, { + state = "non-changed state" + }) + + local count = 0 + store.changed:connect(function() + print("store changed") + count = count + 1 + end) + + store:dispatch({ + type = "" + }) + + store:flush() + + expect(count).to.equal(0) + + store:destruct() + end) end) end From d4010a91a77c9f5d279fea6a3a36701953c3eeb3 Mon Sep 17 00:00:00 2001 From: OverHash <46231745+OverHash@users.noreply.github.com> Date: Mon, 13 Jul 2020 23:12:56 +1200 Subject: [PATCH 3/5] Check for store changes before running .changed --- src/Store.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Store.lua b/src/Store.lua index 90aa02f..548851e 100644 --- a/src/Store.lua +++ b/src/Store.lua @@ -1,5 +1,6 @@ local RunService = game:GetService("RunService") +local didChange = require(script.Parent.didChange) local Signal = require(script.Parent.Signal) local NoYield = require(script.Parent.NoYield) @@ -86,8 +87,11 @@ function Store:dispatch(action) error("action does not have a type field", 2) end - self._state = self._reducer(self._state, action) - self._mutatedSinceFlush = true + local newState = self._reducer(self._state, action) + if didChange(self._state, newState) then + self._mutatedSinceFlush = true + end + self._state = newState else error(("actions of type %q are not permitted"):format(typeof(action)), 2) end From bb0b23b264fd496a0bdd90fcb155df249bc11a0b Mon Sep 17 00:00:00 2001 From: OverHash <46231745+OverHash@users.noreply.github.com> Date: Tue, 14 Jul 2020 09:36:56 +1200 Subject: [PATCH 4/5] remove print statements --- src/didChange.lua | 3 --- src/didChange.spec.lua | 4 ---- 2 files changed, 7 deletions(-) diff --git a/src/didChange.lua b/src/didChange.lua index 0f6b5aa..b8cabc6 100644 --- a/src/didChange.lua +++ b/src/didChange.lua @@ -11,12 +11,9 @@ didChange = function(original, new) return original ~= new end - print(new, type(new), original, type(original)) - -- compare new to old for key, value in pairs(new) do -- check for changed keys - print(key, value, original[key], original[key] ~= value) if not (type(original[key]) == 'table' and type(value) == 'table') then if original[key] ~= value then return true diff --git a/src/didChange.spec.lua b/src/didChange.spec.lua index a85563c..46bf9ab 100644 --- a/src/didChange.spec.lua +++ b/src/didChange.spec.lua @@ -27,7 +27,6 @@ return function() } local isDifferent = didChange(original, new) - print('isDiff?', isDifferent) expect(isDifferent).to.equal(true) -- check new key added @@ -40,7 +39,6 @@ return function() } isDifferent = didChange(original, new) - print('isDiff2?', isDifferent) expect(isDifferent).to.equal(true) -- check key removed @@ -50,7 +48,6 @@ return function() new = {} isDifferent = didChange(original, new) - print('isDiff3?', isDifferent) expect(isDifferent).to.equal(true) -- check recursive @@ -66,7 +63,6 @@ return function() } isDifferent = didChange(original, new) - print('isDiff4?', isDifferent) expect(isDifferent).to.equal(true) end) From 1ed7417f06b0eb79f3e7643304a4d83298889e0f Mon Sep 17 00:00:00 2001 From: OverHash <46231745+OverHash@users.noreply.github.com> Date: Tue, 14 Jul 2020 10:24:03 +1200 Subject: [PATCH 5/5] Fix didChange to check children of original --- src/didChange.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/didChange.lua b/src/didChange.lua index b8cabc6..e605b98 100644 --- a/src/didChange.lua +++ b/src/didChange.lua @@ -22,7 +22,9 @@ didChange = function(original, new) -- repeat for children if type(value) == 'table' then - return didChange(original[key], value) + if didChange(original[key], value) then + return true + end end end @@ -37,7 +39,9 @@ didChange = function(original, new) -- repeat for children if type(value) == 'table' then - return didChange(value, new[key]) + if didChange(value, new[key]) then + return true + end end end