Skip to content

'reverse' context.wrap support #13

@AndreLouisIssa

Description

@AndreLouisIssa

a primitive implementation of a 'reverse' context.wrap is desired
but it seems like the scope for what this is used for is very narrow

maybe instead the context infrastructure could expose extra tracking information?

non-primitive implementations:

if we don't care about recursion or threads

local tracker_Thing1 = false

local postfix_return_CPS = function(f,...)
  f()
  return ...
end

local function restore_tracker_Thing1()
  tracker_Thing1 = false
end

modutil.mod.Path.Wrap("Thing1"),function(base, ...)
  tracker_Thing1 = true
  return postfix_return_CPS(restore_tracker_Thing1, base(...))
end)

modutil.mod.Path.Wrap("Thing2",function(base, ...)
  if tracker_Thing1 then
    return base(...)
  end
  return your_reverse_wrap(base, ...)
end)

if we care about threads but not recursion

local tracker_Thing1 = setmetatable({},{__mode='k'})

local postfix_return_CPS = function(f,...)
  f()
  return ...
end

local function tracker_Thing1()
  tracker_Thing1[coroutine.running()] = false
end

modutil.mod.Path.Wrap("Thing1"),function(base, ...)
  tracker_Thing1[coroutine.running()] = true
  return postfix_return_CPS(tracker_Thing1, base(...))
end)

modutil.mod.Path.Wrap("Thing2",function(base, ...)
  if tracker_Thing1[coroutine.running()] then
    return base(...)
  end
  return your_reverse_wrap(base, ...)
end)

if we care about recursion but not threads

local tracker_Thing1 = 0

local postfix_return_CPS = function(f,...)
  f()
  return ...
end

local function restore_tracker_Thing1()
  tracker_Thing1 = tracker_Thing1 - 1
end

modutil.mod.Path.Wrap("Thing1"),function(base, ...)
  tracker_Thing1 = tracker_Thing1 + 1
  return postfix_return_CPS(restore_tracker_Thing1, base(...))
end)

modutil.mod.Path.Wrap("Thing2",function(base, ...)
  if tracker_Thing1 > 0 then
    return base(...)
  end
  return your_reverse_wrap(base, ...)
end)

if we care about both threads and recursion

local tracker_Thing1 = setmetatable({},{__mode = 'k'})

local postfix_return_CPS = function(f,...)
  f()
  return ...
end

local function restore_tracker_Thing1()
  local co = coroutine.running()
  local t = tracker_Thing1[co]
  assert(t ~= nil)
  tracker_Thing1[co] = t - 1
end

modutil.mod.Path.Wrap("Thing1"),function(base, ...)
  local co = coroutine.running()
  local t = tracker_Thing1[co] or 0
  tracker_Thing1[co] = t + 1
  return postfix_return_CPS(restore_tracker_Thing1, base(...))
end)

modutil.mod.Path.Wrap("Thing2",function(base, ...)
  local co = coroutine.running()
  local t = tracker_Thing1[co]
  if t ~= nil and t > 0 then
    return base(...)
  end
  return your_reverse_wrap(base, ...)
end)

if we care about both but want to re-use the current context infrasatructure (best late loaded):

local old_Thing2 = modutil.mod.Path.Get("Thing2") -- or rom.game.Thing2 or game.Thing2 or Thing2 etc

modutil.mod.Path.Wrap("Thing2",function(base, ...)
  return your_reverse_wrap(base, ...)
end)

modutil.mod.Path.Context.Wrap.Static("Thing1",function()
  Thing2 = old_Thing2
end)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions