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