Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f43abc885c | |||
| ed19da4994 | |||
| f435c9942a | |||
| 07c421194e | |||
| 04c17fe1e6 | |||
| 3c2f7491f7 | |||
| 755237c0b7 | |||
| b18716027e | |||
| 8f32923a31 |
13
changes.md
13
changes.md
@ -4,7 +4,7 @@ Table of contents
|
|||||||
---
|
---
|
||||||
[Update 14.1.0 - A whole new world of possibilities](#update-1410---a-whole-new-world-of-possibilities)</br>[Update 14.0.0 - Consistency, Additions and Stability](#update-1400-consistency-additions-and-stability)</br>[Update 13.1.0 - Bug fixes and features added](#update-1310-bug-fixes-and-features-added)</br>[Update 13.0.0 - Added some documentation, and some new features too check it out!](#update-1300-added-some-documentation-and-some-new-features-too-check-it-out)</br>[Update 12.2.2 - Time for some more bug fixes!](#update-1222-time-for-some-more-bug-fixes)</br>[Update 12.2.1 - Time for some bug fixes!](#update-1221-time-for-some-bug-fixes)</br>[Update 12.2.0 - The chains of binding](#update-1220---the-chains-of-binding)</br>[Update 12.1.0 - Threads just can't hold on anymore](#update-1210---threads-just-cant-hold-on-anymore)</br>[Update: 12.0.0 - Big update (Lots of additions some changes)](#update-1200-big-update-lots-of-additions-some-changes)</br>[Update: 1.11.1 - Small Clarification on Love](#update-1111---small-clarification-on-love)</br>[Update: 1.11.0](#update-1110)</br>[Update: 1.10.0](#update-1100)</br>[Update: 1.9.2](#update-192)</br>[Update: 1.9.1 - Threads can now argue](#update-191---threads-can-now-argue)</br>[Update: 1.9.0](#update-190)</br>[Update: 1.8.7](#update-187)</br>[Update: 1.8.6](#update-186)</br>[Update: 1.8.5](#update-185)</br>[Update: 1.8.4](#update-184)</br>[Update: 1.8.3 - Mainloop recieves some needed overhauling](#update-183---mainloop-recieves-some-needed-overhauling)</br>[Update: 1.8.2](#update-182)</br>[Update: 1.8.1](#update-181)</br>[Update: 1.7.6](#update-176)</br>[Update: 1.7.5](#update-175)</br>[Update: 1.7.4](#update-174)</br>[Update: 1.7.3](#update-173)</br>[Update: 1.7.2](#update-172)</br>[Update: 1.7.1 - Bug Fixes Only](#update-171---bug-fixes-only)</br>[Update: 1.7.0 - Threading the systems](#update-170---threading-the-systems)</br>[Update: 1.6.0](#update-160)</br>[Update: 1.5.0](#update-150)</br>[Update: 1.4.1 (4/10/2017) - First Public release of the library](#update-141-4102017---first-public-release-of-the-library)</br>[Update: 1.4.0 (3/20/2017)](#update-140-3202017)</br>[Update: 1.3.0 (1/29/2017)](#update-130-1292017)</br>[Update: 1.2.0 (12.31.2016)](#update-120-12312016)</br>[Update: 1.1.0](#update-110)</br>[Update: 1.0.0](#update-100)</br>[Update: 0.6.3](#update-063)</br>[Update: 0.6.2](#update-062)</br>[Update: 0.6.1-6](#update-061-6)</br>[Update: 0.5.1-6](#update-051-6)</br>[Update: 0.4.1](#update-041)</br>[Update: 0.3.0 - The update that started it all](#update-030---the-update-that-started-it-all)</br>[Update: EventManager 2.0.0](#update-eventmanager-200)</br>[Update: EventManager 1.2.0](#update-eventmanager-120)</br>[Update: EventManager 1.1.0](#update-eventmanager-110)</br>[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)</br>[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different)
|
[Update 14.1.0 - A whole new world of possibilities](#update-1410---a-whole-new-world-of-possibilities)</br>[Update 14.0.0 - Consistency, Additions and Stability](#update-1400-consistency-additions-and-stability)</br>[Update 13.1.0 - Bug fixes and features added](#update-1310-bug-fixes-and-features-added)</br>[Update 13.0.0 - Added some documentation, and some new features too check it out!](#update-1300-added-some-documentation-and-some-new-features-too-check-it-out)</br>[Update 12.2.2 - Time for some more bug fixes!](#update-1222-time-for-some-more-bug-fixes)</br>[Update 12.2.1 - Time for some bug fixes!](#update-1221-time-for-some-bug-fixes)</br>[Update 12.2.0 - The chains of binding](#update-1220---the-chains-of-binding)</br>[Update 12.1.0 - Threads just can't hold on anymore](#update-1210---threads-just-cant-hold-on-anymore)</br>[Update: 12.0.0 - Big update (Lots of additions some changes)](#update-1200-big-update-lots-of-additions-some-changes)</br>[Update: 1.11.1 - Small Clarification on Love](#update-1111---small-clarification-on-love)</br>[Update: 1.11.0](#update-1110)</br>[Update: 1.10.0](#update-1100)</br>[Update: 1.9.2](#update-192)</br>[Update: 1.9.1 - Threads can now argue](#update-191---threads-can-now-argue)</br>[Update: 1.9.0](#update-190)</br>[Update: 1.8.7](#update-187)</br>[Update: 1.8.6](#update-186)</br>[Update: 1.8.5](#update-185)</br>[Update: 1.8.4](#update-184)</br>[Update: 1.8.3 - Mainloop recieves some needed overhauling](#update-183---mainloop-recieves-some-needed-overhauling)</br>[Update: 1.8.2](#update-182)</br>[Update: 1.8.1](#update-181)</br>[Update: 1.7.6](#update-176)</br>[Update: 1.7.5](#update-175)</br>[Update: 1.7.4](#update-174)</br>[Update: 1.7.3](#update-173)</br>[Update: 1.7.2](#update-172)</br>[Update: 1.7.1 - Bug Fixes Only](#update-171---bug-fixes-only)</br>[Update: 1.7.0 - Threading the systems](#update-170---threading-the-systems)</br>[Update: 1.6.0](#update-160)</br>[Update: 1.5.0](#update-150)</br>[Update: 1.4.1 (4/10/2017) - First Public release of the library](#update-141-4102017---first-public-release-of-the-library)</br>[Update: 1.4.0 (3/20/2017)](#update-140-3202017)</br>[Update: 1.3.0 (1/29/2017)](#update-130-1292017)</br>[Update: 1.2.0 (12.31.2016)](#update-120-12312016)</br>[Update: 1.1.0](#update-110)</br>[Update: 1.0.0](#update-100)</br>[Update: 0.6.3](#update-063)</br>[Update: 0.6.2](#update-062)</br>[Update: 0.6.1-6](#update-061-6)</br>[Update: 0.5.1-6](#update-051-6)</br>[Update: 0.4.1](#update-041)</br>[Update: 0.3.0 - The update that started it all](#update-030---the-update-that-started-it-all)</br>[Update: EventManager 2.0.0](#update-eventmanager-200)</br>[Update: EventManager 1.2.0](#update-eventmanager-120)</br>[Update: EventManager 1.1.0](#update-eventmanager-110)</br>[Update: EventManager 1.0.0 - Error checking](#update-eventmanager-100---error-checking)</br>[Version: EventManager 0.0.1 - In The Beginning things were very different](#version-eventmanager-001---in-the-beginning-things-were-very-different)
|
||||||
|
|
||||||
# Update 14.1.0 - A whole new world of possibilities
|
# Update 14.1.3 - A whole new world of possibilities
|
||||||
Full Update Showcase
|
Full Update Showcase
|
||||||
---
|
---
|
||||||
Something I plan on doing each version going forward
|
Something I plan on doing each version going forward
|
||||||
@ -110,6 +110,17 @@ print(func("Hello"))
|
|||||||
print(func("sigh"))
|
print(func("sigh"))
|
||||||
multi:lightloop()
|
multi:lightloop()
|
||||||
```
|
```
|
||||||
|
Bug Fixes:
|
||||||
|
---
|
||||||
|
- 1.14.1
|
||||||
|
- Fixed Issue with Service's task method not being set at creation
|
||||||
|
- 1.14.2
|
||||||
|
- Fixed Issue with connections not returning a connection_link
|
||||||
|
- 1.14.3
|
||||||
|
- Fixed Issue with hold like methods not accepting `false` as a valid return
|
||||||
|
- 1.14.4
|
||||||
|
- Reverted `false not being valid. Broke many things needs to be reworked`
|
||||||
|
|
||||||
Going Forward:
|
Going Forward:
|
||||||
---
|
---
|
||||||
- Finish the network manager
|
- Finish the network manager
|
||||||
|
|||||||
353
multi/init.lua
353
multi/init.lua
@ -28,8 +28,8 @@ local thread = {}
|
|||||||
if not _G["$multi"] then
|
if not _G["$multi"] then
|
||||||
_G["$multi"] = {multi=multi,thread=thread}
|
_G["$multi"] = {multi=multi,thread=thread}
|
||||||
end
|
end
|
||||||
multi.Version = "14.1.0"
|
multi.Version = "14.1.4"
|
||||||
multi._VERSION = "14.1.0"
|
multi._VERSION = "14.1.4"
|
||||||
multi.stage = "stable"
|
multi.stage = "stable"
|
||||||
multi.__index = multi
|
multi.__index = multi
|
||||||
multi.Name = "multi.root"
|
multi.Name = "multi.root"
|
||||||
@ -620,7 +620,9 @@ function multi:isDone()
|
|||||||
end
|
end
|
||||||
multi.IsDone=multi.isDone
|
multi.IsDone=multi.isDone
|
||||||
function multi:create(ref)
|
function multi:create(ref)
|
||||||
multi.OnObjectCreated:Fire(ref,self)
|
if multi.OnObjectCreated then
|
||||||
|
multi.OnObjectCreated:Fire(ref,self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
function multi:setName(name)
|
function multi:setName(name)
|
||||||
self.Name = name
|
self.Name = name
|
||||||
@ -628,6 +630,176 @@ function multi:setName(name)
|
|||||||
end
|
end
|
||||||
multi.SetName = multi.setName
|
multi.SetName = multi.setName
|
||||||
--Constructors [CORE]
|
--Constructors [CORE]
|
||||||
|
local CRef = {
|
||||||
|
Fire = function() end
|
||||||
|
}
|
||||||
|
function multi:newConnection(protect,func,kill)
|
||||||
|
local c={}
|
||||||
|
c.callback = func
|
||||||
|
c.Parent=self
|
||||||
|
c.lock = false
|
||||||
|
setmetatable(c,{__call=function(self,...)
|
||||||
|
local t = ...
|
||||||
|
if type(t)=="table" then
|
||||||
|
for i,v in pairs(t) do
|
||||||
|
if v==self then
|
||||||
|
return self:Fire(select(2,...))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self:connect(...)
|
||||||
|
else
|
||||||
|
return self:connect(...)
|
||||||
|
end
|
||||||
|
end})
|
||||||
|
c.Type='connector'
|
||||||
|
c.func={}
|
||||||
|
c.ID=0
|
||||||
|
c.protect=protect or true
|
||||||
|
c.connections={}
|
||||||
|
c.fconnections={}
|
||||||
|
c.FC=0
|
||||||
|
function c:holdUT(n)
|
||||||
|
local n=n or 0
|
||||||
|
self.waiting=true
|
||||||
|
local count=0
|
||||||
|
local id=self:connect(function()
|
||||||
|
count = count + 1
|
||||||
|
if n<=count then
|
||||||
|
self.waiting=false
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
repeat
|
||||||
|
self.Parent:uManager(multi.defaultSettings)
|
||||||
|
until self.waiting==false
|
||||||
|
id:Destroy()
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
c.HoldUT=c.holdUT
|
||||||
|
function c:fConnect(func)
|
||||||
|
local temp=self:connect(func)
|
||||||
|
table.insert(self.fconnections,temp)
|
||||||
|
self.FC=self.FC+1
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
c.FConnect=c.fConnect
|
||||||
|
function c:getConnection(name,ignore)
|
||||||
|
if ignore then
|
||||||
|
return self.connections[name] or CRef
|
||||||
|
else
|
||||||
|
return self.connections[name] or self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function c:Lock()
|
||||||
|
c.lock = true
|
||||||
|
end
|
||||||
|
function c:Unlock()
|
||||||
|
c.lock = false
|
||||||
|
end
|
||||||
|
function c:Fire(...)
|
||||||
|
local ret={}
|
||||||
|
if self.lock then return end
|
||||||
|
for i=#self.func,1,-1 do
|
||||||
|
if self.protect then
|
||||||
|
if not self.func[i] then return end
|
||||||
|
local temp={pcall(self.func[i][1],...)}
|
||||||
|
if temp[1] then
|
||||||
|
table.remove(temp,1)
|
||||||
|
table.insert(ret,temp)
|
||||||
|
else
|
||||||
|
multi.print(temp[2])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not self.func[i] then return end
|
||||||
|
table.insert(ret,{self.func[i][1](...)})
|
||||||
|
end
|
||||||
|
if kill then
|
||||||
|
table.remove(self.func,i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
function c:Bind(t)
|
||||||
|
self.func=t
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
function c:Remove()
|
||||||
|
self.func={}
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
local function conn_helper(self,func,name,num)
|
||||||
|
self.ID=self.ID+1
|
||||||
|
if num then
|
||||||
|
table.insert(self.func,num,{func,self.ID})
|
||||||
|
else
|
||||||
|
table.insert(self.func,1,{func,self.ID})
|
||||||
|
end
|
||||||
|
local temp = {
|
||||||
|
Link=self.func,
|
||||||
|
func=func,
|
||||||
|
Type="connector_link",
|
||||||
|
ID=self.ID,
|
||||||
|
Parent=self,
|
||||||
|
}
|
||||||
|
function temp:Fire(...)
|
||||||
|
if self.Parent.lock then return end
|
||||||
|
if self.Parent.protect then
|
||||||
|
local t=pcall(self.func,...)
|
||||||
|
if t then
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return self.func(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function temp:Destroy()
|
||||||
|
for i=1,#self.Link do
|
||||||
|
if self.Link[i][2]~=nil then
|
||||||
|
if self.Link[i][2]==self.ID then
|
||||||
|
table.remove(self.Link,i)
|
||||||
|
self.remove=function() end
|
||||||
|
self.Link=nil
|
||||||
|
self.ID=nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if name then
|
||||||
|
self.connections[name]=temp
|
||||||
|
end
|
||||||
|
if self.callback then
|
||||||
|
self.callback(temp)
|
||||||
|
end
|
||||||
|
return temp
|
||||||
|
end
|
||||||
|
function c:connect(...)--func,name,num
|
||||||
|
local tab = {...}
|
||||||
|
local funcs={}
|
||||||
|
for i=1,#tab do
|
||||||
|
if type(tab[i])=="function" then
|
||||||
|
funcs[#funcs+1] = tab[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #funcs>1 then
|
||||||
|
local ret = {}
|
||||||
|
for i=1,#funcs do
|
||||||
|
table.insert(ret,conn_helper(self,funcs[i]))
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
else
|
||||||
|
return conn_helper(self,tab[1],tab[2],tab[3])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
c.Connect=c.connect
|
||||||
|
c.GetConnection=c.getConnection
|
||||||
|
if not(ignoreconn) then
|
||||||
|
multi:create(c)
|
||||||
|
end
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
multi.OnObjectCreated=multi:newConnection()
|
||||||
|
multi.OnObjectDestroyed=multi:newConnection()
|
||||||
local _tid = 0
|
local _tid = 0
|
||||||
function multi:newBase(ins)
|
function multi:newBase(ins)
|
||||||
if not(self.Type=='mainprocess' or self.Type=='process' or self.Type=='queue') then error('Can only create an object on multi or an interface obj') return false end
|
if not(self.Type=='mainprocess' or self.Type=='process' or self.Type=='queue') then error('Can only create an object on multi or an interface obj') return false end
|
||||||
@ -770,179 +942,6 @@ function multi:newConnector()
|
|||||||
local c = {Type = "connector"}
|
local c = {Type = "connector"}
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
local CRef = {
|
|
||||||
Fire = function() end
|
|
||||||
}
|
|
||||||
function multi:newConnection(protect,func,kill)
|
|
||||||
local c={}
|
|
||||||
c.callback = func
|
|
||||||
c.Parent=self
|
|
||||||
c.lock = false
|
|
||||||
setmetatable(c,{__call=function(self,...)
|
|
||||||
local t = ...
|
|
||||||
if type(t)=="table" then
|
|
||||||
for i,v in pairs(t) do
|
|
||||||
if v==self then
|
|
||||||
return self:Fire(select(2,...))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return self:connect(...)
|
|
||||||
else
|
|
||||||
return self:connect(...)
|
|
||||||
end
|
|
||||||
end})
|
|
||||||
c.Type='connector'
|
|
||||||
c.func={}
|
|
||||||
c.ID=0
|
|
||||||
c.protect=protect or true
|
|
||||||
c.connections={}
|
|
||||||
c.fconnections={}
|
|
||||||
c.FC=0
|
|
||||||
function c:holdUT(n)
|
|
||||||
local n=n or 0
|
|
||||||
self.waiting=true
|
|
||||||
local count=0
|
|
||||||
local id=self:connect(function()
|
|
||||||
count = count + 1
|
|
||||||
if n<=count then
|
|
||||||
self.waiting=false
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
repeat
|
|
||||||
self.Parent:uManager(multi.defaultSettings)
|
|
||||||
until self.waiting==false
|
|
||||||
id:Destroy()
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
c.HoldUT=c.holdUT
|
|
||||||
function c:fConnect(func)
|
|
||||||
local temp=self:connect(func)
|
|
||||||
table.insert(self.fconnections,temp)
|
|
||||||
self.FC=self.FC+1
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
c.FConnect=c.fConnect
|
|
||||||
function c:getConnection(name,ignore)
|
|
||||||
if ignore then
|
|
||||||
return self.connections[name] or CRef
|
|
||||||
else
|
|
||||||
return self.connections[name] or self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function c:Lock()
|
|
||||||
c.lock = true
|
|
||||||
end
|
|
||||||
function c:Unlock()
|
|
||||||
c.lock = false
|
|
||||||
end
|
|
||||||
function c:Fire(...)
|
|
||||||
local ret={}
|
|
||||||
if self.lock then return end
|
|
||||||
for i=#self.func,1,-1 do
|
|
||||||
if self.protect then
|
|
||||||
if not self.func[i] then return end
|
|
||||||
local temp={pcall(self.func[i][1],...)}
|
|
||||||
if temp[1] then
|
|
||||||
table.remove(temp,1)
|
|
||||||
table.insert(ret,temp)
|
|
||||||
else
|
|
||||||
multi.print(temp[2])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if not self.func[i] then return end
|
|
||||||
table.insert(ret,{self.func[i][1](...)})
|
|
||||||
end
|
|
||||||
if kill then
|
|
||||||
table.remove(self.func,i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
function c:Bind(t)
|
|
||||||
self.func=t
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
function c:Remove()
|
|
||||||
self.func={}
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
local function conn_helper(self,func,name,num)
|
|
||||||
self.ID=self.ID+1
|
|
||||||
if num then
|
|
||||||
table.insert(self.func,num,{func,self.ID})
|
|
||||||
else
|
|
||||||
table.insert(self.func,1,{func,self.ID})
|
|
||||||
end
|
|
||||||
local temp = {
|
|
||||||
Link=self.func,
|
|
||||||
func=func,
|
|
||||||
ID=self.ID,
|
|
||||||
Parent=self,
|
|
||||||
Fire=function(self,...)
|
|
||||||
if self.Parent.lock then return end
|
|
||||||
if self.Parent.protect then
|
|
||||||
local t=pcall(self.func,...)
|
|
||||||
if t then
|
|
||||||
return t
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return self.func(...)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
Remove=function(self)
|
|
||||||
for i=1,#self.Link do
|
|
||||||
if self.Link[i][2]~=nil then
|
|
||||||
if self.Link[i][2]==self.ID then
|
|
||||||
table.remove(self.Link,i)
|
|
||||||
self.remove=function() end
|
|
||||||
self.Link=nil
|
|
||||||
self.ID=nil
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
temp.Destroy=temp.Remove
|
|
||||||
if name then
|
|
||||||
self.connections[name]=temp
|
|
||||||
end
|
|
||||||
if self.callback then
|
|
||||||
self.callback(temp)
|
|
||||||
end
|
|
||||||
return temp
|
|
||||||
end
|
|
||||||
function c:connect(...)--func,name,num
|
|
||||||
local tab = {...}
|
|
||||||
local funcs={}
|
|
||||||
for i=1,#tab do
|
|
||||||
if type(tab[i])=="function" then
|
|
||||||
funcs[#funcs+1] = tab[i]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #funcs>1 then
|
|
||||||
local ret = {}
|
|
||||||
for i=1,#funcs do
|
|
||||||
table.insert(ret,conn_helper(self,funcs[i]))
|
|
||||||
end
|
|
||||||
return ret
|
|
||||||
else
|
|
||||||
conn_helper(self,tab[1],tab[2],tab[3])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
c.Connect=c.connect
|
|
||||||
c.GetConnection=c.getConnection
|
|
||||||
function c:tofile(path)
|
|
||||||
local m=bin.new()
|
|
||||||
m:addBlock(self.Type)
|
|
||||||
m:addBlock(self.func)
|
|
||||||
m:tofile(path)
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
return c
|
|
||||||
end
|
|
||||||
multi.OnObjectCreated=multi:newConnection()
|
|
||||||
multi.OnObjectDestroyed=multi:newConnection()
|
|
||||||
function multi:newJob(func,name)
|
function multi:newJob(func,name)
|
||||||
if not(self.Type=='mainprocess' or self.Type=='process') then error('Can only create an object on multi or an interface obj') return false end
|
if not(self.Type=='mainprocess' or self.Type=='process') then error('Can only create an object on multi or an interface obj') return false end
|
||||||
local c = {}
|
local c = {}
|
||||||
@ -1819,7 +1818,7 @@ function multi:newService(func) -- Priority managed threads
|
|||||||
local time
|
local time
|
||||||
local p = multi.Priority_Normal
|
local p = multi.Priority_Normal
|
||||||
local ap
|
local ap
|
||||||
local task
|
local task = thread.sleep
|
||||||
local scheme = 1
|
local scheme = 1
|
||||||
function c.Start()
|
function c.Start()
|
||||||
time = multi:newTimer()
|
time = multi:newTimer()
|
||||||
|
|||||||
@ -103,7 +103,7 @@ function multi:newSystemThreadedJobQueue(n)
|
|||||||
end)
|
end)
|
||||||
return thread.hold(function()
|
return thread.hold(function()
|
||||||
if rets then
|
if rets then
|
||||||
return unpack(rets)
|
return unpack(rets) or multi.NIL
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end,holup),name
|
end,holup),name
|
||||||
|
|||||||
@ -121,7 +121,7 @@ function multi:newSystemThreadedJobQueue(n)
|
|||||||
end)
|
end)
|
||||||
return thread.hold(function()
|
return thread.hold(function()
|
||||||
if rets then
|
if rets then
|
||||||
return unpack(rets)
|
return unpack(rets) or multi.NIL
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end,holup),name
|
end,holup),name
|
||||||
|
|||||||
15
multitut.lua
15
multitut.lua
@ -1,15 +0,0 @@
|
|||||||
package.path="?/init.lua;?.lua;"..package.path
|
|
||||||
local multi = require("multi")
|
|
||||||
--~ local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
|
|
||||||
--~ nGLOBAL = require("multi.integration.networkManager").init()
|
|
||||||
|
|
||||||
|
|
||||||
local a = 0
|
|
||||||
local clock = os.clock
|
|
||||||
b = clock()
|
|
||||||
while clock()-b <1 do
|
|
||||||
a = a +1
|
|
||||||
end
|
|
||||||
print("a: "..a)
|
|
||||||
--~ multi:benchMark(1,nil,"Bench:")
|
|
||||||
--~ multi:mainloop()
|
|
||||||
570
time/init.lua
570
time/init.lua
@ -1,570 +0,0 @@
|
|||||||
--------------------------------------------------------------------------------
|
|
||||||
-- A library for the manipulation of dates and periods according to the
|
|
||||||
-- Gregorian calendar.
|
|
||||||
--
|
|
||||||
-- Credit: the Gregorian calendar routines contained in this library are
|
|
||||||
-- ported from Claus Tøndering calendar algorithms:
|
|
||||||
-- http://www.tondering.dk/main/index.php/calendar-information .
|
|
||||||
--
|
|
||||||
-- Copyright (C) 2011-2016 Stefano Peluchetti. All rights reserved.
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
local ffi = require "ffi"
|
|
||||||
|
|
||||||
local C = ffi.C
|
|
||||||
local format = string.format
|
|
||||||
local floor, min = math.floor, math.min
|
|
||||||
local type, new, istype, tonumber = type, ffi.new, ffi.istype, tonumber
|
|
||||||
|
|
||||||
local int64_ct = ffi.typeof("int64_t")
|
|
||||||
|
|
||||||
local function T_int(x)
|
|
||||||
if not (type(x) == "number" and x == floor(x)) then
|
|
||||||
error("integer number expected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function T_same(x, y)
|
|
||||||
if not istype(x, y) then
|
|
||||||
error("same type expected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Period ----------------------------------------------------------------------
|
|
||||||
-- Return string representation for a positive period.
|
|
||||||
local function posptostr(h, m, s, ms)
|
|
||||||
return format("%02i:%02i:%02i.%06i", h, m, s, ms)
|
|
||||||
end
|
|
||||||
|
|
||||||
local p_ct
|
|
||||||
|
|
||||||
local function T_period(x)
|
|
||||||
if not istype(p_ct, x) then
|
|
||||||
error("period expected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function p_64(ticks)
|
|
||||||
return new(p_ct, ticks)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function pfirst(x, y)
|
|
||||||
if istype(p_ct, y) then
|
|
||||||
return y, x
|
|
||||||
else
|
|
||||||
return x, y
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local p_mt = {
|
|
||||||
__new = function(ct, h, m, s, ms)
|
|
||||||
h = h or 0; m = m or 0; s = s or 0; ms = ms or 0;
|
|
||||||
T_int(h); T_int(m); T_int(s); T_int(ms);
|
|
||||||
return new(ct, h*(1e6*60*60LL)+m*(1e6*60LL)+s*(1e6*1LL)+ms)
|
|
||||||
end,
|
|
||||||
copy = function(self)
|
|
||||||
return new(p_ct, self)
|
|
||||||
end,
|
|
||||||
__eq = function(self, rhs) T_same(self, rhs)
|
|
||||||
return self._ticks == rhs._ticks
|
|
||||||
end,
|
|
||||||
__lt = function(self, rhs) T_same(self, rhs)
|
|
||||||
return self._ticks < rhs._ticks
|
|
||||||
end,
|
|
||||||
__le = function(self, rhs) T_same(self, rhs)
|
|
||||||
return self._ticks <= rhs._ticks
|
|
||||||
end,
|
|
||||||
__add = function(self, rhs) T_same(self, rhs) -- Commutative.
|
|
||||||
return p_64(self._ticks + rhs._ticks)
|
|
||||||
end,
|
|
||||||
__sub = function(self, rhs) T_same(self, rhs)
|
|
||||||
return p_64(self._ticks - rhs._ticks)
|
|
||||||
end,
|
|
||||||
__unm = function(self)
|
|
||||||
return p_64(-self._ticks)
|
|
||||||
end,
|
|
||||||
__mul = function(self, rhs) -- Commutative.
|
|
||||||
local p, n = pfirst(self, rhs)
|
|
||||||
T_int(n)
|
|
||||||
return p_64(p._ticks*n)
|
|
||||||
end,
|
|
||||||
-- Approximate ratio, non-reversible in both cases.
|
|
||||||
__div = function(self, rhs)
|
|
||||||
T_period(self) -- Disallow (not-a-period)/period.
|
|
||||||
if type(rhs) == "number" then
|
|
||||||
return p_64(self._ticks/rhs)
|
|
||||||
elseif istype(p_ct, rhs) then
|
|
||||||
return tonumber(self._ticks)/tonumber(rhs._ticks)
|
|
||||||
else
|
|
||||||
error("unexpected type")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
__tostring = function(self)
|
|
||||||
local h, m, s, ms = self:parts()
|
|
||||||
if self._ticks >= 0 then
|
|
||||||
return posptostr(h, m, s, ms)
|
|
||||||
else
|
|
||||||
return "-"..posptostr(-h, -m, -s, -ms)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
ticks = function(self) -- Expose int64_t.
|
|
||||||
return self._ticks
|
|
||||||
end,
|
|
||||||
microseconds = function(self)
|
|
||||||
return tonumber(self._ticks%1e6)
|
|
||||||
end,
|
|
||||||
seconds = function(self)
|
|
||||||
return tonumber((self._ticks/1e6)%60)
|
|
||||||
end,
|
|
||||||
minutes = function(self)
|
|
||||||
return tonumber((self._ticks/(1e6*60))%60)
|
|
||||||
end,
|
|
||||||
hours = function(self)
|
|
||||||
return tonumber(self._ticks/(1e6*60*60))
|
|
||||||
end,
|
|
||||||
parts = function(self)
|
|
||||||
return self:hours(), self:minutes(), self:seconds(), self:microseconds()
|
|
||||||
end,
|
|
||||||
tomicroseconds = function(self)
|
|
||||||
return tonumber(self._ticks)
|
|
||||||
end,
|
|
||||||
tomilliseconds = function(self)
|
|
||||||
return tonumber(self._ticks)/1e3
|
|
||||||
end,
|
|
||||||
toseconds = function(self)
|
|
||||||
return tonumber(self._ticks)/1e6
|
|
||||||
end,
|
|
||||||
tominutes = function(self)
|
|
||||||
return tonumber(self._ticks)/(1e6*60)
|
|
||||||
end,
|
|
||||||
tohours = function(self)
|
|
||||||
return tonumber(self._ticks)/(1e6*60*60)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
p_mt.__index = p_mt
|
|
||||||
|
|
||||||
p_ct = ffi.metatype("struct { int64_t _ticks; }", p_mt)
|
|
||||||
|
|
||||||
local function weeks(x) T_int(x) return p_64(x*(1e6*60*60*24*7LL)) end
|
|
||||||
local function days(x) T_int(x) return p_64(x*(1e6*60*60*24LL)) end
|
|
||||||
local function hours(x) T_int(x) return p_64(x*(1e6*60*60LL)) end
|
|
||||||
local function minutes(x) T_int(x) return p_64(x*(1e6*60LL)) end
|
|
||||||
local function seconds(x) T_int(x) return p_64(x*(1e6*1LL)) end
|
|
||||||
local function milliseconds(x) T_int(x) return p_64(x*(1e3*1LL)) end
|
|
||||||
local function microseconds(x) T_int(x) return p_64(x*1LL) end
|
|
||||||
|
|
||||||
local function toperiod(x)
|
|
||||||
if type(x) == "string" then
|
|
||||||
local f1, l1, h, m, s, ms = x:find("(%d+):(%d+):(%d+).(%d+)")
|
|
||||||
if h == nil or ms == nil or l1 ~= #x then
|
|
||||||
error("'"..x.."' is not a string representation of a period")
|
|
||||||
end
|
|
||||||
local ton = tonumber
|
|
||||||
return p_ct(ton(h), ton(m), ton(s), ton(ms))
|
|
||||||
elseif istype(int64_ct, x) then
|
|
||||||
return p_64(x)
|
|
||||||
else
|
|
||||||
error("unexpected type")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Months ----------------------------------------------------------------------
|
|
||||||
local months_mt = {
|
|
||||||
__new = function(ct, x) T_int(x)
|
|
||||||
return new(ct, x)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local months_ct = ffi.metatype("struct { int32_t _m; }", months_mt)
|
|
||||||
|
|
||||||
-- Years -----------------------------------------------------------------------
|
|
||||||
local years_mt = {
|
|
||||||
__new = function(ct, x) T_int(x)
|
|
||||||
return new(ct, x)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local years_ct = ffi.metatype("struct { int32_t _y; }", years_mt)
|
|
||||||
|
|
||||||
-- Date ------------------------------------------------------------------------
|
|
||||||
-- It's date(1582, 1, 1):
|
|
||||||
local d_ticks_min = 198622713600000000LL
|
|
||||||
-- It's date(9999,12,31) + period(23, 59, 59, 999999):
|
|
||||||
local d_ticks_max = 464269103999999999LL
|
|
||||||
|
|
||||||
local d_ct
|
|
||||||
|
|
||||||
local function T_date(x)
|
|
||||||
if not istype(d_ct, x) then
|
|
||||||
error("date expected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function T_date_range(ticks)
|
|
||||||
if not (d_ticks_min <= ticks and ticks <= d_ticks_max) then
|
|
||||||
error("resulting date is outside the allowed range")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function d_64(ticks) T_date_range(ticks)
|
|
||||||
return new(d_ct, ticks)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function dfirst(x, y)
|
|
||||||
if istype(d_ct, y) then
|
|
||||||
return y, x
|
|
||||||
else
|
|
||||||
return x, y
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 1582 adoption, 9999 to keep 4 chars for years part:
|
|
||||||
local function T_year(year) T_int(year)
|
|
||||||
if not (1582 <= year and year <= 9999) then
|
|
||||||
error("year "..year.." outside the allowed range [1582, 9999]")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function T_month(month) T_int(month)
|
|
||||||
if not (1 <= month and month <= 12) then
|
|
||||||
error("month "..month.." outside the allowed range [1, 12]")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function isleapyear(year) T_year(year)
|
|
||||||
return year%4 == 0 and (year%100 ~= 0 or year%400 == 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
local eom = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
|
||||||
|
|
||||||
local function endofmonth(year, month) T_year(year) T_month(month)
|
|
||||||
return (month == 2 and isleapyear(year)) and 29 or eom[month]
|
|
||||||
end
|
|
||||||
|
|
||||||
local function T_day(year, month, day)
|
|
||||||
if not (1 <= day and day <= endofmonth(year, month)) then
|
|
||||||
error(year.."-"..month.."-"..day.." is not a valid date")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function weekday(year, month, day) T_year(year) T_month(month)
|
|
||||||
T_day(year, month, day)
|
|
||||||
local a = floor((14 - month)/12)
|
|
||||||
local y = year - a
|
|
||||||
local m = month + 12*a - 2
|
|
||||||
local d = (day + y + floor(y/4) - floor(y/100) + floor(y/400) +
|
|
||||||
floor((31*m)/12)) % 7
|
|
||||||
return d == 0 and 7 or d -- Days of week from 1 = Monday to 7 = Sunday.
|
|
||||||
end
|
|
||||||
|
|
||||||
local function shift_months(y, m, deltam)
|
|
||||||
local newm = (m - 1 + deltam) % 12 + 1
|
|
||||||
local newy = y + floor((m - 1 + deltam)/12)
|
|
||||||
T_year(newy)
|
|
||||||
T_month(newm)
|
|
||||||
return newy, newm
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ymd_to_julian(year, month, day)
|
|
||||||
-- Range of numbers suffices for this:
|
|
||||||
local a = floor((14 - month)/12)
|
|
||||||
local y = year + 4800 - a
|
|
||||||
local m = month + 12*a - 3
|
|
||||||
return day + floor((153*m + 2)/5) + 365*y + floor(y/4) - floor(y/100) +
|
|
||||||
floor(y/400) - 32045
|
|
||||||
end
|
|
||||||
|
|
||||||
local function julian_to_ymd(julian)
|
|
||||||
-- Range of numbers suffices for this:
|
|
||||||
local a = julian + 32044
|
|
||||||
local b = floor((4*a + 3)/146097)
|
|
||||||
local c = a - floor((146097*b)/4)
|
|
||||||
local d = floor((4*c + 3)/1461)
|
|
||||||
local e = c - floor((1461*d)/4)
|
|
||||||
local m = floor((5*e + 2)/153)
|
|
||||||
local day = e - floor((153*m + 2)/5) + 1
|
|
||||||
local month = m + 3 - 12*floor(m/10)
|
|
||||||
local year = 100*b + d - 4800 + floor(m/10)
|
|
||||||
return year, month, day
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Assumes only violation of valid date may be in day outside of end of month
|
|
||||||
-- due to months and years shifts. Cap the day and returns a valid date.
|
|
||||||
local function valid_date_cap_day(year, month, day)
|
|
||||||
day = min(day, endofmonth(year, month))
|
|
||||||
return d_ct(year, month, day)
|
|
||||||
end
|
|
||||||
|
|
||||||
local d_mt = {
|
|
||||||
__new = function(ct, year, month, day) T_year(year) T_month(month)
|
|
||||||
T_day(year, month, day)
|
|
||||||
return new(ct, ymd_to_julian(year, month, day)*(86400LL*1e6))
|
|
||||||
end,
|
|
||||||
copy = function(self)
|
|
||||||
return new(d_ct, self)
|
|
||||||
end,
|
|
||||||
__eq = p_mt.__eq,
|
|
||||||
__lt = p_mt.__lt,
|
|
||||||
__le = p_mt.__le,
|
|
||||||
__add = function(self, rhs) -- Commutative.
|
|
||||||
local d, s = dfirst(self, rhs)
|
|
||||||
if istype(p_ct, s) then
|
|
||||||
return d_64(d._ticks + s._ticks)
|
|
||||||
elseif istype(months_ct, s) then
|
|
||||||
local year, month, day = d:ymd()
|
|
||||||
year, month = shift_months(year, month, s._m)
|
|
||||||
return valid_date_cap_day(year, month, day) + d:period()
|
|
||||||
elseif istype(years_ct, s) then
|
|
||||||
local year, month, day = d:ymd()
|
|
||||||
year = year + s._y
|
|
||||||
return valid_date_cap_day(year, month, day) + d:period()
|
|
||||||
else
|
|
||||||
error("unexpected type")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
__sub = function(self, rhs)
|
|
||||||
T_date(self) -- Disallow (not-a-date)-date.
|
|
||||||
if istype(p_ct, rhs) then
|
|
||||||
return d_64(self._ticks - rhs._ticks)
|
|
||||||
elseif istype(months_ct, rhs) then
|
|
||||||
local year, month, day = self:ymd()
|
|
||||||
year, month = shift_months(year, month, -rhs._m)
|
|
||||||
return valid_date_cap_day(year, month, day) + self:period()
|
|
||||||
elseif istype(years_ct, rhs) then
|
|
||||||
local year, month, day = self:ymd()
|
|
||||||
year = year - rhs._y
|
|
||||||
return valid_date_cap_day(year, month, day) + self:period()
|
|
||||||
elseif istype(d_ct, rhs) then
|
|
||||||
return p_64(self._ticks - rhs._ticks)
|
|
||||||
else
|
|
||||||
error("unexpected type")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
__tostring = function(self)
|
|
||||||
local year, month, day = self:ymd()
|
|
||||||
local h, m, s, ms = self:period():parts()
|
|
||||||
return format("%i-%02i-%02iT", year, month, day)..posptostr(h, m, s, ms)
|
|
||||||
end,
|
|
||||||
ticks = p_mt.ticks,
|
|
||||||
ymd = function(self)
|
|
||||||
local julian = tonumber(self._ticks/(86400LL*1e6))
|
|
||||||
return julian_to_ymd(julian)
|
|
||||||
end,
|
|
||||||
year = function(self) local y, m, d = self:ymd() return y end,
|
|
||||||
month = function(self) local y, m, d = self:ymd() return m end,
|
|
||||||
day = function(self) local y, m, d = self:ymd() return d end,
|
|
||||||
period = function(self)
|
|
||||||
return p_64(self._ticks%(86400LL*1e6))
|
|
||||||
end,
|
|
||||||
isleapyear = function(self)
|
|
||||||
local y = self:ymd()
|
|
||||||
return isleapyear(y)
|
|
||||||
end,
|
|
||||||
endofmonth = function(self)
|
|
||||||
local y, m = self:ymd()
|
|
||||||
return endofmonth(y, m)
|
|
||||||
end,
|
|
||||||
weekday = function(self)
|
|
||||||
local y, m, d = self:ymd()
|
|
||||||
return weekday(y, m, d)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
d_mt.__index = d_mt
|
|
||||||
|
|
||||||
d_ct = ffi.metatype("struct { int64_t _ticks; }", d_mt)
|
|
||||||
|
|
||||||
local function todate(x)
|
|
||||||
if type(x) == "string" then
|
|
||||||
local f1, l1, year, month, day, h, m, s, ms =
|
|
||||||
x:find("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)")
|
|
||||||
if year == nil or ms == nil or l1 ~= #x then
|
|
||||||
error("'"..x.."' is not a string representation of a date")
|
|
||||||
end
|
|
||||||
local ton = tonumber
|
|
||||||
return d_ct(ton(year), ton(month), ton(day)) +
|
|
||||||
p_ct(ton(h), ton(m), ton(s), ton(ms))
|
|
||||||
elseif istype(int64_ct, x) then
|
|
||||||
return d_64(x)
|
|
||||||
else
|
|
||||||
error("unexpected type")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- System-dependent functions --------------------------------------------------
|
|
||||||
local nowlocal, nowutc, sleep
|
|
||||||
|
|
||||||
if jit.os == "Windows" then -- On Windows sizeof(long) == 4 on both x86 and x64.
|
|
||||||
ffi.cdef[[
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
typedef unsigned short WORD;
|
|
||||||
typedef unsigned __int64 ULONGLONG;
|
|
||||||
|
|
||||||
typedef struct _SYSTEMTIME {
|
|
||||||
WORD wYear;
|
|
||||||
WORD wMonth;
|
|
||||||
WORD wDayOfWeek;
|
|
||||||
WORD wDay;
|
|
||||||
WORD wHour;
|
|
||||||
WORD wMinute;
|
|
||||||
WORD wSecond;
|
|
||||||
WORD wMilliseconds;
|
|
||||||
} SYSTEMTIME, *PSYSTEMTIME;
|
|
||||||
|
|
||||||
typedef union _ULARGE_INTEGER {
|
|
||||||
struct {
|
|
||||||
DWORD LowPart;
|
|
||||||
DWORD HighPart;
|
|
||||||
};
|
|
||||||
struct {
|
|
||||||
DWORD LowPart;
|
|
||||||
DWORD HighPart;
|
|
||||||
} u;
|
|
||||||
ULONGLONG QuadPart;
|
|
||||||
} ULARGE_INTEGER, *PULARGE_INTEGER;
|
|
||||||
|
|
||||||
typedef struct _FILETIME {
|
|
||||||
DWORD dwLowDateTime;
|
|
||||||
DWORD dwHighDateTime;
|
|
||||||
} FILETIME, *PFILETIME;
|
|
||||||
|
|
||||||
void GetLocalTime(
|
|
||||||
PSYSTEMTIME lpSystemTime
|
|
||||||
);
|
|
||||||
//void GetSystemTime(
|
|
||||||
// PSYSTEMTIME lpSystemTime
|
|
||||||
//);
|
|
||||||
void GetSystemTimeAsFileTime(
|
|
||||||
PFILETIME lpSystemTimeAsFileTime
|
|
||||||
);
|
|
||||||
void GetSystemTimeAsPreciseFileTime(
|
|
||||||
PFILETIME lpSystemTimeAsFileTime
|
|
||||||
);
|
|
||||||
void Sleep(
|
|
||||||
DWORD dwMilliseconds
|
|
||||||
);
|
|
||||||
]]
|
|
||||||
|
|
||||||
local st = ffi.new("SYSTEMTIME")
|
|
||||||
local ft = ffi.new("FILETIME")
|
|
||||||
local ul = ffi.new("ULARGE_INTEGER")
|
|
||||||
|
|
||||||
nowlocal = function()
|
|
||||||
C.GetLocalTime(st)
|
|
||||||
return d_ct(st.wYear, st.wMonth, st.wDay) + p_ct(st.wHour, st.wMinute,
|
|
||||||
st.wSecond, st.wMilliseconds*1000)
|
|
||||||
end
|
|
||||||
|
|
||||||
local epoch_offset = d_ct(1601, 1, 1):ticks()
|
|
||||||
local function if_available(lib, fname)
|
|
||||||
local ok, f = pcall(function() return lib[fname] end)
|
|
||||||
return ok and f
|
|
||||||
end
|
|
||||||
local get_system_time = if_available(C, 'GetSystemTimeAsPreciseFileTime')
|
|
||||||
or C.GetSystemTimeAsFileTime
|
|
||||||
|
|
||||||
nowutc = function()
|
|
||||||
-- Resolution: 1 microsecond.
|
|
||||||
-- Accuracy : 1 millisecond up to Windows 7, higher otherwise.
|
|
||||||
get_system_time(ft)
|
|
||||||
ul.LowPart = ft.dwLowDateTime
|
|
||||||
ul.HighPart = ft.dwHighDateTime
|
|
||||||
return new(d_ct, epoch_offset + ul.QuadPart/10)
|
|
||||||
end
|
|
||||||
|
|
||||||
sleep = function(p)
|
|
||||||
if p < p_ct() then
|
|
||||||
error("cannot sleep a negative amount of time")
|
|
||||||
end
|
|
||||||
C.Sleep(p:ticks()/1000)
|
|
||||||
end
|
|
||||||
|
|
||||||
else -- Linux and OSX.
|
|
||||||
ffi.cdef[[
|
|
||||||
typedef long time_t;
|
|
||||||
typedef int useconds_t;
|
|
||||||
|
|
||||||
typedef struct timeval {
|
|
||||||
long tv_sec;
|
|
||||||
int tv_usec;
|
|
||||||
} timeval;
|
|
||||||
typedef struct tm {
|
|
||||||
int tm_sec;
|
|
||||||
int tm_min;
|
|
||||||
int tm_hour;
|
|
||||||
int tm_mday;
|
|
||||||
int tm_mon;
|
|
||||||
int tm_year;
|
|
||||||
int tm_wday;
|
|
||||||
int tm_yday;
|
|
||||||
int tm_isdst;
|
|
||||||
long tm_gmtoff;
|
|
||||||
char *tm_zone;
|
|
||||||
} tm;
|
|
||||||
|
|
||||||
int gettimeofday(
|
|
||||||
struct timeval * restrict,
|
|
||||||
void * restrict
|
|
||||||
);
|
|
||||||
struct tm *localtime(
|
|
||||||
const time_t *
|
|
||||||
);
|
|
||||||
int usleep(
|
|
||||||
useconds_t useconds
|
|
||||||
);
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- C.host_get_clock_service it's slower and we don't need higher resolution.
|
|
||||||
-- C.mach_absolute_time does not report real clock.
|
|
||||||
local epoch_offset = d_ct(1970, 1, 1):ticks()
|
|
||||||
local tv = ffi.new("timeval[1]")
|
|
||||||
local tt = ffi.new("time_t[1]")
|
|
||||||
|
|
||||||
nowlocal = function()
|
|
||||||
C.gettimeofday(tv, nil)
|
|
||||||
tt[0] = tv[0].tv_sec
|
|
||||||
local tm = C.localtime(tt)
|
|
||||||
return d_ct(1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday) +
|
|
||||||
p_ct(tm.tm_hour, tm.tm_min, tm.tm_sec, tv[0].tv_usec)
|
|
||||||
end
|
|
||||||
|
|
||||||
nowutc = function()
|
|
||||||
-- Resolution: 1 microsecond.
|
|
||||||
-- Accuracy : 1 microsecond.
|
|
||||||
C.gettimeofday(tv, nil)
|
|
||||||
return new(d_ct, epoch_offset + tv[0].tv_sec*1000000LL + tv[0].tv_usec)
|
|
||||||
end
|
|
||||||
|
|
||||||
sleep = function(p)
|
|
||||||
if p < p_ct() then
|
|
||||||
error("cannot sleep a negative amount of time")
|
|
||||||
end
|
|
||||||
C.usleep(p:ticks())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
period = p_ct,
|
|
||||||
toperiod = toperiod,
|
|
||||||
|
|
||||||
weeks = weeks,
|
|
||||||
days = days,
|
|
||||||
hours = hours,
|
|
||||||
minutes = minutes,
|
|
||||||
seconds = seconds,
|
|
||||||
milliseconds = milliseconds,
|
|
||||||
microseconds = microseconds,
|
|
||||||
|
|
||||||
date = d_ct,
|
|
||||||
todate = todate,
|
|
||||||
|
|
||||||
isleapyear = isleapyear,
|
|
||||||
endofmonth = endofmonth,
|
|
||||||
weekday = weekday,
|
|
||||||
|
|
||||||
months = months_ct,
|
|
||||||
years = years_ct,
|
|
||||||
|
|
||||||
sleep = sleep,
|
|
||||||
nowlocal = nowlocal,
|
|
||||||
nowutc = nowutc,
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user