diff --git a/lapis/flow.lua b/lapis/flow.lua index ed62561a..f11e2270 100644 --- a/lapis/flow.lua +++ b/lapis/flow.lua @@ -1,7 +1,7 @@ -local type, getmetatable, setmetatable, rawset +local type, getmetatable, setmetatable, rawset, rawget do local _obj_0 = _G - type, getmetatable, setmetatable, rawset = _obj_0.type, _obj_0.getmetatable, _obj_0.setmetatable, _obj_0.rawset + type, getmetatable, setmetatable, rawset, rawget = _obj_0.type, _obj_0.getmetatable, _obj_0.setmetatable, _obj_0.rawset, _obj_0.rawget end local Flow local is_flow @@ -14,6 +14,27 @@ is_flow = function(cls) end return is_flow(cls.__parent) end +local MEMO_KEY = setmetatable({ }, { + __tostring = function() + return "::memo_key::" + end +}) +local memo +memo = function(fn) + return function(self, ...) + local cache = rawget(self, MEMO_KEY) + if not (cache) then + cache = { } + rawset(self, MEMO_KEY, cache) + end + if not (cache[fn]) then + cache[fn] = { + fn(self, ...) + } + end + return unpack(cache[fn]) + end +end do local _class_0 local _base_0 = { @@ -105,5 +126,7 @@ do end return { Flow = Flow, - is_flow = is_flow + is_flow = is_flow, + MEMO_KEY = MEMO_KEY, + memo = memo } diff --git a/lapis/flow.moon b/lapis/flow.moon index d9ade5e0..d6107545 100644 --- a/lapis/flow.moon +++ b/lapis/flow.moon @@ -1,5 +1,5 @@ -import type, getmetatable, setmetatable, rawset from _G +import type, getmetatable, setmetatable, rawset, rawget from _G local Flow @@ -8,7 +8,26 @@ is_flow = (cls) -> return true if cls == Flow is_flow cls.__parent --- a mediator for encapsulating logic between multiple models and a request +MEMO_KEY = setmetatable {}, __tostring: -> "::memo_key::" + +-- make method cached on the instance so that it's not called multiple times +-- FIXME: if expose assigns is enabled, don't write memo to exposed request +memo = (fn) -> + (...) => + cache = rawget @, MEMO_KEY + + unless cache + cache = {} + rawset @, MEMO_KEY, cache + + unless cache[fn] + cache[fn] = {fn @, ...} + + unpack cache[fn] + +-- A flow is a object that forwards all methods and property access that don't +-- exist on the flow to the wrapped object. This allows you to encapsulate +-- functionality within the scope of the Flow class class Flow expose_assigns: false @@ -68,4 +87,4 @@ class Flow setmetatable @, mt -{ :Flow, :is_flow } +{ :Flow, :is_flow, :MEMO_KEY, :memo }