Anatomy of a pvserver in Lua script language
A pvserver in Lua can be created without installing the Qt SDK and a C++ compiler. All you need is within our installation package. The structure of a Lua pvserver is very similar to the C/C++ version, Our libraries are used via a language binding that is created with swig. Because of this the reference manual for the pvslib and the rllib can also be used for Lua. There is a main program called pvslua which will read file main.lua and execute the lua script. Within main.lua there is a function luaMain(ptr) where the handling of a pvbrowser client starts. In fact pvslua is a C/C++ program with the same structure as a pvserver in C/C++. But within pvMain() pvslua starts processing main.lua.
You start a pvserver in Lua with the following command:
pvslua main.lua
With a pvserver in Lua it is possible to change the Lua code while the pvserver is running. A newly connected pvbrowser client will immediately see the modified version.
main.lua
Whenever a pvbrowser client connects pvslua creates a new thread for handling that client and executes file main.lua. The function showMask1() will show and handle mask1.
------------------------------------------------------------------------------
-- pvserver in lua : pvslua -port=5050 -cd=/your/directory/with/your/lua/code
------------------------------------------------------------------------------
trace = 1 -- here you may put variables global for all your masks
dofile("mask1.lua") -- include your masks here
------------------------------------------------------------------------------
function luaMain(ptr) -- pvserver Lua Main Program
p = pv.getParam(ptr) -- get the PARAM structure
pv.pvSetCaption(p,string.format("Hello Lua %d",123))
pv.pvResize(p,0,1280,1024)
pv.pvGetInitialMask(p)
print("Inital mask = ", p.initial_mask)
ret = 1
while 1 do -- show your masks
if (ret==1) then
ret = showMask1(p)
else
ret = 1
end
end
pv.pvThreadFatal(p,"Lua calling ThreadFatal")
return 0
end
Definition of mask1 in Lua
showMask1() is generated by pvdevelop. You do not have to write it manually. It will show mask1. On the begin of that function the names of the widgets you have designed are listed. Also the toolTip and whatsThis properties of the widgets are listed and the widgetType is available.
Then you see the calls to pv functions that create the widget tree in the pvbrowser client.
Finally the function goes to the event loop where the events send by the pvbrowser client are interpreted and the according slotFunctions are called.
------------------------------------------------------------------------------
-- this file is generated by pvdevelop. DO NOT EDIT !!!
------------------------------------------------------------------------------
function showMask1(p)
--- begin variables that are private to this mask --------------------------
iarray = pv.IntegerArray() -- see pv.getIntegers(text,iarray) below
farray = pv.FloatArray() -- see pv.getFloats(text,farray) below
--- begin construction of our mask -----------------------------------------
ID_MAIN_WIDGET = 0
PushButtonBack = 1
ID_END_OF_WIDGETS = 2
toolTip = {}
toolTip[0] = ""
toolTip[1] = ""
whatsThis = {}
whatsThis[0] = ""
whatsThis[1] = ""
widgetType = {}
widgetType[0] = pv.TQWidget
widgetType[1] = pv.TQPushButton
pv.pvStartDefinition(p,ID_END_OF_WIDGETS)
pv.pvQPushButton(p,PushButtonBack,0)
pv.pvSetGeometry(p,PushButtonBack,10,10,111,40)
pv.pvSetText(p,PushButtonBack,"Lua test")
pv.pvEndDefinition(p);
--- end construction of our mask -------------------------------------------
--- end variables that are private to this mask ----------------------------
dofile("mask1_slots.lua") -- include our slot functions
if trace == 1 then print("show mask1") end
pv.pvClearMessageQueue(p) -- clear all pending events
ret = slotInit(p) -- intitialize our variables
if ret ~= 0 then return ret end -- return number of next mask to call
while(1) -- event loop
do
event = pv.pvGetEvent(p) -- get the next event
result = pv.pvParseEventStruct(p,event) -- parse the event
id = result.event
i = result.i
text = result.text
-- now call the according slot function
if id == pv.NULL_EVENT then
ret = slotNullEvent(p)
elseif id == pv.BUTTON_EVENT then
if trace==1 then print("BUTTON_EVENT id=", i) end
ret = slotButtonEvent(p,i)
elseif id == pv.BUTTON_PRESSED_EVENT then
if trace == 1 then print("BUTTON_PRESSED_EVENT id=",i) end
ret=slotButtonPressedEvent(p,i)
elseif id == pv.BUTTON_RELEASED_EVENT then
if trace == 1 then print("BUTTON_RELEASED_EVENT id=",i) end
ret=slotButtonReleasedEvent(p,i)
elseif id == pv.TEXT_EVENT then
--- snip ...
slotFunctions in Lua
The task of the developer of a visualization is to code the slotFunctions. The framework was generated by pvdevelop when you created the mask.
------------------------------------------------------------------------------
-- mask1_slots.lua Please edit this file in order to define your logic
------------------------------------------------------------------------------
-- here you may define variables local for your mask
-- also see the variables in the generated maskX.lua
function slotInit(p) -- this function will be called before the event loop
print("slotInit called")
return 0
end
function slotNullEvent(p)
print("slotNullEvent called")
return 0
end
function slotButtonEvent(p,id)
if (id == PushButtonBack) then
pv.pvSetText(p,PushButtonBack,"I have been clicked")
end
return 0
end
function slotButtonPressedEvent(p,id)
return 0
end
function slotButtonReleasedEvent(p,id)
return 0
end
--- snip ...

