summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua173
1 files changed, 122 insertions, 51 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua b/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
index 485e742b64a..5ebfca87d14 100644
--- a/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
+++ b/Master/texmf-dist/tex/context/base/mkiv/node-ppt.lua
@@ -26,14 +26,12 @@ local getid = nuts.getid
local getnext = nuts.getnext
local getprev = nuts.getprev
local getsubtype = nuts.getsubtype
+local getfield = nuts.getfield
local getlist = nuts.getlist
local setlist = nuts.setlist
-local getprop = nuts.getprop
-
local removenode = nuts.remove
-
-local nextnode = nuts.traversers.node
-local nextwhatsit = nuts.traversers.whatsit
+local traverse = nuts.traverse
+local traverse_id = nuts.traverse_id
local nodecodes = nodes.nodecodes
local whatsitcodes = nodes.whatsitcodes
@@ -41,17 +39,18 @@ local whatsitcodes = nodes.whatsitcodes
local whatsit_code = nodecodes.whatsit
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
-
-local userdefinedwhatsit_code = whatsitcodes.userdefined
+local userdefined_code = whatsitcodes.userdefined
local nodepool = nodes.pool
-local new_usernode = nodepool.usernode
+local new_usernumber = nodepool.usernumber
local variables = interfaces.variables
local v_before = variables.before
local v_after = variables.after
local v_here = variables.here
+local cache = { }
+local nofslots = 0
local property_id = nodepool.userids["property"]
local properties = nodes.properties
@@ -72,8 +71,15 @@ local function register(where,data,...)
where = v_after
end
if data then
+ local data = { where, data, ... }
nofslots = nofslots + 1
- return new_usernode(property_id,{ where, data, ... })
+ if nofslots > 1 then
+ cache[nofslots] = data
+ else
+ -- report("restarting attacher")
+ cache = { data } -- also forces collection
+ end
+ return new_usernumber(property_id,nofslots)
end
end
@@ -102,9 +108,17 @@ local f_delayed = formatters["return function(target,head,where,propdata,paren
local f_immediate = formatters["return function(target,head,where,propdata) %s end"]
local nofdelayed = 0 -- better is to keep track of it per page ... we can have deleted nodes with properties
-local nofslots = 0
function actions.delayed(target,head,where,propdata,code,...) -- this one is used at the tex end
+-- local kind = type(code)
+-- if kind == "string" then
+-- code, err = load(f_delayed(code))
+-- if code then
+-- code = code()
+-- end
+-- elseif kind ~= "function" then
+-- code = nil
+-- end
if code then
local delayed = propdata.delayed
if delayed then
@@ -117,6 +131,15 @@ function actions.delayed(target,head,where,propdata,code,...) -- this one is use
end
function actions.fdelayed(target,head,where,propdata,code,...) -- this one is used at the tex end
+-- local kind = type(code)
+-- if kind == "string" then
+-- code, err = load(f_delayed(code))
+-- if code then
+-- code = code()
+-- end
+-- elseif kind ~= "function" then
+-- code = nil
+-- end
if code then
local delayed = propdata.delayed
if delayed then
@@ -147,41 +170,81 @@ function actions.immediate(target,head,where,propdata,code,...) -- this one is u
end
end
+-- another experiment (a table or function closure are equally efficient); a function
+-- is easier when we want to experiment with different (compatible) implementations
+
+-- local nutpool = nuts.pool
+-- local nut_usernumber = nutpool.usernumber
+
+-- function nodes.nuts.pool.deferredfunction(...)
+-- nofdelayed = nofdelayed + 1
+-- local n = nut_usernumber(property_id,0)
+-- propertydata[n] = { deferred = { ... } }
+-- return n
+-- end
+
+-- function nodes.nuts.pool.deferredfunction(f)
+-- nofdelayed = nofdelayed + 1
+-- local n = nut_usernumber(property_id,0)
+-- propertydata[n] = { deferred = f }
+-- return n
+-- end
+
+-- maybe actions will get parent too
+
local function delayed(head,parent) -- direct based
- for target, id in nextnode, head do
+ for target in traverse(head) do
local p = propertydata[target]
if p then
- local delayed = p.delayed
- if delayed then
- for i=1,#delayed do
- local d = delayed[i]
- local code = d[2]
- local kind = type(code)
- if kind == "string" then
- code, err = load(f_delayed(code))
- if code then
- code = code()
+ -- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v)
+ -- if deferred then
+ -- -- if #deferred > 0 then
+ -- -- deferred[1](unpack(deferred,2))
+ -- -- else
+ -- -- deferred[1]()
+ -- -- end
+ -- deferred()
+ -- p.deferred = false
+ -- if nofdelayed == 1 then
+ -- nofdelayed = 0
+ -- return head
+ -- else
+ -- nofdelayed = nofdelayed - 1
+ -- end
+ -- else
+ local delayed = p.delayed
+ if delayed then
+ for i=1,#delayed do
+ local d = delayed[i]
+ local code = d[2]
+ local kind = type(code)
+ if kind == "string" then
+ code, err = load(f_delayed(code))
+ if code then
+ code = code()
+ end
end
- end
- local where = d[1]
- if where then
- local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent
- if h and h ~= head then
- head = h
+ local where = d[1]
+ if where then
+ local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent
+ if h and h ~= head then
+ head = h
+ end
+ else
+ code(unpack(d,3))
end
+ end
+ p.delayed = nil
+ if nofdelayed == 1 then
+ nofdelayed = 0
+ return head
else
- code(unpack(d,3))
+ nofdelayed = nofdelayed - 1
end
end
- p.delayed = nil
- if nofdelayed == 1 then
- nofdelayed = 0
- return head
- else
- nofdelayed = nofdelayed - 1
- end
- end
+ -- end
end
+ local id = getid(target)
if id == hlist_code or id == vlist_code then
local list = getlist(target)
if list then
@@ -205,13 +268,14 @@ function properties.delayed(head) --
if nofdelayed > 0 then
-- if next(propertydata) then
starttiming(properties)
- head = delayed(head)
+ head = delayed(tonut(head))
stoptiming(properties)
+ return tonode(head), true -- done in shipout anyway
-- else
-- delayed = 0
- -- end
+ -- end
end
- return head
+ return head, false
end
-- more explicit ones too
@@ -220,7 +284,7 @@ local anchored = {
[v_before] = function(n)
while n do
n = getprev(n)
- if getid(n) == whatsit_code and getsubtype(n) == user_code and getprop(n,"id") == property_id then
+ if getid(n) == whatsit_code and getsubtype(n) == user_code and getfield(n,"user_id") == property_id then
-- continue
else
return n
@@ -232,7 +296,7 @@ local anchored = {
n = getnext(n)
if getid(n) == whatsit_code then
local subtype = getsubtype(n)
- if (subtype == userdefinedwhatsit_code and getprop(n,"id") == property_id) then
+ if (subtype == userdefined_code and getfield(n,"user_id") == property_id) then
-- continue
else
return n
@@ -256,22 +320,26 @@ end)
function properties.attach(head)
if nofslots <= 0 then
- return head
+ return head, false
end
+ local done = false
local last = nil
+ local head = tonut(head)
starttiming(properties)
- for source, subtype in nextwhatsit, head do
- if subtype == userdefinedwhatsit_code then
+ for source in traverse_id(whatsit_code,head) do
+ if getsubtype(source) == userdefined_code then
if last then
removenode(head,last,true)
last = nil
end
- if getprop(source,"id") == property_id then
- local data = getprop(source,"data")
+ if getfield(source,"user_id") == property_id then
+ local slot = getfield(source,"value")
+ local data = cache[slot]
if data then
+ cache[slot] = nil
local where = data[1]
local target = anchored[where](source)
if target then
@@ -325,7 +393,7 @@ function properties.attach(head)
target,nodecodes[getid(target)],serialize(propertydata[target],false))
end
end
- if nofslots == 1 then
+ if nofslots == 1 then
nofslots = 0
last = source
break
@@ -344,22 +412,25 @@ function properties.attach(head)
stoptiming(properties)
- return head
+ return head, done
end
+local tasks = nodes.tasks
+
-- maybe better hard coded in-place
+-- tasks.prependaction("processors","before","nodes.properties.attach")
+-- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed")
+
statistics.register("properties processing time", function()
return statistics.elapsedseconds(properties)
end)
-- only for development
--- local tasks = nodes.tasks
---
-- local function show(head,level,report)
--- for target in nextnode, head do
+-- for target in traverse(head) do
-- local p = propertydata[target]
-- if p then
-- report("level %i, node %i, id %s, data %s",