Yes, we package our custom Lua (and widgets) with every module. That way every module is independent. The user does not have to install Lua or anything else.
I have been trying to implement a few features with wxLua so as to test what a script like this can do.
- Code: Select all
package.cpath = '/home/test/Documents/wxLua-build/lib/Debug/lib?.so'
require('wx')
frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, "pilot Vassal 4",
wx.wxDefaultPosition, wx.wxSize(450, 450),
wx.wxDEFAULT_FRAME_STYLE)
panel = wx.wxPanel(frame, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize(300, 300))
map = wx.wxBitmap("/home/test/projects/vassal/map.png")
piece1 = wx.wxBitmap("/home/test/projects/vassal/piece1.png")
piece2 = wx.wxBitmap("/home/test/projects/vassal/piece2.png")
Counter = { x, y, bitmap, panel }
Counter.__index = Counter
function Counter:create(x, y, piece)
local cnt = {}
setmetatable(cnt, Counter)
cnt.x = x
cnt.y = y
cnt.bitmap = piece
cnt.panel = wx.wxPanel(panel, wx.wxID_ANY, wx.wxPoint(x,y), wx.wxSize(50, 50))
local OnLeftDown = function(event)
local dropSource = wx.wxDropSource(cnt.panel)
dropSource.SetData(dropSource, wx.wxBitmapDataObject(cnt.bitmap))
local result = dropSource.DoDragDrop(dropSource)
end
cnt.panel:Connect(wx.wxEVT_LEFT_DOWN, OnLeftDown)
return cnt
end
function Counter:paint()
local dc = wx.wxPaintDC(self.panel)
dc.DrawBitmap(dc, self.bitmap, 0, 0, false)
dc:delete()
end
counters = {}
table.insert(counters, Counter:create(14, 10, piece1))
table.insert(counters, Counter:create(196, 114, piece2))
function OnLeftDown(event)
local pos = wx.wxGetMousePosition()
pos = frame:ScreenToClient(pos)
print(pos.x.." "..pos.y)
end
panel:Connect(wx.wxEVT_LEFT_DOWN, OnLeftDown)
function OnPaint(event)
local dc = wx.wxPaintDC(panel)
dc.DrawBitmap(dc, map, 0, 0, false)
for i = 1, #counters do
counters[i]:paint()
end
dc:delete()
end
panel:Connect(wx.wxEVT_PAINT, OnPaint)
frame:Show(true)
The files map.png, piece1.png and piece2.png can be anything but my two piece sizes were 50x50.
The first problem with the script is that it is possible to load files from the host file system. This is a feature of the widgets classes. This must not be allowed. I presume that is is possible to turn off class member functions in a custom widget.
The second problem came when I tried to implement drag-and-drop. wxWidgets has classes for this: wxDropSource and wxDropTarget. wxDropSource works (and when you run the script you see that). wxDropTarget did not work. An instance of this class could simply not be created. I looked at the source code in wxLua and found this in wxLua-2.8.12.3-src/bindings/wxwidgets/wxcore_clipdrag.i
- Code: Select all
class wxDropTarget // FIXME implement virtual
{
//wxDropTarget(wxDataObject* data = NULL) pure virtual functions in MSW
virtual bool GetData( );
//wxDragResult GetDefaultAction( );
//virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def );
//virtual bool OnDrop(wxCoord x, wxCoord y );
//virtual wxDragResult OnEnter(wxCoord x, wxCoord y, wxDragResult def );
//virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def );
//virtual void OnLeave( );
//void SetDataObject(wxDataObject* data );
//void SetDefaultAction(wxDragResult action );
};
All members except GetData() have not been implemented. I can not possibly comment on why, but it shows that everything has to be tested and that any given widget may not work completely.
Else I am happy with what I can do with wxLua. Note how click events are captured by the Counter class, so that when you click on a counter its own OnLeftDown is triggered.
Use of widgets have great potential as it gives the module designer an unlimited amount of access to the data structures of the module such as map and counters. You can also draw what you want on the screen.
The question remains what happens when the script file(s) start to get huge. This is a question of both writing and maintaining the scripts for the module maker and a question of efficiency when the module becomes large and complex.
What a script does:
- Holds the game data structures and their associated functions, like map, grid and counter.
- Draws the Map window and a tabbed Counter window with counters/cards that can be dragged to the map.
What vassal.cpp does:
- All loading and saving of games.
- All communication with the server.
- Draws the Room window and the Chat window,
- Logfiles/Undo functionality.
Effective communication of data between script and vassal.cpp is essential.
The efficiency of such a design remains to be seen. But it certainly gives the module designer great freedom.