forked from pkulchenko/wxlua
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcoroutine.wx.lua
More file actions
179 lines (141 loc) · 6.51 KB
/
coroutine.wx.lua
File metadata and controls
179 lines (141 loc) · 6.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
-------------------------------------------------------------------------=---
-- Name: coroutine.wx.lua
-- Purpose: Tests coroutines and wxIDLE_EVENTS
-- Author: Leandro Motta Barros
-- Created: 2006
-- Copyright:
-- Licence: wxWidgets licence
-------------------------------------------------------------------------=---
-- Load the wxLua module, does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit
package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
require("wx")
-- Test that we can get the value from a wxLuaObject in a coroutine
wxlobj = wxlua.wxLuaObject("Created in main lua_State")
-------------------------------------------------------------------------------
-- ProgressWindow
-------------------------------------------------------------------------------
ProgressWindow = {
-- The 'wxDialog' being encapsulated by this "class".
dialog = nil,
-- The label telling what's going on ("Processing 7/10...")
label = nil,
}
-- The constructor for the progress dialog.
-- 'parent' is the parent window.
-- 'workCoroutine' is the coroutine used to process whatever is desired.
-- 'caption' is the caption to be used for this window.
-- 'initialLabel' is the string that will be initially shown in the window.
function ProgressWindow:new(parent, workCoroutine, caption, initialLabel)
-- Sanity test to ensure that we can call binding functions
-- fails on r:SetX if wx bindings aren't installed correctly for the coroutine
local r = wx.wxRect(1,2,3,4)
r:SetX(10)
assert((r:GetX() == 10) and (r:GetY() == 2))
-- Test that wxLuaObjects also work in coroutines
local co_wxlobj = wxlua.wxLuaObject("hello")
assert(co_wxlobj:GetObject() == "hello")
co_wxlobj:SetObject(r)
assert(co_wxlobj:GetObject():GetX() == 10)
-- Test that wxLuaObjects created in main lua_State still work in coroutines
assert(wxlobj:GetObject() == "Created in main lua_State")
-- Test that wxLuaObjects created in coroutine can be accessed in main lua_State
self.wxlobj = wxlua.wxLuaObject("Created in coroutine")
-- Create a Lua 'class' object to store the coroutine's data
local o = { }
setmetatable(o, self)
self.__index = self
-- Check input parameters
assert(type(workCoroutine) == "thread")
assert(type(caption) == "string")
assert(type(initialLabel) == "string")
-- Create dialog
o.dialog = wx.wxDialog(parent, wx.wxID_ANY, caption,
wx.wxDefaultPosition, wx.wxDefaultSize,
wx.wxDEFAULT_DIALOG_STYLE)
o.label = wx.wxTextCtrl(o.dialog, wx.wxID_ANY, "",
wx.wxDefaultPosition, wx.wxDefaultSize,
wx.wxTE_MULTILINE + wx.wxTE_READONLY)
local mainSizer = wx.wxBoxSizer(wx.wxVERTICAL)
mainSizer:Add(o.label, 1, wx.wxGROW)
o.dialog:SetSizer(mainSizer)
-- Handle idle events: run the coroutine's next "step"
o.dialog:Connect(wx.wxEVT_IDLE,
function (event)
if coroutine.status(workCoroutine) ~= "dead" then
local s, msg = coroutine.resume(workCoroutine)
if not msg then
o.dialog:Close()
else
o:setStatus(msg)
end
event:RequestMore()
event:Skip()
end
end)
-- Voilà
return o
end
-- Sets the ProgressWindow's "status". For now, this means "change the text"
-- being displayed in the window (usually something like "Doing this thing").
function ProgressWindow:setStatus(label)
self.label:AppendText("\n"..label)
end
-------------------------------------------------------------------------------
-- The main frame
-------------------------------------------------------------------------------
local ID_THE_BUTTON = wx.wxID_HIGHEST + 100
frame = wx.wxFrame(wx.NULL, wx.wxID_ANY,
"wxLua Idle Events and Coroutines")
-- ----------------------------------------------------------------------------
-- create a simple file menu
local fileMenu = wx.wxMenu()
fileMenu:Append(wx.wxID_EXIT, "E&xit", "Quit the program")
-- create a simple help menu
local helpMenu = wx.wxMenu()
helpMenu:Append(wx.wxID_ABOUT, "&About", "About the wxLua Coroutine Sample")
-- create a menu bar and append the file and help menus
local menuBar = wx.wxMenuBar()
menuBar:Append(fileMenu, "&File")
menuBar:Append(helpMenu, "&Help")
-- attach the menu bar into the frame
frame:SetMenuBar(menuBar)
-- connect the selection event of the exit menu item to an
-- event handler that closes the window
frame:Connect(wx.wxID_EXIT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event) frame:Close(true) end )
-- connect the selection event of the about menu item
frame:Connect(wx.wxID_ABOUT, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
wx.wxMessageBox('This is the "About" dialog of the Coroutine wxLua sample.\n'..
wxlua.wxLUA_VERSION_STRING.." built with "..wx.wxVERSION_STRING,
"About wxLua",
wx.wxOK + wx.wxICON_INFORMATION,
frame)
end )
-- ----------------------------------------------------------------------------
panel = wx.wxPanel(frame, wx.wxID_ANY)
button = wx.wxButton(panel, ID_THE_BUTTON, "Perform some long operation")
frame:Connect(ID_THE_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function (event)
local function workFunc()
for i = 1, 10 do
coroutine.yield("Performing step "..tostring(i).."/10")
wx.wxSleep(1)
end
end
local workCoroutine = coroutine.create(workFunc)
local wndProgress =
ProgressWindow:new(frame, workCoroutine,
"Performing some long operation",
"Performing step 1/many")
wndProgress.dialog:ShowModal(true)
wndProgress.dialog:Destroy()
assert(wndProgress.wxlobj:GetObject() == "Created in coroutine")
end)
-- Show the main frame
frame:Show(true)
-- Call wx.wxGetApp():MainLoop() last to start the wxWidgets event loop,
-- otherwise the wxLua program will exit immediately.
-- Does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit since the
-- MainLoop is already running or will be started by the C++ program.
wx.wxGetApp():MainLoop()