1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
if not modules then modules = { } end modules ['supp-ran'] = {
version = 1.001,
comment = "companion to supp-ran.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-- We cannot ask for the current seed, so we need some messy hack here.
local report_system = logs.reporter("system","randomizer")
local trace_random = false trackers.register("system.randomizer", function(v) trace_random = v end)
local trace_detail = false trackers.register("system.randomizer.detail",function(v) trace_detail = v end)
local insert, remove = table.insert, table.remove
local math = math
local context = context
local implement = interfaces.implement
local random = math.random
local randomseed = math.randomseed
local round = math.round
local stack = { }
local last = 1
local maxcount = 2^30-1 -- 1073741823
math.random = function(...)
local n = random(...)
if trace_detail then
report_system("math %s",n)
end
return n
end
local function setrandomseedi(n)
if n <= 1 then
n = n * maxcount
elseif n < 1000 then
n = n * 1000
end
n = round(n)
randomseed(n)
last = random(0,maxcount) -- we need an initial value
if trace_detail then
report_system("seed %s from %s",last,n)
elseif trace_random then
report_system("setting seed %s",n)
end
end
math.setrandomseedi = setrandomseedi
local function getrandomnumber(min,max)
last = random(min,max)
if trace_detail then
report_system("number %s",last)
end
return last
end
local function setrandomseed(n)
last = n
setrandomseedi(n)
end
local function getrandomseed()
return last
end
-- local function getmprandomnumber()
-- last = random(0,4095)
-- if trace_detail then
-- report_system("mp number %s",last)
-- end
-- return last
-- end
-- maybe stack
local function pushrandomseed()
insert(stack,last)
if trace_random or trace_detail then
report_system("pushing seed %s",last)
end
end
local function reuserandomseed(n)
local seed = stack[#stack]
if seed then
if trace_random or trace_detail then
report_system("reusing seed %s",last)
end
randomseed(seed)
end
end
local function poprandomseed()
local seed = remove(stack)
if seed then
if trace_random or trace_detail then
report_system("popping seed %s",seed)
end
randomseed(seed)
end
end
local function getrandom(where,...)
if type(where) == "string" then
local n = random(...)
if trace_detail then
report_system("%s %s",where,n)
end
return n
else
local n = random(where,...)
if trace_detail then
report_system("utilities %s",n)
end
return n
end
end
utilities.randomizer = {
setseedi = setrandomseedi,
getnumber = getrandomnumber,
setseed = setrandomseed,
getseed = getrandomseed,
-- getmpnumber = getmprandomnumber,
pushseed = pushrandomseed,
reuseseed = reuserandomseed,
popseed = poprandomseed,
get = getrandom,
}
-- todo: also open up in utilities.randomizer.*
implement { name = "getrandomnumber", actions = { getrandomnumber, context }, arguments = { "integer", "integer" } }
implement { name = "getrandomdimen", actions = { getrandomnumber, context }, arguments = { "dimen", "dimen" } }
implement { name = "getrandomfloat", actions = { getrandomnumber, context }, arguments = { "number", "number" } }
--------- { name = "getmprandomnumber", actions = { getmprandomnumber, context } }
implement { name = "setrandomseed", actions = { setrandomseed }, arguments = { "integer" } }
implement { name = "getrandomseed", actions = { getrandomseed, context } }
implement { name = "pushrandomseed", actions = { pushrandomseed } }
implement { name = "poprandomseed", actions = { poprandomseed } }
implement { name = "reuserandomseed", actions = { reuserandomseed } }
|