new script engine, and things maybe be bugged for a while

master
Eduardo Bart 13 years ago
parent ab7394f357
commit 70f0b0dace

@ -7,7 +7,7 @@ SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
# find needed packages
SET(Boost_USE_STATIC_LIBS ON)
SET(Boost_USE_MULTITHREADED OFF)
FIND_PACKAGE(Boost COMPONENTS system signals REQUIRED)
FIND_PACKAGE(Boost COMPONENTS system REQUIRED)
FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(Lua REQUIRED)
FIND_PACKAGE(PhysFS REQUIRED)
@ -56,7 +56,7 @@ SET(SOURCES
src/framework/core/configs.cpp
src/framework/core/resources.cpp
src/framework/core/engine.cpp
src/framework/core/modules.cpp
src/framework/core/packages.cpp
# framework otml
src/framework/otml/otmlemitter.cpp
@ -64,9 +64,13 @@ SET(SOURCES
src/framework/otml/otmlnode.cpp
# framework script
src/framework/script/scriptobject.cpp
src/framework/script/scriptcontext.cpp
src/framework/script/scriptfunctions.cpp
src/framework/script/luastate.cpp
src/framework/script/luavalue.cpp
src/framework/script/luaobject.cpp
src/framework/script/luainterface.cpp
src/framework/script/luafunctions.cpp
src/framework/script/luaexception.cpp
src/framework/script/luavaluecasts.cpp
# framework utilities
src/framework/util/color.cpp
@ -125,7 +129,7 @@ IF(WIN32)
ADD_DEFINITIONS(-DWIN32_NO_CONSOLE)
ELSE(WIN32)
SET(SOURCES ${SOURCES} src/framework/platform/x11platform.cpp)
ADD_DEFINITIONS(-D_DEBUG_MEMORY)
#ADD_DEFINITIONS(-D_DEBUG_MEMORY)
SET(ADDITIONAL_LIBRARIES pthread GLU)
ENDIF(WIN32)

@ -0,0 +1,10 @@
glyph-height: 14
glyph-spacing: [1, 1]
top-margin: 2
image: helvetica-11px-bold.png
image-glyph-size: [16, 16]
glyph-widths:
32: 4
65: 8

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

@ -0,0 +1,9 @@
glyph-height: 14
glyph-spacing: [1, 1]
top-margin: 1
image: helvetica-11px.png
image-glyph-size: [16, 16]
glyph-widths:
32: 4

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

@ -0,0 +1,10 @@
glyph-height: 16
glyph-spacing: [1, 1]
top-margin: 2
image: helvetica-12px-bold.png
image-glyph-size: [18, 18]
glyph-widths:
32: 4
65: 9

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

@ -0,0 +1,9 @@
glyph-height: 15
glyph-spacing: [1, 1]
top-margin: 1
image: helvetica-12px.png
image-glyph-size: [16, 16]
glyph-widths:
32: 4
65: 8

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

@ -0,0 +1,10 @@
glyph-height: 16
glyph-spacing: [1, 1]
top-margin: 2
image: helvetica-14px-bold.png
image-glyph-size: [20, 20]
glyph-widths:
32: 4
65: 9

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -1,8 +0,0 @@
glyph height: 14
glyph spacing: [0, 1]
top margin: 0
image: sans-11px-bold.png
image glyph size: [16, 16]
glyph widths:
32: 4

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

@ -1,8 +0,0 @@
glyph height: 14
glyph spacing: [0, 1]
top margin: 0
image: sans-11px.png
image glyph size: [16, 16]
glyph widths:
32: 4

@ -1,8 +0,0 @@
glyph height: 14
glyph spacing: [0, 1]
top margin: 0
image: sans-12px-bold.png
image glyph size: [20, 16]
glyph widths:
32: 4

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

@ -1,8 +0,0 @@
glyph height: 16
glyph spacing: [0, 1]
top margin: 0
image: sans-12px.png
image glyph size: [20, 16]
glyph widths:
32: 4

@ -1,9 +0,0 @@
glyph height: 10
glyph spacing: [1, 4]
top margin: 3
image: tibia-10px-antialised.png
image glyph size: [8, 16]
first glyph: 32
glyph widths:
32: 2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

@ -1,9 +0,0 @@
glyph height: 10
glyph spacing: [1, 1]
top margin: 3
image: tibia-10px-monochrome.png
image glyph size: [8, 16]
first glyph: 32
glyph widths:
32: 2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

@ -1,232 +0,0 @@
glyph height: 12
glyph spacing: [0, 1]
top margin: 3
image: tibia-12px-rounded.png
image glyph size: [16, 16]
first glyph: 32
glyph widths:
32: 4
33: 4
34: 7
35: 9
36: 8
37: 10
38: 10
39: 4
40: 6
41: 6
42: 8
43: 9
44: 4
45: 7
46: 4
47: 8
48: 8
49: 6
50: 8
51: 8
52: 8
53: 8
54: 8
55: 8
56: 8
57: 8
58: 5
59: 5
60: 10
61: 10
62: 10
63: 7
64: 10
65: 9
66: 8
67: 8
68: 9
69: 8
70: 8
71: 9
72: 9
73: 6
74: 7
75: 8
76: 8
77: 10
78: 9
79: 9
80: 8
81: 9
82: 9
83: 8
84: 10
85: 9
86: 8
87: 10
88: 8
89: 8
90: 8
91: 6
92: 8
93: 6
94: 11
95: 9
96: 7
97: 8
98: 8
99: 7
100: 8
101: 8
102: 7
103: 8
104: 8
105: 4
106: 6
107: 8
108: 4
109: 10
110: 8
111: 8
112: 8
113: 8
114: 7
115: 7
116: 7
117: 8
118: 8
119: 10
120: 8
121: 8
122: 7
123: 8
124: 5
125: 8
126: 9
127: 13
128: 8
129: 13
130: 4
131: 8
132: 6
133: 13
134: 8
135: 8
136: 7
137: 20
138: 8
139: 6
140: 13
141: 13
142: 7
143: 13
144: 13
145: 4
146: 4
147: 6
148: 6
149: 8
150: 8
151: 12
152: 7
153: 11
154: 7
155: 6
156: 13
157: 13
158: 7
159: 9
160: 4
161: 5
162: 8
163: 8
164: 8
165: 8
166: 7
167: 8
168: 7
169: 12
170: 7
171: 9
172: 11
173: 6
174: 12
175: 8
176: 7
177: 11
178: 7
179: 7
180: 7
181: 8
182: 8
183: 5
184: 7
185: 7
186: 7
187: 9
188: 15
189: 15
190: 15
191: 7
192: 10
193: 10
194: 10
195: 10
196: 10
197: 10
198: 13
199: 8
200: 7
201: 7
202: 7
203: 7
204: 5
205: 5
206: 5
207: 5
208: 10
209: 8
210: 9
211: 9
212: 9
213: 9
214: 9
215: 11
216: 9
217: 8
218: 8
219: 8
220: 8
221: 9
222: 9
223: 8
224: 8
225: 8
226: 8
227: 8
228: 8
229: 8
230: 12
231: 6
232: 8
233: 8
234: 8
235: 8
236: 5
237: 5
238: 3
239: 3
240: 8
241: 8
242: 8
243: 8
244: 8
245: 8
246: 8
247: 11
248: 8
249: 8
250: 8
251: 8
252: 8
253: 8
254: 8
255: 8

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

@ -1,9 +0,0 @@
glyph height: 8
glyph spacing: [0, 1]
top margin: 1
image: tibia-8px-antialised.png
image glyph size: [8, 8]
first glyph: 32
glyph widths:
32: 2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

@ -1,4 +0,0 @@
-- some aliases
loadUI = UI.load
rootUI = UI.getRootContainer()

@ -3,6 +3,6 @@ AnchorNone = 0
AnchorTop = 1
AnchorBottom = 2
AnchorLeft = 3
AnchorRight = 4
AnchorRight = 4
AnchorVerticalCenter = 5
AnchorHorizontalCenter = 6

@ -1,4 +1,3 @@
require 'aliases'
require 'enums'
require 'constants'
require 'util'
require 'messagebox'

@ -10,17 +10,21 @@ function MessageBox.create(title, text, flags)
setmetatable(box, MessageBox)
-- create messagebox window
local window = UIWindow.new("messageBoxWindow", rootUI)
local window = UIWindow.create()
id = "messageBoxWindow"
window.title = title
window:centerIn(rootUI)
window:setLocked()
window:setLocked(true)
rootUI:addChild(window)
-- create messagebox label
local label = UILabel.new("messageBoxLabel", window)
local label = UILabel.create()
id = "messageBoxLabel"
label.text = text
label:addAnchor(AnchorHorizontalCenter, window, AnchorHorizontalCenter)
label:addAnchor(AnchorTop, window, AnchorTop)
label:setMargin(27, 0)
label:addAnchor(AnchorHorizontalCenter, window.id, AnchorHorizontalCenter)
label:addAnchor(AnchorTop, window.id, AnchorTop)
--label:setMargin(27, 0)
window:addChild(label)
-- set window size based on label size
window.width = label.width + 40
@ -28,27 +32,29 @@ function MessageBox.create(title, text, flags)
-- setup messagebox first button
local buttonText
local button1 = UIButton.new("messageBoxButton1", window)
button1:addAnchor(AnchorBottom, window, AnchorBottom)
button1:addAnchor(AnchorRight, window, AnchorRight)
button1:setMargin(10)
local button1 = UIButton.new()
id = "messageBoxButton1"
button1:addAnchor(AnchorBottom, window.id, AnchorBottom)
button1:addAnchor(AnchorRight, window.id, AnchorRight)
--button1:setMargin(10)
button1.width = 64
window:addChild(button1)
if flags == MessageBoxOk then
buttonText = "Ok"
button1.text = "Ok"
box.onOk = createEmptyFunction()
button1.onClick = function()
box.onOk()
box:destroy()
end
elseif flags == MessageBoxCancel then
buttonText = "Cancel"
button1.text = "Cancel"
box.onCancel = createEmptyFunction()
button1.onClick = function()
box.onCancel()
box:destroy()
end
end
button1.text = buttonText
box.window = window
return box

@ -1,8 +0,0 @@
title: Core
notes: Core utilities used by other modules
author: edubart
version: 1
website: https://github.com/edubart/otclient
enabled: true
script: core.lua

@ -1,6 +1,9 @@
function EnterGame_connectToLoginServer()
-- create login protocol
local protocolLogin = ProtocolLogin.new()
local protocolLogin = ProtocolLogin.create()
print(ProtocolLogin_mt)
print(Protocol_mt)
print(getmetatable(protocolLogin))
-- used to recreate enter game window
local recreateEnterGame = function()
@ -11,14 +14,14 @@ function EnterGame_connectToLoginServer()
local loadBox = displayCancelBox("Please wait", "Connecting..")
-- cancel loading callback
loadBox.onCancel = function()
loadBox.onCancel = function(protocol)
-- cancel protocol and reacreate enter game window
protocolLogin:cancel()
protocol:cancel()
recreateEnterGame()
end
-- error callback
protocolLogin.onError = function(error)
protocolLogin.onError = function(protocol, error)
-- destroy loading message box
loadBox:destroy()
@ -26,12 +29,12 @@ function EnterGame_connectToLoginServer()
local errorBox = displayErrorBox("Login Error", error)
-- cancel protocol and reacreate enter game window
self.cancel()
protocol.cancel()
errorBox.onOk = recreateEnterGame
end
-- motd callback
protocolLogin.onMotd = function(motd)
protocolLogin.onMotd = function(protocol, motd)
-- destroy loading message box
loadBox:destroy()
@ -41,14 +44,14 @@ function EnterGame_connectToLoginServer()
local motdBox = displayInfoBox("Message of the day", motdText)
-- cancel protocol and reacreate enter game window
self.cancel()
protocol.cancel()
motdBox.onOk = recreateEnterGame
end
-- get account and password then login
local enterGameWindow = rootUI:child("enterGameWindow")
local account = enterGameWindow:child("accountNameTextEdit").text
local password = enterGameWindow:child("passwordTextEdit").text
local enterGameWindow = rootUI:getChild("enterGameWindow")
local account = enterGameWindow:getChild("accountNameTextEdit").text
local password = enterGameWindow:getChild("passwordTextEdit").text
protocolLogin:login(account, password)
-- destroy enter game window

@ -1,16 +1,16 @@
require 'entergame'
function initializeApplication()
mainMenu = loadUI("ui/mainmenu")
mainMenu = loadUI("ui/mainmenu", rootUI)
end
function terminateApplication()
App.exit()
exit()
end
-- here is where everything starts
if not initialized then
initializeApplication()
App.onClose = terminateApplication
onClose = terminateApplication
initialized = true
end

@ -1,10 +0,0 @@
title: Main menu
notes: Used to create the main menu
enabled: true
#dependencies
interface: 020
author: edubart
version: 0.2
scripts:
- menustate.lua
- mainmenu.lua

@ -1,67 +1,54 @@
%window#enterGameWindow
title: Enter Game
size: [236, 178]
size: [236, 160]
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onLoad: self:setLocked()
%label#accountNameLabel
skin: large
text: Account name
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 33
margin.top: 28
%label#passwordLabel
text: "Password:"
%textEdit#accountNameTextEdit
text: tibialua0
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
anchors.top: prev.bottom
margin.left: 18
margin.top: 62
margin.right: 18
%label#createAccountLabel
text: |
If you don't have
an account yet
anchors.left: parent.left
anchors.top: parent.top
margin.left: 18
margin.top: 87
%label#passwordLabel
skin: large
text: Password
anchors.left: prev.left
anchors.top: prev.bottom
margin.top: 8
%button#createAccountButton
text: Create Account
%textEdit#passwordTextEdit
text: lua123456
anchors.left: parent.left
anchors.top: parent.top
margin.top: 94
margin.left: 132
onClick: displayErrorBox("Error", "Not implemented yet")
anchors.right: parent.right
anchors.top: prev.bottom
margin.left: 18
margin.right: 18
%button#okButton
text: Ok
size: [43, 20]
anchors.right: parent.right
width: 64
anchors.right: next.left
anchors.bottom: parent.bottom
margin.bottom: 10
margin.right: 66
margin.bottom: 16
margin.right: 16
onClick: EnterGame_connectToLoginServer()
%button#cancelButton
text: Cancel
size: [43, 20]
width: 64
anchors.right: parent.right
anchors.bottom: parent.bottom
margin.bottom: 10
margin.right: 13
onClick: self.parent:destroy()
%textEdit#accountNameTextEdit
anchors.right: parent.right
anchors.top: parent.top
margin.top: 32
margin.right: 18
%textEdit#passwordTextEdit
anchors.right: parent.right
anchors.top: parent.top
margin.top: 61
margin.right: 18
margin.bottom: 16
margin.right: 16
onClick: function(self) rootUI:getChild("enterGameWindow"):destroy() end

@ -3,7 +3,7 @@
size: [244, 221]
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onLoad: self.locked = true
onLoad: function(self) self:setLocked() end
%panel#infoPanel
skin: flatPanel
@ -39,7 +39,7 @@
%button#websiteButton
text: Github Page
size: [80,22]
size: [88, 24]
anchors.right: parent.right
anchors.bottom: parent.bottom
margin.bottom: 9
@ -55,9 +55,9 @@
%button#okButton
text: Ok
size: [43, 20]
size: [46, 24]
anchors.left: parent.left
anchors.top: parent.top
margin.top: 191
margin.left: 188
onClick: self.parent:destroy()
onClick: function(self) self.parent:destroy() end

@ -7,7 +7,7 @@
%panel#mainMenu
skin: roundedGridPanel
size: [117, 171]
size: [144, 162]
anchors.left: parent.left
anchors.bottom: parent.bottom
margin.left: 60
@ -17,33 +17,26 @@
text: Enter Game
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 16
onClick: UI.load("entergamewindow")
%button#accessAccountButton
text: Access Account
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 46
onClick: displayErrorBox("Error", "Not implemented yet")
margin.top: 18
onClick: loadUI("entergamewindow", rootUI)
%button#optionsButton
text: Options
anchors.top: parent.top
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 76
onClick: UI.load("optionswindow")
margin.top: 10
onClick: loadUI("optionswindow", rootUI)
%button#infoButton
text: Info
anchors.top: parent.top
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 106
onClick: UI.load("infowindow")
margin.top: 10
onClick: loadUI("infowindow", rootUI)
%button#exitGameButton
text: Exit
anchors.top: parent.top
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 136
margin.top: 10
onClick: terminateApplication()

@ -3,7 +3,7 @@
size: [286, 262]
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
onLoad: self.locked = true
onLoad: function(self) self:setLocked(true) end
# general
%button#generalButton
@ -17,10 +17,10 @@
text: |-
Change general
game options
anchors.left: parent.left
anchors.top: parent.top
margin.left: 117
margin.top: 29
anchors.left: prev.right
anchors.top: prev.top
margin.left: 10
margin.top: -2
# graphics
%button#graphicsButton
@ -34,10 +34,10 @@
text: |-
Change graphics and
performance settings
anchors.left: parent.left
anchors.top: parent.top
margin.left: 117
margin.top: 62
anchors.left: prev.right
anchors.top: prev.top
margin.left: 10
margin.top: -2
# console
%button#consoleButton
@ -49,10 +49,10 @@
%label#consoleLabel
text: Customise the console
anchors.left: parent.left
anchors.top: parent.top
margin.left: 117
margin.top: 95
anchors.left: prev.right
anchors.top: prev.top
margin.left: 10
margin.top: -2
# hotkeys
%button#hotkeysButton
@ -64,10 +64,10 @@
%label#hotkeysLabel
text: Edit your hotkey texts
anchors.left: parent.left
anchors.top: parent.top
margin.left: 117
margin.top: 128
anchors.left: prev.right
anchors.top: prev.top
margin.left: 10
margin.top: -2
%lineDecoration#middleSeparator
anchors.left: parent.left
@ -89,10 +89,10 @@
text: |
Show the most recent
Message of the Day
anchors.left: parent.left
anchors.bottom: parent.bottom
margin.left: 117
margin.bottom: 56
anchors.left: prev.right
anchors.top: prev.top
margin.left: 10
margin.top: -2
%lineDecoration#bottomSeparator
anchors.left: parent.left
@ -110,4 +110,4 @@
anchors.bottom: parent.bottom
margin.right: 10
margin.bottom: 13
onClick: self.parent:destroy()
onClick: function(self) self.parent:destroy() end

@ -1,8 +0,0 @@
title: Message box
notes: Functions for creating message boxes
author: edubart
version: 1
website: https://github.com/edubart/otclient
enabled: true
script: messagebox.lua

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

@ -0,0 +1,80 @@
default font: helvetica-12px
default font color: [210, 210, 210, 255]
buttons:
default:
font: helvetica-11px-bold
font color: [240, 173, 77, 255]
default size: [106, 24]
bordered image:
source: button.png
border: 5
hover state:
bordered image:
source: button_hover.png
border: 5
down state:
text translate: [1, 1]
bordered image:
source: button_down.png
border: 5
panels:
default:
# the default panel is empty
mainMenuBackground:
image: background.png
antialised: true
roundedGridPanel:
bordered image:
source: panel_rounded.png
border: 4
flatPanel:
bordered image:
source: panel_flat.png
border: 1
labels:
default:
large:
font: helvetica-12px-bold
windows:
default:
font: helvetica-11px-bold
font color: [240, 173, 77, 255]
head:
height: 20
bordered image:
source: window.png
size: [256, 19]
border: 4
bottom: 3
body:
bordered image:
source: window.png
size: [256, 237]
offset: [0, 19]
border: 4
top: 0
text edits:
default:
default size: [86, 20]
text margin: 3
bordered image:
source: panel_flat.png
border: 1
line decorations:
default:
bordered image:
source: horizontal_separator.png
top: 2

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

@ -1,137 +0,0 @@
default font: sans-11px-bold
default font color: [51, 51, 51, 255]
buttons:
default:
default size: [96, 22]
font color: [0, 115, 234, 255]
bordered image:
source: lightness/button-up.png
left border: [0,2,2,6]
right border: [22,2,2,6]
top border: [2,0,20,2]
bottom border: [2,8,20,2]
top left corner: [0,0,2,2]
top right corner: [22,0,2,2]
bottom left corner: [0,8,2,2]
bottom right corner: [22,8,2,2]
center: [2,2,20,6]
hover state:
font color: [255, 255, 255, 255]
bordered image:
source: lightness/button-hover.png
left border: [0,2,2,6]
right border: [22,2,2,6]
top border: [2,0,20,2]
bottom border: [2,8,20,2]
top left corner: [0,0,2,2]
top right corner: [22,0,2,2]
bottom left corner: [0,8,2,2]
bottom right corner: [22,8,2,2]
center: [2,2,20,6]
down state:
font color: [255, 0, 132, 255]
bordered image:
source: lightness/button-down.png
left border: [0,2,2,6]
right border: [22,2,2,6]
top border: [2,0,20,2]
bottom border: [2,8,20,2]
top left corner: [0,0,2,2]
top right corner: [22,0,2,2]
bottom left corner: [0,8,2,2]
bottom right corner: [22,8,2,2]
center: [2,2,20,6]
panels:
default:
# the default panel is empty
mainMenuBackground:
image: lightness/background.png
antialised: true
roundedGridPanel:
bordered image:
source: lightness/menupanel.png
left border: [0,2,2,6]
right border: [22,2,2,6]
top border: [2,0,20,2]
bottom border: [2,8,20,2]
top left corner: [0,0,2,2]
top right corner: [22,0,2,2]
bottom left corner: [0,8,2,2]
bottom right corner: [22,8,2,2]
center: [2,2,20,6]
flatPanel:
bordered image:
source: lightness/panel.png
left border: [0,2,2,6]
right border: [22,2,2,6]
top border: [2,0,20,2]
bottom border: [2,8,20,2]
top left corner: [0,0,2,2]
top right corner: [22,0,2,2]
bottom left corner: [0,8,2,2]
bottom right corner: [22,8,2,2]
center: [2,2,20,6]
labels:
default:
font: sans-12px
windows:
default:
font: sans-12px-bold
font color: [80, 80, 80, 255]
head:
text align: left
margin: 8
height: 26
bordered image:
source: lightness/window.png
left border: [0,5,5,22]
right border: [251,5,5,22]
top border: [5,0,246,5]
bottom border: [5,27,246,5]
top left corner: [0,0,5,5]
top right corner: [251,0,5,5]
bottom left corner: [0,27,5,5]
bottom right corner: [251,27,5,5]
center: [5,5,246,22]
body:
bordered image:
source: lightness/window.png
left border: [0,32,2,222]
right border: [254,32,2,222]
bottom border: [2,254,252,2]
bottom left corner: [0,254,2,2]
bottom right corner: [254,254,2,2]
center: [2, 32, 92, 92]
text edits:
default:
default size: [86, 20]
font color: [80, 80, 80, 255]
text margin: 3
bordered image:
source: lightness/button-down.png
left border: [0,2,2,6]
right border: [22,2,2,6]
top border: [2,0,20,2]
bottom border: [2,8,20,2]
top left corner: [0,0,2,2]
top right corner: [22,0,2,2]
bottom left corner: [0,8,2,2]
bottom right corner: [22,8,2,2]
center: [2,2,20,6]
line decorations:
default:
bordered image:
source: lightness/window.png
top border: [2,254,252,2]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

@ -1,111 +0,0 @@
default font: tibia-10px-antialised
default font color: [191, 191, 191, 255]
default texture: tibiaskin/skin.png
buttons:
default:
font: tibia-8px-antialised
font color: [238, 238, 238, 255]
default size: [86, 20]
bordered image:
left border: [45,139,1,18]
right border: [130,139,1,18]
top border: [46,138,84,1]
bottom border: [46,157,84,1]
top left corner: [45,138,1,1]
top right corner: [130,138,1,1]
bottom left corner: [45,157,1,1]
bottom right corner: [130,157,1,1]
center: [46,139,84,18]
down state:
text translate: [1, 1]
bordered image:
left border: [45,159,1,18]
right border: [130,159,1,18]
top border: [46,158,84,1]
bottom border: [46,177,84,1]
top left corner: [45,158,1,1]
top right corner: [130,158,1,1]
bottom left corner: [45,177,1,1]
bottom right corner: [130,177,1,1]
center: [46,159,84,18]
panels:
default:
# the default panel is empty
mainMenuBackground:
image: tibiaskin/background.png
antialised: true
roundedGridPanel:
bordered image:
left border: [0,214,5,32]
right border: [6,214,5,32]
top border: [43,214,32,5]
bottom border: [43,220,32,5]
top left corner: [43,225,5,5]
top right corner: [49,225,5,5]
bottom left corner: [43,230,5,5]
bottom right corner: [48,231,5,5]
center: [11,214,32,32]
flatPanel:
bordered image:
left border: [275,0,1,96]
right border: [276,0,1,96]
top border: [2,210,91,1]
bottom border: [2,211,91,1]
top left corner: [275,0,1,1]
top right corner: [276,0,1,1]
bottom left corner: [2,210,1,1]
bottom right corner: [276,95,1,1]
center: [0, 0, 96, 96]
labels:
default:
windows:
default:
font color: [143, 143, 143, 255]
head:
height: 17
bordered image:
left border: [106,187,4,9]
right border: [110,187,4,9]
top border: [114,183,92,4]
bottom border: [114,196,92,4]
top left corner: [106,183,4,4]
top right corner: [110,183,4,4]
bottom left corner: [106,196,4,4]
bottom right corner: [110,196,4,4]
center: [114,187,96,9]
body:
bordered image:
left border: [98,180,4,12]
right border: [99,180,4,12]
bottom border: [2,193,96,4]
bottom left corner: [98,193,4,4]
bottom right corner: [102,193,4,4]
center: [0, 0, 96, 96]
text edits:
default:
default size: [86, 16]
text margin: 3
bordered image:
left border: [308,97,1,1]
right border: [319,97,1,10]
top border: [309,96,10,1]
bottom border: [309,107,10,1]
top left corner: [308,96,1,1]
top right corner: [319,96,1,1]
bottom left corner: [308,107,1,1]
bottom right corner: [319,107,1,1]
center: [309,97,10,10]
line decorations:
default:
bordered image:
top border: [2,210,96,2]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

@ -1,4 +1,4 @@
rootUI = UI.getRootContainer()
rootUI = App.getRootContainer()
-- AnchorPoint
AnchorNone = 0

@ -1,50 +1,60 @@
window#enterGameWindow
Window
id: enterGameWindow
title: Enter Game
size: 236 178
anchor.centerIn: parent
lockOnLoad: true
%label
Label
text: Account name
position: 18 33
%label
Label
text: "Password:"
position: 18 62
%label
text: |
If you don't have
an account yet
Label
text:
[[If you don't have
an account yet]]
anchors.top: parent.top
anchors.left: parent.left
margin: 87 18
%button.notImplemented
Button
text: Create Account
anchors.top: parent.top
anchors.right: parent.right
margin: 94 18
onClick:
function(self)
displayErrorBox("Error", "Not implemented yet")
self.parent:destroy()
end
%button.small
SmallButton
text: Ok
anchors.bottomRight: parent.bottomRight
margin: 10 66
onClick: EnterGame_connectToLoginServer()
%button.small.closeParent
SmallButton
text: Cancel
anchors.bottom: parent.bottom
anchors.right: parent.right
margin: 10 13
onClick: displayErrorBox("Error", "Not implemented yet")
%textEdit#accountNameTextEdit
TextEdit
id: accountNameTextEdit
text: tibialua0
anchors.top: parent.top
anchors.right: parent.right
margin: 32 18
%textEdit#passwordTextEdit
TextEdit
id: passwordTextEdit
text: lua123456
text-hidden: true
anchors.top: parent.top

@ -1,37 +1,63 @@
%panel#mainBackground
image: { source: background.png; antialised: true }
@import "additional_elements"
Panel
id: "mainBackground"
image:
source: "background.png"
antialised: true
anchor.fill: parent
%panel#mainMenuPanel.flat
size: 117 171
lista:
- valor1
- valor2
- valor3
FlatPanel
id: mainMenuPanel
size: {117, 171}
anchors.bottom: parent.bottom
anchors.left: parent.left
margin: 70 60
margin: {70, 60}
button
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 6
%button.first
// enter game button
Button
text: "Enter Game"
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 16
text: Enter Game
onClick: loadUI("entergamewindow")
onClick: |
function(self)
if not mainMenu:getChild("enterGameWindow") then
local enterGame = loadUI("entergamewindow")
enterGame:setLocked(true)
end
end
%button.notImplemented
text: Access Account
Button
text: "Access Account"
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 6
onClick: loadUI("entergamewindow")
%button
text: Options
Button
text: "Options"
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 6
onClick: loadUI("optionswindow")
%button
text: Info
Button
text: "Info"
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 6
onClick: loadUI("infowindow")
%button
text: Exit
Button
text: "Exit"
anchors.top: prev.bottom
anchors.horizontalCenter: parent.horizontalCenter
margin.top: 6
onClick: terminateApplication()

@ -4,6 +4,7 @@
#include <global.h>
struct ConfigValueProxy {
ConfigValueProxy(const std::string& v) : value(v) { }
operator std::string() const { return convert<std::string>(value); }
operator float() const { return convert<float>(value); }
operator int() const { return convert<int>(value); }
@ -20,7 +21,7 @@ public:
template<class T>
void set(const std::string& key, const T& value) { m_confsMap[key] = convert<std::string>(value); }
ConfigValueProxy get(const std::string& key) { return ConfigValueProxy{m_confsMap[key]}; }
ConfigValueProxy get(const std::string& key) { return ConfigValueProxy(m_confsMap[key]); }
private:
std::string m_fileName;

@ -29,12 +29,12 @@ void Dispatcher::poll()
}
}
void Dispatcher::scheduleTask(const boost::function<void()>& callback, int delay)
void Dispatcher::scheduleTask(const std::function<void()>& callback, int delay)
{
m_scheduledTaskList.push(new ScheduledTask(g_engine.getCurrentFrameTicks() + delay, callback));
}
void Dispatcher::addTask(const boost::function<void()>& callback, bool pushFront)
void Dispatcher::addTask(const std::function<void()>& callback, bool pushFront)
{
if(pushFront)
m_taskList.push_front(callback);

@ -4,15 +4,12 @@
#include <global.h>
#include <queue>
#include <boost/bind.hpp>
#include <boost/function.hpp>
struct ScheduledTask {
ScheduledTask(const boost::function<void()>& _callback) : ticks(0), callback(_callback) { }
ScheduledTask(int _ticks, const boost::function<void()>& _callback) : ticks(_ticks), callback(_callback) { }
ScheduledTask(const std::function<void()>& _callback) : ticks(0), callback(_callback) { }
ScheduledTask(int _ticks, const std::function<void()>& _callback) : ticks(_ticks), callback(_callback) { }
bool operator<(const ScheduledTask& other) const { return ticks > other.ticks; }
int ticks;
boost::function<void()> callback;
std::function<void()> callback;
};
struct lessScheduledTask : public std::binary_function<ScheduledTask*&, ScheduledTask*&, bool> {
@ -31,13 +28,13 @@ public:
void poll();
/// Add an event
void addTask(const boost::function<void()>& callback, bool pushFront = false);
void addTask(const std::function<void()>& callback, bool pushFront = false);
/// Schedula an event
void scheduleTask(const boost::function<void()>& callback, int delay);
void scheduleTask(const std::function<void()>& callback, int delay);
private:
std::list<boost::function<void()>> m_taskList;
std::list<std::function<void()>> m_taskList;
std::priority_queue<ScheduledTask*, std::vector<ScheduledTask*>, lessScheduledTask> m_scheduledTaskList;
};

@ -6,7 +6,7 @@
#include <graphics/textures.h>
#include <ui/uicontainer.h>
#include <ui/uiskins.h>
#include <script/scriptcontext.h>
#include <script/luainterface.h>
#include <net/connection.h>
Engine g_engine;
@ -113,7 +113,7 @@ void Engine::stop()
void Engine::onClose()
{
g_dispatcher.addTask(boost::bind(&ScriptContext::callModuleField, &g_lua, "App", "onClose"));
g_lua.getGlobal("onClose")->call("onClose");
}
void Engine::onResize(const Size& size)

@ -1,2 +0,0 @@
#include "modules.h"

@ -1,8 +0,0 @@
#ifndef MODULES_H
#define MODULES_H
class Modules
{
};
#endif // MODULES_H

@ -0,0 +1,29 @@
#include "packages.h"
#include <core/resources.h>
#include <script/luainterface.h>
Packages g_packages;
void Packages::loadPackages()
{
std::list<std::string> packages = g_resources.listDirectoryFiles("modules");
foreach(const std::string& package, packages) {
std::string dir = make_string("modules/", package);
g_resources.pushCurrentPath(dir);
std::list<std::string> packagesFiles = g_resources.listDirectoryFiles();
foreach(const std::string& packageFile, packagesFiles) {
if(boost::ends_with(packageFile, ".lua")) {
g_lua.runScript(packageFile);
}
}
g_resources.popCurrentPath();
}
}
void Packages::terminate()
{
}

@ -0,0 +1,15 @@
#ifndef PACKAGES_H
#define PACKAGES_H
#include <global.h>
class Packages
{
public:
void loadPackages();
void terminate();
};
extern Packages g_packages;
#endif // MODULES_H

@ -2,7 +2,6 @@
#include "resources.h"
#include "platform.h"
#include <boost/algorithm/string.hpp>
#include <physfs.h>
Resources g_resources;
@ -148,12 +147,15 @@ std::list<std::string> Resources::listDirectoryFiles(const std::string& director
void Resources::pushCurrentPath(const std::string &currentPath)
{
//logTraceDebug(currentPath);
m_currentPaths.push(currentPath);
}
void Resources::popCurrentPath()
{
m_currentPaths.pop();
//if(!m_currentPaths.empty())
// logTraceDebug(m_currentPaths.top());
}
std::string Resources::resolvePath(const std::string& path)

@ -16,13 +16,17 @@
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <algorithm>
#include <exception>
#include <memory>
#include <type_traits>
#include <functional>
#include <regex>
// smart pointers
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
// string algorithms
#include <boost/algorithm/string.hpp>
// constants
#include <const.h>
@ -41,5 +45,6 @@
#include <util/foreach.h>
#include <util/makestring.h>
#include <util/logger.h>
#include <util/algorithms.h>
#endif // GLOBAL_H

@ -44,7 +44,7 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra
}
m_currentFrame = -1;
g_dispatcher.scheduleTask(boost::bind(&AnimatedTexture::processAnimation, this), 0);
g_dispatcher.scheduleTask(std::bind(&AnimatedTexture::processAnimation, this), 0);
}
AnimatedTexture::~AnimatedTexture()
@ -70,7 +70,7 @@ void AnimatedTexture::processAnimation()
if(m_currentFrame >= m_numFrames)
m_currentFrame = 0;
m_textureId = m_framesTextureId[m_currentFrame];
AnimatedTexturePtr me = boost::static_pointer_cast<AnimatedTexture>(shared_from_this());
AnimatedTexturePtr me = std::static_pointer_cast<AnimatedTexture>(shared_from_this());
if(me.use_count() > 1)
g_dispatcher.scheduleTask(boost::bind(&AnimatedTexture::processAnimation, me), m_framesDelay[m_currentFrame]);
g_dispatcher.scheduleTask(std::bind(&AnimatedTexture::processAnimation, me), m_framesDelay[m_currentFrame]);
}

@ -45,7 +45,7 @@ private:
int m_lastAnimCheckTicks;
};
typedef boost::shared_ptr<AnimatedTexture> AnimatedTexturePtr;
typedef boost::weak_ptr<AnimatedTexture> AnimatedTextureWeakPtr;
typedef std::shared_ptr<AnimatedTexture> AnimatedTexturePtr;
typedef std::weak_ptr<AnimatedTexture> AnimatedTextureWeakPtr;
#endif // ANIMATEDTEXTURE_H

@ -96,13 +96,13 @@ BorderedImagePtr BorderedImage::loadFromOTMLNode(OTMLNode* node, TexturePtr defa
left = node->readAt("left", left);
right = node->readAt("right", right);
leftBorder = Rect(subRect.left(), subRect.top() + top, left, subRect.height() - top - bottom);
rightBorder = Rect(subRect.right() - right, subRect.top() + top, right, subRect.height() - top - bottom);
rightBorder = Rect(subRect.right() - right + 1, subRect.top() + top, right, subRect.height() - top - bottom);
topBorder = Rect(subRect.left() + left, subRect.top(), subRect.width() - right - left, top);
bottomBorder = Rect(subRect.left() + left, subRect.bottom() - bottom, subRect.width() - right - left, bottom);
bottomBorder = Rect(subRect.left() + left, subRect.bottom() - bottom + 1, subRect.width() - right - left, bottom);
topLeftCorner = Rect(subRect.left(), subRect.top(), left, top);
topRightCorner = Rect(subRect.right() - right, subRect.top(), right, top);
topRightCorner = Rect(subRect.right() - right + 1, subRect.top(), right, top);
bottomLeftCorner = Rect(subRect.left(), subRect.bottom() - bottom, left, bottom);
bottomRightCorner = Rect(subRect.right() - right, subRect.bottom() - bottom, right, bottom);
bottomRightCorner = Rect(subRect.right() - right + 1, subRect.bottom() - bottom + 1, right, bottom);
center = Rect(subRect.left() + left, subRect.top() + top, subRect.width() - right - left, subRect.height() - top - bottom);
leftBorder = node->readAt("left border", leftBorder);
rightBorder = node->readAt("right border", rightBorder);

@ -31,7 +31,7 @@
#include <otml/otmlnode.h>
class BorderedImage;
typedef boost::shared_ptr<BorderedImage> BorderedImagePtr;
typedef std::shared_ptr<BorderedImage> BorderedImagePtr;
class BorderedImage : public Image
{

@ -1,27 +1,3 @@
/* The MIT License
*
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <global.h>
#include <core/resources.h>
#include <graphics/font.h>
@ -54,6 +30,7 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
// if all pixels were alpha we found the width
if(columnFilledPixels == 0) {
width = x - glyphCoords.left();
width += m_glyphSpacing.width();
if(m_glyphHeight >= 16 && lastColumnFilledPixels >= m_glyphHeight/3)
width += 1;
break;
@ -84,11 +61,11 @@ bool Font::load(const std::string& file)
// required values
textureName = doc->valueAt("image");
glyphSize = doc->readAt("image glyph size", Size(16, 16));
m_glyphHeight = doc->readAt("glyph height", 11);
m_firstGlyph = doc->readAt("first glyph", 32);
m_topMargin = doc->readAt("top margin", 0);
m_glyphSpacing = doc->readAt("glyph spacing", Size(0,0));
glyphSize = doc->readAt("image-glyph-size", Size(16, 16));
m_glyphHeight = doc->readAt("glyph-height", 11);
m_firstGlyph = doc->readAt("first-glyph", 32);
m_topMargin = doc->readAt("top-margin", 0);
m_glyphSpacing = doc->readAt("glyph-spacing", Size(0,0));
// load texture
m_texture = g_textures.get(textureName);
@ -101,16 +78,16 @@ bool Font::load(const std::string& file)
calculateGlyphsWidthsAutomatically(glyphSize);
// read custom widths
if(doc->hasChild("glyph widths")) {
if(doc->hasChild("glyph-widths")) {
std::map<int, int> glyphWidths;
doc->readAt("glyph widths", &glyphWidths);
doc->readAt("glyph-widths", &glyphWidths);
foreach(const auto& pair, glyphWidths)
m_glyphsSize[pair.first].setWidth(pair.second);
}
// calculate glyphs texture coords
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
for(int glyph = m_firstGlyph; glyph< 256; ++glyph) {
for(int glyph = m_firstGlyph; glyph < 256; ++glyph) {
m_glyphsTextureCoords[glyph].setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.width(),
((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.height(),
m_glyphsSize[glyph].width(),
@ -248,7 +225,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
lineWidths.resize(lines+1);
lineWidths[lines] = 0;
} else if(glyph >= 32) {
lineWidths[lines] += m_glyphsSize[glyph].width() + m_glyphSpacing.width();
lineWidths[lines] += m_glyphsSize[glyph].width();
maxLineWidth = std::max(maxLineWidth, lineWidths[lines]);
}
}
@ -281,7 +258,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
// render only if the glyph is valid
if(glyph >= 32 && glyph != (uchar)'\n') {
virtualPos.x += m_glyphsSize[glyph].width() + m_glyphSpacing.width();
virtualPos.x += m_glyphsSize[glyph].width();
}
}

@ -75,6 +75,6 @@ private:
Size m_glyphsSize[256];
};
typedef boost::shared_ptr<Font> FontPtr;
typedef std::shared_ptr<Font> FontPtr;
#endif // FONT_H

@ -1,32 +1,7 @@
/* The MIT License
*
* Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <global.h>
#include <core/resources.h>
#include <graphics/fonts.h>
#include <boost/algorithm/string.hpp>
Fonts g_fonts;

@ -44,6 +44,6 @@ protected:
Rect m_textureCoords;
};
typedef boost::shared_ptr<Image> ImagePtr;
typedef std::shared_ptr<Image> ImagePtr;
#endif // IMAGE_H

@ -27,7 +27,7 @@
#include <global.h>
class Texture : public boost::enable_shared_from_this<Texture>
class Texture : public std::enable_shared_from_this<Texture>
{
public:
/// Create a texture, width and height must be a multiple of 2
@ -55,7 +55,7 @@ protected:
Size m_glSize;
};
typedef boost::shared_ptr<Texture> TexturePtr;
typedef boost::weak_ptr<Texture> TextureWeakPtr;
typedef std::shared_ptr<Texture> TexturePtr;
typedef std::weak_ptr<Texture> TextureWeakPtr;
#endif // TEXTURE_H

@ -28,8 +28,6 @@
#include <graphics/textureloader.h>
#include <core/dispatcher.h>
#include <boost/algorithm/string.hpp>
Textures g_textures;
TexturePtr Textures::get(const std::string& textureFile)

@ -40,61 +40,57 @@ void Connection::poll()
ioService.reset();
}
void Connection::connect(const std::string& host, uint16 port, const boost::function<void()>& connectCallback)
void Connection::connect(const std::string& host, uint16 port, const std::function<void()>& connectCallback)
{
m_connectCallback = connectCallback;
m_connectionState = CONNECTION_STATE_RESOLVING;
boost::asio::ip::tcp::resolver::query query(host, convert<std::string>(port));
m_resolver.async_resolve(query, boost::bind(&Connection::onResolve, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator));
m_resolver.async_resolve(query, std::bind(&Connection::onResolve, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
m_timer.expires_from_now(boost::posix_time::seconds(2));
m_timer.async_wait(boost::bind(&Connection::onTimeout, shared_from_this(), boost::asio::placeholders::error));
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
}
void Connection::send(OutputMessage *outputMessage)
{
boost::asio::async_write(m_socket,
boost::asio::buffer(outputMessage->getBuffer(), outputMessage->getMessageSize()),
boost::bind(&Connection::onSend, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
std::bind(&Connection::onSend, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
m_timer.expires_from_now(boost::posix_time::seconds(2));
m_timer.async_wait(boost::bind(&Connection::onTimeout, shared_from_this(), boost::asio::placeholders::error));
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
}
void Connection::onTimeout(const boost::system::error_code& error)
{
if(error != boost::asio::error::operation_aborted)
g_dispatcher.addTask(boost::bind(m_errorCallback, error));
g_dispatcher.addTask(std::bind(m_errorCallback, error));
}
void Connection::onResolve(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator endpointIterator)
{
trace();
m_timer.cancel();
if(error) {
if(m_errorCallback)
g_dispatcher.addTask(boost::bind(m_errorCallback, error));
g_dispatcher.addTask(std::bind(m_errorCallback, error));
return;
}
m_socket.async_connect(*endpointIterator, boost::bind(&Connection::onConnect, shared_from_this(), boost::asio::placeholders::error));
m_socket.async_connect(*endpointIterator, std::bind(&Connection::onConnect, shared_from_this(), std::placeholders::_1));
m_timer.expires_from_now(boost::posix_time::seconds(2));
m_timer.async_wait(boost::bind(&Connection::onTimeout, shared_from_this(), boost::asio::placeholders::error));
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
}
void Connection::onConnect(const boost::system::error_code& error)
{
trace();
m_timer.cancel();
if(error) {
if(m_errorCallback)
g_dispatcher.addTask(boost::bind(m_errorCallback, error));
g_dispatcher.addTask(std::bind(m_errorCallback, error));
return;
}
@ -103,29 +99,25 @@ void Connection::onConnect(const boost::system::error_code& error)
// Start listening.
boost::asio::async_read(m_socket,
boost::asio::buffer(m_inputMessage.getBuffer(), InputMessage::HEADER_LENGTH),
boost::bind(&Connection::onRecvHeader, shared_from_this(), boost::asio::placeholders::error));
std::bind(&Connection::onRecvHeader, shared_from_this(), std::placeholders::_1));
}
void Connection::onSend(const boost::system::error_code& error, size_t)
{
trace();
m_timer.cancel();
if(error) {
if(m_errorCallback)
g_dispatcher.addTask(boost::bind(m_errorCallback, error));
g_dispatcher.addTask(std::bind(m_errorCallback, error));
return;
}
}
void Connection::onRecvHeader(const boost::system::error_code& error)
{
trace();
if(error) {
if(m_errorCallback)
g_dispatcher.addTask(boost::bind(m_errorCallback, error));
g_dispatcher.addTask(std::bind(m_errorCallback, error));
return;
}
@ -134,16 +126,14 @@ void Connection::onRecvHeader(const boost::system::error_code& error)
boost::asio::async_read(m_socket,
boost::asio::buffer(m_inputMessage.getBuffer() + InputMessage::CHECKSUM_POS, messageSize),
boost::bind(&Connection::onRecvData, shared_from_this(), boost::asio::placeholders::error));
std::bind(&Connection::onRecvData, shared_from_this(), std::placeholders::_1));
}
void Connection::onRecvData(const boost::system::error_code& error)
{
trace();
if(error) {
if(m_errorCallback)
g_dispatcher.addTask(boost::bind(m_errorCallback, error));
g_dispatcher.addTask(std::bind(m_errorCallback, error));
return;
}
@ -151,7 +141,7 @@ void Connection::onRecvData(const boost::system::error_code& error)
// must be called outside dispatcher cause of inputmessage.
if(m_recvCallback)
m_recvCallback(&m_inputMessage);
//g_dispatcher.addTask(boost::bind(m_recvCallback, &m_inputMessage));
//g_dispatcher.addTask(std::bind(m_recvCallback, &m_inputMessage));
// keep reading
@ -159,6 +149,6 @@ void Connection::onRecvData(const boost::system::error_code& error)
/*m_inputMessage.reset();
boost::asio::async_read(m_socket,
boost::asio::buffer(m_inputMessage.getBuffer(), InputMessage::HEADER_LENGTH),
boost::bind(&Connection::onRecvHeader, shared_from_this(), boost::asio::placeholders::error));*/
std::bind(&Connection::onRecvHeader, shared_from_this(), std::placeholders::_1));*/
}

@ -31,19 +31,18 @@
#include <net/outputmessage.h>
#include <boost/asio.hpp>
#include <boost/function.hpp>
typedef boost::function<void(boost::system::error_code&)> ErrorCallback;
typedef boost::function<void(InputMessage*)> RecvCallback;
typedef std::function<void(boost::system::error_code&)> ErrorCallback;
typedef std::function<void(InputMessage*)> RecvCallback;
class Connection : public boost::enable_shared_from_this<Connection>, boost::noncopyable
class Connection : public std::enable_shared_from_this<Connection>, boost::noncopyable
{
public:
Connection();
static void poll();
void connect(const std::string& host, uint16 port, const boost::function<void()>& connectCallback);
void connect(const std::string& host, uint16 port, const std::function<void()>& connectCallback);
void send(OutputMessage *outputMessage);
void setErrorCallback(const ErrorCallback& errorCallback) { m_errorCallback = errorCallback; }
@ -66,7 +65,7 @@ public:
private:
ErrorCallback m_errorCallback;
RecvCallback m_recvCallback;
boost::function<void()> m_connectCallback;
std::function<void()> m_connectCallback;
ConnectionState_t m_connectionState;
boost::asio::deadline_timer m_timer;
@ -76,6 +75,6 @@ private:
};
typedef boost::shared_ptr<Connection> ConnectionPtr;
typedef std::shared_ptr<Connection> ConnectionPtr;
#endif

@ -29,12 +29,12 @@
Protocol::Protocol() :
m_connection(new Connection)
{
m_connection->setErrorCallback(boost::bind(&Protocol::onError, this, _1));
m_connection->setRecvCallback(boost::bind(&Protocol::onRecv, this, _1));
m_connection->setErrorCallback(std::bind(&Protocol::onError, this, std::placeholders::_1));
m_connection->setRecvCallback(std::bind(&Protocol::onRecv, this, std::placeholders::_1));
m_xteaEncryptionEnabled = false;
}
void Protocol::connect(const std::string& host, uint16 port, const boost::function<void()>& callback)
void Protocol::connect(const std::string& host, uint16 port, const std::function<void()>& callback)
{
m_connection->connect(host, port, callback);
}

@ -28,7 +28,7 @@
#include <net/connection.h>
#include <net/inputmessage.h>
#include <net/outputmessage.h>
#include <script/scriptobject.h>
#include <script/luaobject.h>
#define CIPSOFT_PUBLIC_RSA "1321277432058722840622950990822933849527763264961655079678763618" \
"4334395343554449668205332383339435179772895415509701210392836078" \
@ -38,18 +38,18 @@
//#define RSA "109120132967399429278860960508995541528237502902798129123468757937266291492576446330739696001110603907230888610072655818825358503429057592827629436413108566029093628212635953836686562675849720620786279431090218017681061521755056710823876476444260558147179707119674283982419152118103759076030616683978566631413"
class Protocol : public ScriptObject
class Protocol : public LuaObject
{
public:
Protocol();
void connect(const std::string& host, uint16 port, const boost::function<void()>& callback);
void connect(const std::string& host, uint16 port, const std::function<void()>& callback);
void send(OutputMessage *outputMessage);
virtual void onRecv(InputMessage *inputMessage);
virtual void onError(const boost::system::error_code& err);
virtual const char *getScriptObjectType() const { return "Protocol"; }
virtual const char* getLuaTypeName() const { return "Protocol"; }
protected:
uint32 m_xteaKey[4];
@ -63,6 +63,6 @@ private:
ConnectionPtr m_connection;
};
typedef boost::shared_ptr<Protocol> ProtocolPtr;
typedef std::shared_ptr<Protocol> ProtocolPtr;
#endif

@ -44,6 +44,6 @@ protected:
mpz_t m_p, m_q, m_u, m_d, m_dp, m_dq, m_mod;
};
typedef boost::shared_ptr<Rsa> RsaPtr;
typedef std::shared_ptr<Rsa> RsaPtr;
#endif //RSA_H

@ -0,0 +1,191 @@
#ifndef LUABINDER_H
#define LUABINDER_H
#include "luavalue.h"
#include "luastate.h"
namespace luabinder
{
// transform const T& -> T
template<typename T>
struct remove_const_ref {
typedef typename std::remove_const<typename std::remove_reference<T>::type>::type type;
};
// pack an value into tuple recursively
template<int N>
struct pack_values_into_tuple {
template<typename Tuple>
static void call(Tuple& tuple, LuaState* lua) {
typedef typename std::tuple_element<N-1, Tuple>::type ValueType;
std::get<N-1>(tuple) = safe_luavalue_cast<ValueType>(lua->popValue());
pack_values_into_tuple<N-1>::call(tuple, lua);
}
};
template<>
struct pack_values_into_tuple<0> {
template<typename Tuple>
static void call(Tuple &tuple, LuaState* lua) { }
};
// call function
template<typename Ret, typename F, typename... Args>
typename std::enable_if<!std::is_void<Ret>::value, int>::type
call_fun_and_push_result(const F& f, LuaState* lua, Args... args) {
Ret ret = f(args...);
lua->pushValue(safe_to_luavalue(ret));
return 1;
}
// call function with no return
template<typename Ret, typename F, typename... Args>
typename std::enable_if<std::is_void<Ret>::value, int>::type
call_fun_and_push_result(const F& f, LuaState* lua, Args... args) {
f(args...);
return 0;
}
// expand function arguments for calling
template<int N, typename Ret>
struct expand_fun_arguments {
template<typename Tuple, typename F, typename... Args>
static int call(const Tuple& tuple, const F& f, LuaState* lua, Args... args) {
return expand_fun_arguments<N-1,Ret>::call(tuple, f, lua, std::cref(std::get<N-1>(tuple)), args...);
}
};
template<typename Ret>
struct expand_fun_arguments<0,Ret> {
template<typename Tuple, typename F, typename... Args>
static int call(const Tuple& tuple, const F& f, LuaState* lua, Args... args) {
return call_fun_and_push_result<Ret>(f, lua, args...);
}
};
// bind different types of functions
template<typename Ret, typename F, typename Tuple>
LuaCppFunction bind_fun_specializer(const F& f) {
enum { N = std::tuple_size<Tuple>::value };
return [=](LuaState* lua) {
if(lua->stackSize() != N)
throw LuaBadNumberOfArgumentsException(N, lua->stackSize());
Tuple tuple;
pack_values_into_tuple<N>::call(tuple, lua);
return expand_fun_arguments<N,Ret>::call(tuple, f, lua);
};
}
// bind a std::function
template<typename Ret, typename... Args>
LuaCppFunction bind_fun(const std::function<Ret(Args...)>& f) {
typedef typename std::tuple<typename remove_const_ref<Args>::type...> Tuple;
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
decltype(f),
Tuple>(f);
}
// bind a custumized function
inline
LuaCppFunction bind_fun(const std::function<int(LuaState*)>& f) {
return f;
}
// convert to std::function then bind
template<typename Ret, typename... Args>
LuaCppFunction bind_fun(Ret (*f)(Args...)) {
return bind_fun(std::function<Ret(Args...)>(f));
}
// a tuple_element that works with the next algorithm
template<std::size_t __i, typename _Tp>
struct tuple_element;
template<std::size_t __i, typename _Head, typename... _Tail>
struct tuple_element<__i, std::tuple<_Head, _Tail...> >
: tuple_element<__i - 1, std::tuple<_Tail...> > { };
template<typename _Head, typename... _Tail>
struct tuple_element<0, std::tuple<_Head, _Tail...> > { typedef _Head type; };
template<typename _Head>
struct tuple_element<-1,std::tuple<_Head>> { typedef void type; };
template<std::size_t __i>
struct tuple_element<__i,std::tuple<>> { typedef void type; };
// rebind functions already binded by std::bind that have placeholders
template<typename Enable, int N, typename ArgsTuple, typename HoldersTuple, typename... Args>
struct get_holded_tuple;
template<int N, typename ArgsTuple, typename HoldersTuple, typename... Args>
struct get_holded_tuple<typename std::enable_if<(N > 0 && std::is_placeholder<typename tuple_element<N-1, HoldersTuple>::type>::value > 0), void>::type, N, ArgsTuple, HoldersTuple, Args...> {
typedef typename std::tuple_element<N-1, HoldersTuple>::type holder_type;
typedef typename tuple_element<std::is_placeholder<holder_type>::value-1, ArgsTuple>::type _arg_type;
typedef typename remove_const_ref<_arg_type>::type arg_type;
typedef typename get_holded_tuple<void, N-1, ArgsTuple, HoldersTuple, arg_type, Args...>::type type;
};
template<int N, typename ArgsTuple, typename HoldersTuple, typename... Args>
struct get_holded_tuple<typename std::enable_if<(N > 0 && std::is_placeholder<typename tuple_element<N-1, HoldersTuple>::type>::value == 0), void>::type, N, ArgsTuple, HoldersTuple, Args...> {
typedef typename get_holded_tuple<void, N-1, ArgsTuple, HoldersTuple, Args...>::type type;
};
template<typename ArgsTuple, typename HoldersTuple, typename... Args>
struct get_holded_tuple<void, 0, ArgsTuple, HoldersTuple, Args...> {
typedef typename std::tuple<Args...> type;
};
template<typename Ret, typename... Args, typename... Holders>
LuaCppFunction bind_fun(const std::_Bind<Ret (*(Holders...))(Args...)>& f) {
typedef typename std::tuple<Args...> ArgsTuple;
typedef typename std::tuple<Holders...> HoldersTuple;
typedef typename get_holded_tuple<void, sizeof...(Holders), ArgsTuple, HoldersTuple>::type Tuple;
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
decltype(f),
Tuple>(f);
}
template<typename Obj, typename Ret, typename... Args, typename... Holders>
LuaCppFunction bind_fun(const std::_Bind<std::_Mem_fn<Ret (Obj::*)(Args...)>(Obj*, Holders...)>& f) {
typedef typename std::tuple<Args...> ArgsTuple;
typedef typename std::tuple<Holders...> HoldersTuple;
typedef typename get_holded_tuple<void, sizeof...(Holders), ArgsTuple, HoldersTuple>::type Tuple;
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
decltype(f),
Tuple>(f);
}
// custumized functions already binded by std::bind doesn't need to be bind again
template<typename Obj>
LuaCppFunction bind_fun(const std::_Bind<std::_Mem_fn<int (Obj::*)(LuaState*)>(Obj*, std::_Placeholder<1>)>& f) {
return f;
}
inline
LuaCppFunction bind_fun(const std::_Bind<int (*(std::_Placeholder<1>))(LuaState*)>& f) {
return f;
}
// bind member function
template<typename Ret, typename Obj, typename... Args>
LuaCppFunction bind_mem_fun(Ret (Obj::*f)(Args...)) {
auto mf = std::mem_fn(f);
typedef typename std::tuple<Obj*, typename remove_const_ref<Args>::type...> Tuple;
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
decltype(mf),
Tuple>(mf);
}
template<typename Ret, typename Obj, typename... Args>
LuaCppFunction bind_mem_fun(Ret (Obj::*f)(Args...) const) {
auto mf = std::mem_fn(f);
typedef typename std::tuple<Obj*, typename remove_const_ref<Args>::type...> Tuple;
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
decltype(mf),
Tuple>(mf);
}
// bind custumized member function
template<typename Obj>
LuaCppFunction bind_mem_fun(int (Obj::*f)(LuaState*)) {
auto mf = std::mem_fn(f);
return [=](LuaState* lua) {
lua->insert(1);
auto obj = safe_luavalue_cast<Obj*>(lua->popValue());
return mf(obj, lua);
};
}
}
#endif // LUABINDER_H

@ -0,0 +1,19 @@
#ifndef LUADECLARATIONS_H
#define LUADECLARATIONS_H
#include <global.h>
class LuaInterface;
class LuaState;
class LuaValue;
class LuaObject;
typedef std::function<int(LuaState*)> LuaCppFunction;
typedef std::shared_ptr<LuaCppFunction> LuaCppFunctionPtr;
typedef std::shared_ptr<LuaValue> LuaValuePtr;
typedef std::shared_ptr<LuaObject> LuaObjectPtr;
typedef std::vector<LuaValuePtr> LuaValueList;
#endif // LUADECLARATIONS_H

@ -0,0 +1,39 @@
#include "luaexception.h"
#include "luainterface.h"
LuaException::LuaException(const std::string& error, int traceLevel)
{
generateLuaErrorMessage(error, traceLevel);
}
void LuaException::generateLuaErrorMessage(const std::string& error, int traceLevel)
{
// clear stack, to prevent further errors
g_lua.clearStack();
// append trace level to error message
if(traceLevel >= 0)
m_what = make_string("LUA ERROR: ", g_lua.getTraceback(error, traceLevel));
else
m_what = make_string("LUA ERROR: ", error);
}
LuaBadNumberOfArgumentsException::LuaBadNumberOfArgumentsException(int expected, int got)
{
std::string error = "attempt to call a function with wrong number of arguments";
if(expected >= 0 && got >= 0)
error = make_string(error, " (expected ", expected, ", but got ", got, ")");
generateLuaErrorMessage(error, 1);
}
LuaBadTypeConversinException::LuaBadTypeConversinException(const std::string& typeName)
{
std::string error = make_string("attempt to convert ", typeName, " to a lua value");
generateLuaErrorMessage(error, 0);
}
LuaBadValueCastException::LuaBadValueCastException(const LuaValuePtr& value, const std::string& typeName)
{
std::string error = make_string("attempt to cast a ", value->getTypeName(), " lua value to ", typeName);
generateLuaErrorMessage(error, 0);
}

@ -0,0 +1,38 @@
#ifndef LUAEXCEPTION_H
#define LUAEXCEPTION_H
#include "luadeclarations.h"
/// LuaException, all lua errors are throwed by it
class LuaException : public std::exception
{
public:
LuaException(const std::string& error, int traceLevel = -1);
virtual ~LuaException() throw() { };
void generateLuaErrorMessage(const std::string& error, int traceLevel);
virtual const char* what() const throw() { return m_what.c_str(); }
protected:
LuaException() { }
std::string m_what;
};
class LuaBadNumberOfArgumentsException : public LuaException {
public:
LuaBadNumberOfArgumentsException(int expected = -1, int got = -1);
};
class LuaBadTypeConversinException : public LuaException {
public:
LuaBadTypeConversinException(const std::string& typeName = "an incompatible lua type");
};
class LuaBadValueCastException : public LuaException {
public:
LuaBadValueCastException(const LuaValuePtr& value, const std::string& typeName = "an incompatible lua type");
};
#endif

@ -0,0 +1,54 @@
#include "luainterface.h"
#include <core/engine.h>
#include <ui/ui.h>
#include "../../protocollogin.h"
void LuaInterface::registerFunctions()
{
g_lua.bindGlobalFunction("exit", std::bind(&Engine::stop, &g_engine));
g_lua.bindGlobalFunction("loadUI", std::bind(&UILoader::loadFromFile, &g_uiLoader, std::placeholders::_1, std::placeholders::_2));
g_lua.setGlobal("rootUI", safe_to_luavalue(UIContainer::getRoot()));
g_lua.registerClass("UIElement");
g_lua.bindClassStaticFunction("UIElement", "new", &UIElement::create);
g_lua.bindClassMemberField("UIElement", "id", &UIElement::getId, &UIElement::setId);
g_lua.bindClassMemberField("UIElement", "enabled", &UIElement::isEnabled, &UIElement::setEnabled);
g_lua.bindClassMemberField("UIElement", "visible", &UIElement::isVisible, &UIElement::setVisible);
g_lua.bindClassMemberField("UIElement", "focused", &UIElement::isFocused, &UIElement::setFocused);
g_lua.bindClassMemberField("UIElement", "width", &UIElement::getWidth, &UIElement::setWidth);
g_lua.bindClassMemberField("UIElement", "height", &UIElement::getHeight, &UIElement::setHeight);
g_lua.bindClassMemberField("UIElement", "parent", &UIElement::getParent, &UIElement::setParent);
g_lua.bindClassMemberFunction("UIElement", "setLocked", &UIElement::setLocked);
//g_lua.bindClassMemberFunction("UIElement", "setMargin", &UIElement::luaSetMargin);
g_lua.bindClassMemberFunction("UIElement", "destroy", &UIElement::destroyLater);
g_lua.bindClassMemberFunction("UIElement", "centerIn", &UIElement::centerIn);
g_lua.bindClassMemberFunction("UIElement", "addAnchor", &UIElement::addAnchor);
g_lua.registerClass("UIContainer", "UIElement");
g_lua.bindClassStaticFunction("UIContainer", "create", &UIContainer::create);
g_lua.bindClassMemberFunction("UIContainer", "getChild", &UIContainer::getChildById);
//g_lua.bindClassMemberFunction("UIContainer", "children", &UIContainer::getChildren);
g_lua.bindClassMemberFunction("UIContainer", "addChild", &UIContainer::addChild);
g_lua.registerClass("UILabel", "UIElement");
g_lua.bindClassStaticFunction("UILabel", "create", &UILabel::create);
g_lua.bindClassMemberField("UILabel", "text", &UILabel::getText, &UILabel::setText);
g_lua.registerClass("UIButton", "UIElement");
g_lua.bindClassStaticFunction("UIButton", "create", &UIButton::create);
g_lua.bindClassMemberField("UIButton", "text", &UIButton::getText, &UIButton::setText);
g_lua.registerClass("UITextEdit", "UIElement");
g_lua.bindClassStaticFunction("UITextEdit", "create", &UITextEdit::create);
g_lua.bindClassMemberField("UITextEdit", "text", &UITextEdit::getText, &UITextEdit::setText);
g_lua.registerClass("UIWindow", "UIContainer");
g_lua.bindClassStaticFunction("UIWindow", "create", &UIWindow::create);
g_lua.bindClassMemberField("UIWindow", "title", &UIWindow::getTitle, &UIWindow::setTitle);
g_lua.registerClass("Protocol");
g_lua.registerClass("ProtocolLogin", "Protocol");
g_lua.bindClassStaticFunction("ProtocolLogin", "create", &ProtocolLogin::create);
g_lua.bindClassMemberFunction("ProtocolLogin", "login", &ProtocolLogin::login);
g_lua.bindClassMemberFunction("ProtocolLogin", "cancel", &ProtocolLogin::cancel);
}

@ -0,0 +1,235 @@
#include "luainterface.h"
LuaInterface g_lua;
void LuaInterface::init()
{
// installs a custom loader that will load scripts correctlyfrom lua require keyword
auto loaders = getGlobal("package")->getField("loaders");
loaders->setTable(loaders->getTableSize() + 1, createCppFunction(&LuaInterface::luaScriptLoader));
// register LuaObject, the class that all other classes will derive from
registerClass("LuaObject");
bindClassMemberGetField("LuaObject", "use_count", &LuaObject::getUseCount);
// register other custom classes and functions
registerFunctions();
}
void LuaInterface::terminate()
{
collectGarbage();
}
LuaValuePtr LuaInterface::loadFunction(const std::string& buffer, const std::string& source)
{
LuaValuePtr func;
// get the function contained the buffer
if(boost::starts_with(buffer, "function")) {
runBuffer(make_string("__func = ", buffer), source);
func = getGlobal("__func");
setGlobal("__func", createNil());
// use the buffer as a function
} else
func = loadBuffer(buffer, source);
return func;
}
LuaValuePtr LuaInterface::evaluateExpression(const std::string& expression, const std::string& source)
{
// run the expression
std::string buffer = make_string("__exp = (", expression, ")");
runBuffer(buffer, source);
// get the expression result
LuaValuePtr res = getGlobal("__exp");
setGlobal("__exp", createNil());
return res;
}
LuaValuePtr LuaInterface::createEnvironment()
{
// creates a new environment table and
// redirect the new environment to the current thread global environment (aka _G)
// this allows to access global variables from _G in the new environment
// and prevents new variables on the new environment to be set on the global environment
auto env = createTable();
auto mt = createTable();
mt->setField("__index", getGlobalEnvironment());
env->setMetatable(mt);
return env;
}
void LuaInterface::registerClass(const std::string& className, const std::string& baseClass)
{
// create the class table (that it is also the class methods table)
auto klass = createTable(className);
// create the class metatable
auto klass_mt = createTable(className + "_mt");
// create the class fieldmethods table
auto klass_fieldmethods = createTable(className + "_fieldmethods");
// set metatable metamethods
klass_mt->setField("__index", &LuaInterface::luaObjectGetEvent);
klass_mt->setField("__newindex", &LuaInterface::luaObjectSetEvent);
klass_mt->setField("__eq", &LuaInterface::luaObjectEqualEvent);
klass_mt->setField("__gc", &LuaInterface::luaObjectCollectEvent);
klass_mt->setField("methods", klass);
klass_mt->setField("fieldmethods", klass_fieldmethods);
// redirect methods and fieldmethods to the base class ones
if(!className.empty() && className != "LuaObject") {
/* the following code what create classes hierarchy for lua, by reproducing the following:
* DerivedClass = { __index = BaseClass }
* DerivedClass_fieldmethods = { __index = BaseClass_methods }
*/
// redirect the class methods to the base methods
auto redirect = createTable();
auto tmp = getGlobal(baseClass);
redirect->setField("__index", tmp);
klass->setMetatable(redirect);
// redirect the class fieldmethods to the base fieldmethods
redirect = createTable();
tmp = getGlobal(baseClass + "_fieldmethods");
redirect->setField("__index", tmp);
klass_fieldmethods->setMetatable(redirect);
}
}
void LuaInterface::registerClassStaticFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function)
{
registerClassMemberFunction(className, functionName, function);
}
void LuaInterface::registerClassMemberFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function)
{
auto table = getGlobal(className);
table->setField(functionName, function);
}
void LuaInterface::registerClassMemberField(const std::string& className, const std::string& field, const LuaCppFunction& getFunction, const LuaCppFunction& setFunction)
{
auto fieldmethods = getGlobal(className + "_fieldmethods");
auto methods = getGlobal(className);
auto capitalized = field;
capitalized[0] = std::toupper(field[0]);
if(getFunction) {
auto func = createCppFunction(getFunction);
fieldmethods->setField(make_string("get_", field), func);
methods->setField(make_string("get", capitalized), func);
}
if(setFunction) {
auto func = createCppFunction(setFunction);
fieldmethods->setField(make_string("set_", field), func);
methods->setField(make_string("set", capitalized), func);
}
}
void LuaInterface::registerGlobalFunction(const std::string& functionName, const LuaCppFunction& function)
{
setGlobal(functionName, createCppFunction(function));
}
int LuaInterface::luaScriptLoader(LuaState* lua)
{
// load the script as a function
auto fileName = make_string(lua->popValue()->toString(), + ".lua");
auto scriptMain = lua->loadScript(fileName);
lua->pushValue(scriptMain);
return 1;
}
int LuaInterface::luaObjectGetEvent(LuaState* lua)
{
// metamethod that will retrive fields values (that include functions) from the object
auto key = lua->popValue()->toString();
auto objRef = lua->popValue();
auto obj = safe_luavalue_cast<LuaObjectPtr>(objRef);
// if a get method for this key exists, calls it
auto get_method = objRef->getMetatable()->getField("fieldmethods")->getField("get_" + key);
if(!get_method->isNil()) {
LuaValueList rets = get_method->call(make_string(obj->getLuaTypeName(), " obj.", key), objRef);
assert(rets.size() == 1);
lua->pushValues(rets);
return 1;
}
// if the field for this key exists, returns it
auto field = obj->getField(key);
if(!field->isNil()) {
lua->pushValue(field);
return 1;
}
// if a method for this key exists, returns it
auto method = objRef->getMetatable()->getField("methods")->getField(key);
lua->pushValue(method);
return 1;
}
int LuaInterface::luaObjectSetEvent(LuaState* lua)
{
// this metamethod is called when setting a field of the object by using the keyword '='
auto value = lua->popValue();
auto key = lua->popValue()->toString();
auto objRef = lua->popValue();
auto obj = safe_luavalue_cast<LuaObjectPtr>(objRef);
// check if a set method for this field exists and call it
auto set_method = objRef->getMetatable()->getField("fieldmethods")->getField("set_" + key);
if(!set_method->isNil()) {
set_method->call(make_string(obj->getLuaTypeName(), " obj.", key, "="), objRef, value);
return 0;
}
// no set method exists, then sets the object table
obj->setField(key, value);
return 0;
}
int LuaInterface::luaObjectEqualEvent(LuaState* lua)
{
// metamethod that will check equality of objects
auto objRef2 = lua->popValue();
auto objRef1 = lua->popValue();
bool ret = false;
// check if obj1 == obj2
if(objRef1->isUserdata() && objRef2->isUserdata()) {
LuaObjectPtr* objPtr1 = static_cast<LuaObjectPtr*>(objRef1->toUserdata());
LuaObjectPtr* objPtr2 = static_cast<LuaObjectPtr*>(objRef2->toUserdata());
assert(objPtr1 && objPtr2);
if(*objPtr1 == *objPtr2)
ret = true;
}
lua->pushBoolean(ret);
return 1;
}
int LuaInterface::luaObjectCollectEvent(LuaState* lua)
{
/* this metamethod is called every two lua garbage collections
* for any LuaObject that have no references left in lua environment
* anymore, thus this creates the possibility of holding an object
* existence by lua
*/
// get object pointer
auto objRef = lua->popValue();
auto objPtr = static_cast<LuaObjectPtr*>(objRef->toUserdata());
assert(objPtr);
// reset pointer to decrease object use count
objPtr->reset();
return 0;
}

@ -0,0 +1,73 @@
#ifndef LUAINTERFACE_H
#define LUAINTERFACE_H
#include "luabinder.h"
#include "luaobject.h"
class LuaInterface : public LuaState
{
public:
void init();
void terminate();
/// Load a function from buffef into a LuaValue
LuaValuePtr loadFunction(const std::string& buffer, const std::string& source = "lua function buffer");
/// Evaluate a lua expression to a LuaValue
LuaValuePtr evaluateExpression(const std::string& expression, const std::string& source = "lua expression");
LuaValuePtr createEnvironment();
/// Register core script functions
void registerFunctions();
// methods for registring classes and functions
void registerClass(const std::string& className, const std::string& baseClass = "LuaObject");
void registerClassStaticFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function);
void registerClassMemberFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function);
void registerClassMemberField(const std::string& className, const std::string& field, const LuaCppFunction& getFunction, const LuaCppFunction& setFunction);
void registerGlobalFunction(const std::string& functionName, const LuaCppFunction& function);
// methods for binding functions
template<typename F>
void bindClassStaticFunction(const std::string& className, const std::string& functionName, const F& function) {
registerClassStaticFunction(className, functionName, luabinder::bind_fun(function));
}
template<class C, typename F>
void bindClassMemberFunction(const std::string& className, const std::string& functionName, F C::*function) {
registerClassMemberFunction(className, functionName, luabinder::bind_mem_fun(function));
}
template<class C, typename F1, typename F2>
void bindClassMemberField(const std::string& className, const std::string& fieldName, F1 C::*getFunction, F2 C::*setFunction) {
registerClassMemberField(className, fieldName, luabinder::bind_mem_fun(getFunction), luabinder::bind_mem_fun(setFunction));
}
template<class C, typename F>
void bindClassMemberGetField(const std::string& className, const std::string& fieldName, F C::*getFunction) {
registerClassMemberField(className, fieldName, luabinder::bind_mem_fun(getFunction), LuaCppFunction());
}
template<class C, typename F>
void bindClassMemberSetField(const std::string& className, const std::string& fieldName, F C::*setFunction) {
registerClassMemberField(className, fieldName, LuaCppFunction(), luabinder::bind_mem_fun(setFunction));
}
template<typename F>
void bindGlobalFunction(const std::string& functionName, const F& function) {
registerGlobalFunction(functionName, luabinder::bind_fun(function));
}
private:
// installed lua callbacks by this interface
static int luaScriptLoader(LuaState* lua);
static int luaObjectGetEvent(LuaState* lua);
static int luaObjectSetEvent(LuaState* lua);
static int luaObjectEqualEvent(LuaState* lua);
static int luaObjectCollectEvent(LuaState* lua);
};
extern LuaInterface g_lua;
#endif // LUAINTERFACE_H

@ -0,0 +1,24 @@
#include "luaobject.h"
#include "luainterface.h"
LuaObject::LuaObject()
{
// creates own table
m_luaTable = g_lua.createTable();
}
LuaObject::~LuaObject()
{
}
LuaValuePtr LuaObject::toLuaValue()
{
// fills a new userdata with a new LuaObject pointer
new(g_lua.newUserdata(sizeof(LuaObjectPtr))) LuaObjectPtr(shared_from_this());
// set the metatable for the userdata
g_lua.setMetatable(make_string(getLuaTypeName(), "_mt"));
return g_lua.popValue();
}

@ -0,0 +1,50 @@
#ifndef LUAOBJECT_H
#define LUAOBJECT_H
#include "luavalue.h"
/// LuaObject, all bound classes must be derived from it
class LuaObject : public std::enable_shared_from_this<LuaObject>
{
public:
LuaObject();
virtual ~LuaObject();
/// Call a field of this lua object
template<typename... T>
LuaValueList callField(const std::string& field, const T&... args) {
// note that we must retrive the field from or lua value (to use the __index metamethod)
// so we cannot use our getField here
auto fieldFunc = toLuaValue()->getField(field);
auto funcName = make_string(getLuaTypeName(), ":", field);
return fieldFunc->call(funcName, shared_from_this(), args...);
}
/// Set a field of this lua object
template<typename T>
void setField(const std::string& key, const T& value) {
m_luaTable->setField(key, value);
}
/// Get a field of this lua object
LuaValuePtr getField(const std::string& key) {
return m_luaTable->getField(key);
}
/// Returns current use count by the shared_ptr
int getUseCount() { return shared_from_this().use_count() - 1; }
/// Class name used in lua, must be overridden by derived classes
virtual const char* getLuaTypeName() const = 0;
/** Convert to a lua value for pushing this object into lua stack.
* Each call to this will create a new pointer, thus increasing the use count.*/
LuaValuePtr toLuaValue();
LuaObjectPtr asLuaObject() { return shared_from_this(); }
private:
LuaValuePtr m_luaTable;
};
#endif // LUAOBJECT_H

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save