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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions