Re: Single instance module and multithreading

From: Alex <alex.bep....at.gmail.com>
Date: Sun, 22 Feb 2009 16:50:28 -0800 (PST)

Hi, too.

Your proof of concept works because you do not actually try to open
the file in TA. ;)

As Benjamin pointed out one cannot use the textadept table from a
lane. I have tried passing it through a linda :), cp Lanes
documentation. As expected, this did not work however, as this table
is custom user data. – Mitchell, maybe you can make more sense of the
“Deep userdata in your own apps” section. I have no C skills
whatsoever.

I have got a rather crude version working. The solution is in two
parts. The first is the listener module for Textadept. It reads
filenames asynchronously from the socket. Upon every activation, it
opens the read filename in TA. The second part is a simple script that
writes the path of the file to open to the socket and then activates
the TA window. This is specific to Windows as I use the afxLua
library. – I said it was crude. ;) The ugliest bit however is
"afx.sleep(50)" in the activator script. Sometimes the script
activated the TA window before the listener had read from the socket.

- Alex

#############
# The listener:

local lanes = require('lanes')

local linda = lanes.linda()
local fileNameKey = "x"

local function receiveNext(server)
    local client = server:accept()
    local line, err = client:receive("*a")
    client:close()
    return err and err or line
end

local function putFileNamesInQueue()
    local socket = require('socket')
    local server, err = socket.bind('localhost', 2558)
    if not server then print(err) end
    while true do
        linda:send(fileNameKey, receiveNext(server))
    end
end
local queueManager = lanes.gen("*", putFileNamesInQueue)()

local processing = false
local function openFileInQueue()
    if not processing then
        processing = true
        local fileName = linda:receive(0.0, fileNameKey)
        if fileName then
            textadept.io.open(fileName)
        end
    end
    processing = false
end

textadept.events.add_handler('view_switch', openFileInQueue)

##############
# The activator:

require('winman')
require('afx')
require('socket')

function sendFileToTextadeptQueue(filePath)
    local client, err = socket.connect('localhost', 2558)
    if not client then print(err) return end

    _, err = client:send(filePath)
    client:close()
    if err then error("Error: "..err) end
end

function startTextadept(path)
    local commandLine = string.format('c:/bpps/textadept-1.4/
textadept.exe "%s"', path)
    afx.run(commandLine, {waitwindow=true})
end

function openWithTextadept(filePath)
    local textadept = winman.find{
        class="gdkWindowToplevel",
        matchtitle=" - Textadept %("
    }
    if textadept then
        sendFileToTextadeptQueue(normalizeWindowsPath(filePath))
        afx.sleep(50)
        textadept:activate()
    else
        startTextadept(filePath)
    end
end

function normalizeWindowsPath(windowsPath)
    return string.gsub(windowsPath, "\\", "/")
end

local relativePath = arg[1]
local workingDir = afx.cwdir()
local absolutePath = afx.buildpath(workingDir, relativePath)
openWithTextadept(absolutePath)

On Feb 22, 11:05 pm, mitchell <mforal.n....at.gmail.com> wrote:
> Hi,
>
> > LuaLanes looks good. I've been playing around with it, but still
> > cannot get something to work yet. The idea I have is to have a socket
> > listening to a port inside a lane, and when it receives something,
> > calls a function defined outside the lane, passing the string
> > parameter that should be executed as Lua code (e.g. 'textadept.io.open
> > ("foo")'). I'm still not sure if this is possible as the Lanes
> > documentation is cryptic.
>
> I've got something working now! This is a proof of concept:
>
> require 'socket'
> require 'lanes'
>
> local port = 3003
>
> function received(text) print('received: '..text) end
>
> function lane(callback)
>   local socket = require 'socket'
>   local server = socket.bind('localhost', port)
>   local client = server:accept()
>   _, _, text = client:receive()
>   callback(text)
>   server:close()
> end
>
> local f = lanes.gen("*", lane)(received)
>
> local client = socket.connect('localhost', port)
> client:send('hi')
> client:close()
> f:cancel()
>
> No blocking!
>
Received on Sun 22 Feb 2009 - 19:50:28 EST

This archive was generated by hypermail 2.2.0 : Thu 08 Mar 2012 - 11:37:31 EST