forked from jnwhiteh/astrolabe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDongleStub.lua
More file actions
126 lines (103 loc) · 3.97 KB
/
DongleStub.lua
File metadata and controls
126 lines (103 loc) · 3.97 KB
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
--[[-------------------------------------------------------------------------
James Whitehead II grants anyone the right to use this work for any purpose,
without any conditions, unless such conditions are required by law.
---------------------------------------------------------------------------]]
local major = "DongleStub"
local minor = tonumber(string.match("$Revision: 313 $", "(%d+)") or 1)
local g = getfenv(0)
if not g.DongleStub or g.DongleStub:IsNewerVersion(major, minor) then
local lib = setmetatable({}, {
__call = function(t,k)
if type(t.versions) == "table" and t.versions[k] then
return t.versions[k].instance
else
error("Cannot find a library with name '"..tostring(k).."'", 2)
end
end
})
function lib:IsNewerVersion(major, minor)
local versionData = self.versions and self.versions[major]
-- If DongleStub versions have differing major version names
-- such as DongleStub-Beta0 and DongleStub-1.0-RC2 then a second
-- instance will be loaded, with older logic. This code attempts
-- to compensate for that by matching the major version against
-- "^DongleStub", and handling the version check correctly.
if major:match("^DongleStub") then
local oldmajor,oldminor = self:GetVersion()
if self.versions and self.versions[oldmajor] then
return minor > oldminor
else
return true
end
end
if not versionData then return true end
local oldmajor,oldminor = versionData.instance:GetVersion()
return minor > oldminor
end
local function NilCopyTable(src, dest)
for k,v in pairs(dest) do dest[k] = nil end
for k,v in pairs(src) do dest[k] = v end
end
function lib:Register(newInstance, activate, deactivate)
assert(type(newInstance.GetVersion) == "function",
"Attempt to register a library with DongleStub that does not have a 'GetVersion' method.")
local major,minor = newInstance:GetVersion()
assert(type(major) == "string",
"Attempt to register a library with DongleStub that does not have a proper major version.")
assert(type(minor) == "number",
"Attempt to register a library with DongleStub that does not have a proper minor version.")
-- Generate a log of all library registrations
if not self.log then self.log = {} end
table.insert(self.log, string.format("Register: %s, %s", major, minor))
if not self:IsNewerVersion(major, minor) then return false end
if not self.versions then self.versions = {} end
local versionData = self.versions[major]
if not versionData then
-- New major version
versionData = {
["instance"] = newInstance,
["deactivate"] = deactivate,
}
self.versions[major] = versionData
if type(activate) == "function" then
table.insert(self.log, string.format("Activate: %s, %s", major, minor))
activate(newInstance)
end
return newInstance
end
local oldDeactivate = versionData.deactivate
local oldInstance = versionData.instance
versionData.deactivate = deactivate
local skipCopy
if type(activate) == "function" then
table.insert(self.log, string.format("Activate: %s, %s", major, minor))
skipCopy = activate(newInstance, oldInstance)
end
-- Deactivate the old libary if necessary
if type(oldDeactivate) == "function" then
local major, minor = oldInstance:GetVersion()
table.insert(self.log, string.format("Deactivate: %s, %s", major, minor))
oldDeactivate(oldInstance, newInstance)
end
-- Re-use the old table, and discard the new one
if not skipCopy then
NilCopyTable(newInstance, oldInstance)
end
return oldInstance
end
function lib:GetVersion() return major,minor end
local function Activate(new, old)
-- This code ensures that we'll move the versions table even
-- if the major version names are different, in the case of
-- DongleStub
if not old then old = g.DongleStub end
if old then
new.versions = old.versions
new.log = old.log
end
g.DongleStub = new
end
-- Actually trigger libary activation here
local stub = g.DongleStub or lib
lib = stub:Register(lib, Activate)
end