94 lines
3.6 KiB
Lua
94 lines
3.6 KiB
Lua
-- Copyright 2011-15 Paul Kulchenko, ZeroBrane LLC
|
|
-- authors: Luxinia Dev (Eike Decker & Christoph Kubisch)
|
|
---------------------------------------------------------
|
|
|
|
local ide = ide
|
|
--[[ single instance
|
|
open an UDP port - if it fails it is either because
|
|
- IDE is running already
|
|
- an application is already blocking that port
|
|
if it fails it tries to contact the running application
|
|
- if it confirms being the IDE we let that instance open it, finish our application
|
|
- otherwise we throw an error message on the user and start like normal
|
|
|
|
probably a pitfal: an instance is running but is not visible
|
|
(because it was finished though the UDP thing still runs)
|
|
]]
|
|
|
|
if not ide.config.singleinstance then return end
|
|
|
|
local socket = require "socket"
|
|
local port = ide.config.singleinstanceport
|
|
local delay = tonumber(ide.config.singleinstance) or 1000 -- in ms
|
|
local svr = socket.udp()
|
|
local success = svr:setsockname("127.0.0.1",port) -- bind on local host
|
|
local protocol = {client = {}, server = {}}
|
|
|
|
protocol.client.greeting = "Is this you, my IDE? It's me, a new instance."
|
|
protocol.server.greeting = "Yes it is me, how may I serve you?"
|
|
protocol.client.requestloading = "Could you please load this file for me: %s"
|
|
protocol.server.answerok = "Sure. You may now leave."
|
|
|
|
if success then -- ok, server was started, we are solo
|
|
--TODO: if multiple files are to be opened, each file is handled one by one - we could create a single string instead...
|
|
ide.idletimer = wx.wxTimer(wx.wxGetApp())
|
|
ide.idletimer:Start(delay,false)
|
|
svr:settimeout(0) -- don't block
|
|
wx.wxGetApp():Connect(wx.wxEVT_TIMER, function()
|
|
if ide.exitingProgram then -- if exiting, terminate the timer loop
|
|
wx.wxGetApp():Disconnect(wx.wxEVT_TIMER)
|
|
return
|
|
end
|
|
|
|
local msg, ip, port = svr:receivefrom() -- receive a msg
|
|
if msg then
|
|
if msg == protocol.client.greeting then -- just send back hi
|
|
svr:sendto(protocol.server.greeting,ip,port)
|
|
elseif msg:match(protocol.client.requestloading:gsub("%%s",".+$")) then -- ok we need to open something
|
|
svr:sendto(protocol.server.answerok,ip,port)
|
|
local filename = msg:match(protocol.client.requestloading:gsub("%%s","(.+)$"))
|
|
if filename then
|
|
RequestAttention()
|
|
if wx.wxDirExists(filename) then
|
|
ProjectUpdateProjectDir(filename)
|
|
elseif not ActivateFile(filename) then
|
|
DisplayOutputLn(TR("Can't open file '%s': %s"):format(filename, wx.wxSysErrorMsg()))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
else -- something different is running on our port
|
|
local cln = socket.udp()
|
|
cln:setpeername("127.0.0.1",port)
|
|
cln:settimeout(2)
|
|
cln:send(protocol.client.greeting)
|
|
|
|
local msg = cln:receive()
|
|
local arg = ide.arg
|
|
if msg and msg == protocol.server.greeting then
|
|
local failed = false
|
|
for index = 2, #arg do
|
|
local fileName = arg[index]
|
|
if fileName ~= "--"
|
|
-- on OSX, the command line includes -psn parameter, so ignore it
|
|
and (ide.osname ~= 'Macintosh' or not fileName:find("^-psn")) then
|
|
cln:send(protocol.client.requestloading:format(fileName))
|
|
|
|
local msg, err = cln:receive()
|
|
if msg ~= protocol.server.answerok then
|
|
failed = true
|
|
print(err,msg)
|
|
end
|
|
end
|
|
end
|
|
if failed then
|
|
print("The server instance failed to open the files, this instance will continue running.")
|
|
else -- done
|
|
os.exit(0)
|
|
end
|
|
else
|
|
print("The single instance communication has failed; there may be another instance running, which may cause interference with the debugger.")
|
|
end
|
|
end
|