-- Simple class for xxx in Lua 5.0 -- by Philippe Lhoste http://Phi.Lho.free.fr -- Implementation of the LTN7: Modules & Packages by Roberto Ierusalimschy -- http://www.lua.org/notes/ltn007.html -- Replace ThisClass by the actual name of the class... -- This is a skeleton of class, you have to change the samples given below -- to something meaningful. -- Avoid to load this file twice if ThisClass ~= nil then return end local Public, Private, Meta = {}, {}, {} ThisClass = Public --==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- -- Private generic functions function Private.GetRaw(a, b) return a * 256 + b end function Private.GetParts(x) local p = math.floor(x / 256) return p, x - p * 256 end -- Fill data with missing fields function Private.Update(data) local raw = data.raw data.hb, data.lb = Private.GetParts(raw) end function Private.IsOK(o) return type(o) == "table" and type(o.raw) == "number" end --==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- -- Meta functions -- All accesses to instance objects will redirect to ThisClass if not overloaded Meta.__index = ThisClass -- Return a string representation function Meta.__tostring(self) return string.format("%02x %02x", self.hb, self.lb) end -- Compute the difference function Meta.__sub(a, b) if Private.IsOK(a) and Private.IsOK(b) then return a.raw - b.raw else error("Can only subtract ThisClass objects") end end -- Compare two ThisClass objects (less or equal) function Meta.__le(a, b) if Private.IsOK(a) and Private.IsOK(b) then return a.raw <= b.raw else error("Can only compare two ThisClass objects") end end -- Compare two ThisClass objects (less than) function Meta.__lt(a, b) if Private.IsOK(a) and Private.IsOK(b) then return a.raw < b.raw else error("Can only compare two ThisClass objects") end end -- Compare two ThisClass objects (equal) function Meta.__eq(a, b) if Private.IsOK(a) and Private.IsOK(b) then return a.raw == b.raw else error("Can only compare two ThisClass objects") end end -- Set a field, but update the raw value and all related fields function Meta.__newindex(self, key, value) print("=== NewIndex: ", key, value) if key == "R" or key == "raw" then self.raw = value elseif key == "L" or key == "lb" then self.raw = self.raw + (value - self.lb) elseif key == "H" or key == "hb" then self.raw = self.raw + (value - self.hb) * 256 else -- Unknown additional field rawset(self, key, value) return end Private.Update(self) end --==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- -- Public generic functions function Public.Invert(x) local a, b = Private.GetParts(x) return a + b * 256 end --==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- -- Member functions function Public:Incr(p) p = string.lower(p or '') if p == 'h' then self.raw = self.raw + 256 else self.raw = self.raw + 1 end Private.Update(self) end function Public:Decr(p) p = string.lower(p or '') if p == 'h' then self.raw = self.raw - 256 else self.raw = self.raw - 1 end Private.Update(self) end --==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==-- -- Constructors -- Normal constructor function Public:New(a, b) local obj = { -- Private data raw = Private.GetRaw(a, b), } -- Compute the missing fields in data table Private.Update(obj) -- Attach metamethods to object setmetatable(obj, Meta) return obj end -- Other constructor function Public:Parse(s) if type(s) ~= "string" then error("Can only parse a string!") end local a, b _, _, a, b = string.find(s, "(%x%x).-(%x%x)") a, b = tonumber(a, 16), tonumber(b, 16) return Public:New(a, b) end