From 80789508b9655d25629223b9dcc84b4cfb77ce45 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 29 Jun 2020 15:29:03 -0400 Subject: Updates for mdoc Also more tests --- Makefile.win | 14 +- reference/networking.md | 40 ++++ spec/common.lua | 63 ++++++ spec/headless/deviceinit.lua | 15 ++ spec/headless/init.lua | 13 ++ spec/server/init.lua | 20 ++ spec/test1_spec.lua | 62 ++---- spec/test2_spec.lua | 297 +++++++++------------------ spec/test3_spec.lua | 100 +-------- spec/test4_spec.lua | 170 +++++++++++++++ spec/test5_spec.lua | 108 ++++++++++ src/client/callbackhandeler.cpp | 73 ++++++- src/client/lua_api/gui/iguibutton.cpp | 15 +- src/client/lua_api/gui/iguicheckbox.cpp | 17 +- src/client/lua_api/gui/iguicolorselector.cpp | 16 +- src/client/lua_api/gui/iguicombobox.cpp | 37 +++- src/client/lua_api/gui/iguieditbox.cpp | 18 +- src/client/lua_api/gui/iguielement.cpp | 20 +- src/client/lua_api/gui/iguifiledialog.cpp | 13 +- src/client/lua_api/gui/iguiimage.cpp | 19 +- src/client/lua_api/gui/iguilabel.cpp | 7 +- src/client/lua_api/gui/iguispinbox.cpp | 11 +- src/client/lua_api/gui/iguitreeview.cpp | 14 +- src/client/lua_api/gui/iguiwindow.cpp | 12 +- src/client/lua_api/io/ifilesystem.cpp | 34 ++- src/client/lua_api/load_gui.cpp | 11 +- src/client/lua_api/load_scene.cpp | 5 + src/client/lua_api/scene/icamera.cpp | 61 ++++++ src/client/lua_api/scene/igeneric.cpp | 72 ++++++- src/client/lua_api/scene/ilight.cpp | 36 +++- src/client/lua_api/scene/imesh.cpp | 3 - src/client/lua_api/video/iimage.cpp | 29 ++- src/client/lua_api/video/smaterial.cpp | 53 ++++- src/client/main.cpp | 4 +- src/server/lua_api/load_io.cpp | 85 ++++---- src/shared/lua_api/load_common.cpp | 51 +++++ src/shared/lua_api/load_net.cpp | 28 +-- src/shared/lua_api/phys/bcollider.cpp | 7 + src/shared/lua_api/phys/bghostobject.cpp | 15 +- src/shared/lua_api/phys/bphysbox.cpp | 2 +- src/shared/lua_api/phys/bphysgeneric.cpp | 15 +- src/shared/lua_api/phys/bphysmodel.cpp | 19 +- 42 files changed, 1171 insertions(+), 533 deletions(-) create mode 100644 reference/networking.md create mode 100644 spec/common.lua create mode 100644 spec/headless/deviceinit.lua create mode 100644 spec/headless/init.lua create mode 100644 spec/server/init.lua create mode 100644 spec/test4_spec.lua create mode 100644 spec/test5_spec.lua diff --git a/Makefile.win b/Makefile.win index 059b3f1..bedd50e 100644 --- a/Makefile.win +++ b/Makefile.win @@ -6,6 +6,7 @@ CXX?=g++ MKDIR?=mkdir RM?=rm -f ECHO?=echo +LD=g++ shared_objs=$(SHARED_SRC:src/shared/%=build/shared/%.o) client_objs=$(CLIENT_SRC:src/client/%=build/client/%.o) @@ -19,7 +20,8 @@ CLIENT_LIB_DIRS=\ -Llib/bullet/lib\ -Llib/irrlicht/lib/Win32-gcc\ -Llib/luajit/src\ - -Llib/nng/static + -Llib/nng/static\ + CLIENT_LIBS=\ -lBulletDynamics\ @@ -33,8 +35,8 @@ CLIENT_LIBS=\ -lmswsock\ -ladvapi32\ -lwinmm\ - -lm\ - #-lstdc++ + -lm + #-lstdc++-6 CFLAGS+=-DNNG_STATIC_LIB ifeq ($(DEBUG), true) @@ -51,13 +53,15 @@ clean: $(RM) $(shared_objs) $(RM) $(bins) +nuke: clean + bin/client/bin/brokengine_client.exe : $(client_objs) $(shared_objs) $(Q)echo "Linking $@" - $(Q)$(CXX) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose + $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose bin/server/bin/brokengine_server.exe : $(server_objs) $(shared_objs) $(Q)echo "Linking $@" - $(Q)$(CXX) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose + $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(CLIENT_LIB_DIRS) $(CLIENT_LIBS) # -Wl,--verbose $(shared_objs) : build/shared/%.o : src/shared/%.cpp src/shared/%.hpp $(Q)echo "CXX $@" diff --git a/reference/networking.md b/reference/networking.md new file mode 100644 index 0000000..087dd95 --- /dev/null +++ b/reference/networking.md @@ -0,0 +1,40 @@ +# Networking example + +A simple example of networking, ripped straight from the brok[en]gine test suite. + + +### Client + + local has_ponged = false + local socket = net.newsocket(net.PAIR) + socket:bind("tcp://127.0.0.1:5555") + function socket:receive(stream) + print("socket receive triggered") + has_ponged = true + local message = stream:readstring() + assert(message == "ping") + socket:send(function(stream2) + stream2:writestring("pong") + end) + end + local i = os.time() + function GAME.tick() + if has_ponged then + GAME.exit() + end + if i - os.time() > 5 then + error("Failed") + end + end + +### Server + + local socket = net.newsocket(net.PAIR) + socket:connect("tcp://127.0.0.1:5555") + function socket:receive(stream) + local message = stream:readstring() + assert(message == "pong") + end + socket:send(function(stream) + stream:writestring("ping") + end) diff --git a/spec/common.lua b/spec/common.lua new file mode 100644 index 0000000..4df1a7c --- /dev/null +++ b/spec/common.lua @@ -0,0 +1,63 @@ +local common = {} +local game_bin = nil + +if package.config:sub(1,1) == "/" then -- linux or osx + game_bin = "bin/client/bin/brokengine_client" + server_bin = "bin/server/bin/brokengine_server" +else -- windows + game_bin = "bin\\client\\bin\\brokengine_client.exe" + server_bin = "bin\\server\\bin\\brokengine_server.exe" +end + +function common.rungame() + f = io.popen(game_bin .. " spec/headless","r") + d = f:read("*all") + f:close() + --print(d) + return d +end + +function common.runboth() + --print("Running both") + --Do we have a race condition here? (Can client start and send it's message + --before the server is ready to accept? + f1 = io.popen(server_bin .. " spec/server","r") + f2 = io.popen(game_bin .. " spec/headless","r") + --print("Both ran...") + d1 = f1:read("*all") + d2 = f2:read("*all") + --print("Both read all") + f1:close() + f2:close() + --print("returning") + return d1, d2 +end + +function common.writegame(...) + f = io.open("spec/headless/init.lua","w") + data = {"GAME.crashy()"} + for _,v in pairs({...}) do + data[#data + 1] = v + end + data[#data + 1] = "\nGAME.exit()\n" + f:write(table.concat(data,"\n")) + f:close() +end + +function common.writeserver(...) + f = io.open("spec/server/init.lua","w") + data = {...} + data[#data + 1] = "\nGAME.exit()\n" + f:write(table.concat(data,"\n")) + f:close() +end + +function common.assert_game_runs() + assert.is_not_nil(common.rungame():find("\nGoodbye\n$")) +end +function common.assert_both_run() + local a,b = common.runboth() + assert.is_not_nil(a:find("\nGoodbye\n$")) + assert.is_not_nil(b:find("\nGoodbye\n$")) +end +return common diff --git a/spec/headless/deviceinit.lua b/spec/headless/deviceinit.lua new file mode 100644 index 0000000..6725820 --- /dev/null +++ b/spec/headless/deviceinit.lua @@ -0,0 +1,15 @@ +return { + ["Anti Alias"] = 16, + ["Bits Per Pixel"] = 16, + ["Device Type"] = "BEST", + ["Display Adapter"] = 0, + ["Double Buffer"] = true, + ["Multithreaded"] = false, + ["Driver Type"] = "NULL", + ["Fullscreen"] = false, + ["Stencil Buffer"] = true, + ["Stereo Buffer"] = false, + ["VSync"] = true, + ["Window Width"] = 640, + ["Window Height"] = 480, +} diff --git a/spec/headless/init.lua b/spec/headless/init.lua new file mode 100644 index 0000000..a5cf357 --- /dev/null +++ b/spec/headless/init.lua @@ -0,0 +1,13 @@ +GAME.crashy() + local socket = net.newsocket(net.PAIR) + socket:connect("tcp://127.0.0.1:5555") + function socket:receive(stream) + local message = stream:readstring() + assert(message == "pong") + end + socket:send(function(stream) + stream:writestring("ping") + end) + + +GAME.exit() diff --git a/spec/server/init.lua b/spec/server/init.lua new file mode 100644 index 0000000..f895ba3 --- /dev/null +++ b/spec/server/init.lua @@ -0,0 +1,20 @@ + local has_ponged = false + local socket = net.newsocket(net.PAIR) + socket:bind("tcp://127.0.0.1:5555") + function socket:receive(stream) + print("Socket receive triggered") + has_ponged = true + local message = stream:readstring() + assert(message == "ping") + socket:send(function(stream2) + stream2:writestring("pong") + end) + end + function GAME.tick() + if has_ponged then + GAME.exit() + end + end + + +GAME.exit() diff --git a/spec/test1_spec.lua b/spec/test1_spec.lua index 147abbd..01d6b0d 100644 --- a/spec/test1_spec.lua +++ b/spec/test1_spec.lua @@ -1,5 +1,10 @@ -print("Hello, world!") +if not package.path:find("spec/%?%.lua;") then + print("including spec") + package.path = "./spec/?.lua;" .. package.path +end +_G.assert = assert +local common = require("common") --[[Create the headless client init file]] local f = io.open("spec/headless/deviceinit.lua","w") f:write([=[ @@ -21,44 +26,14 @@ return { ]=]) f:close() -local game_bin = nil -if package.config:sub(1,1) == "/" then -- linux or osx - game_bin = "bin/client/bin/brokengine_client" -else - game_bin = "bin\\client\\bin\\brokengine_client.exe" -end - -function rungame() - f = io.popen(game_bin .. " spec/headless","r") - d = f:read("*all") - f:close() - return d -end - -function writegame(...) - f = assert(io.open("spec/headless/init.lua","w")) - data = {"GAME.crashy()"} - for _,v in pairs({...}) do - data[#data + 1] = v - end - data[#data + 1] = "\nGAME.exit()\n" - f:write(table.concat(data)) - f:close() -end - -function assert_game_runs() - assert.truthy(rungame():find("\nGoodbye\n$")) -end - describe("Brok[en]gine",function() - it("should run",function() - writegame() - d = rungame() - assert_game_runs() + it("should run #smoke",function() + common.writegame() + common.assert_game_runs() end) - it("should provide a lua environment",function() - writegame("print(\"Hello from lua!\")") - d = rungame() + it("should provide a lua environment #smoke",function() + common.writegame("print(\"Hello from lua!\")") + d = common.rungame() assert.truthy(d:find("\nHello from lua!\n")) end) @@ -75,15 +50,16 @@ describe("Brok[en]gine",function() windows = "newwindow", }) do it("should provide functions to make gui " .. k,function() - writegame("assert(gui." .. v .. ")") - assert_game_runs() + common.writegame("assert(gui." .. v .. ")") + common.assert_game_runs() end) end it("should provide functions to get the width and height of the screen",function() - writegame("assert(scrw)") - assert_game_runs() - writegame("assert(scrh)") - assert_game_runs() + common.writegame("assert(scrw)") + common.assert_game_runs() + common.writegame("assert(scrh)") + common.assert_game_runs() end) + end) diff --git a/spec/test2_spec.lua b/spec/test2_spec.lua index 6b90878..82ca33e 100644 --- a/spec/test2_spec.lua +++ b/spec/test2_spec.lua @@ -1,195 +1,102 @@ - -do return end -local test = require("u-test") - -function rungame() - f = io.popen("bin\\client\\bin\\brokengine_client.exe spec/headless","r") - d = f:read("*all") - f:close() - return d -end - -function runboth() - f1 = io.popen("bin\\server\\bin\\brokengine_server.exe spec/server","r") - f2 = io.popen("bin\\client\\bin\\brokengine_client.exe spec/headless","r") - d1 = f1:read("*all") - d2 = f2:read("*all") - f1:close() - f2:close() - return d1, d2 -end - -function writegame(...) - f = io.open("spec/headless/init.lua","w") - data = {"GAME.crashy()"} - for _,v in pairs({...}) do - data[#data + 1] = v - end - data[#data + 1] = "\nGAME.exit()\n" - f:write(table.concat(data,"\n")) - f:close() -end - -function writeserver(...) - f = io.open("spec/server/init.lua","w") - data = {...} - --data[#data + 1] = "\nGAME.exit()\n" - f:write(table.concat(data,"\n")) - f:close() -end - -function assert_game_runs() - test.is_not_nil(rungame():find("\nGoodbye\n$")) -end -function assert_both_run() - local a,b = runboth() - test.is_not_nil(a:find("\nGoodbye\n$")) - test.is_not_nil(b:find("\nGoodbye\n$")) -end - -test.game_runs = function() - writegame("") - assert_game_runs() -end - -test.gui.elements_exist = function() - for k,v in pairs({ - buttons = "newbutton", - checkboxes = "newcheckbox", - colorselectors = "newcolorselector", - editboxes = "neweditbox", - openfiledialogs = "newfileopendialog", - images = "newiguiimage", - labels = "newlabel", - spinboxes = "newspinbox", - treeviews = "newtreeview", - windows = "newwindow", - }) do - writegame("assert(gui." .. v .. ")") - assert_game_runs() - end -end - -test.gui.screen_functions = function() - writegame("assert(scrw)") - assert_game_runs() - writegame("assert(scrh)") - assert_game_runs() -end - ---#define PAIR 1 ---#define BUS 2 ---#define PUB 3 ---#define SUB 4 ---#define PULL 5 ---#define PUSH 6 ---#define REQ 7 ---#define REP 8 ---#define RESPOND 9 ---#define SURVEY 10 -local protocols = { - "PAIR", "BUS", "PUB", "SUB", "PULL", "PUSH", "REQ", "REP", "RESPOND", "SURVEY" -} -test.net.protocols_exist = function() - for k,v in pairs(protocols) do - writegame(string.format("assert(net.%s)",v)) - assert_game_runs() - end -end - -for _,sockettype in pairs(protocols) do - for _,func in pairs({ - "bind","connect","send" - }) do - test.net[sockettype .. "_socket_has_" .. func .. "_function"] = function() - writegame(string.format([[ - local socket = net.newsocket(net.%s) - assert(socket.%s) - assert(type(socket.%s) == "function") - ]],sockettype,func,func)) - assert_game_runs() - end - end -end ---test.net.functions_exist = function() - --writegame("assert(net.newsocket and type(net.newsocket == 'function'))") - --assert_game_runs() - --for _,sockettype in pairs(protocols) do - --for _,func in pairs({ - --}) do - --writegame(string.format([[ - --local socket = net.newsocket(net.%s) - --assert(socket.%s) - --assert(type(socket.%s) == "function") - --]],sockettype,func,func)) - --assert_game_runs() - --end - --end ---end - -test.net.protocol_pair = function() - writeserver([[ - local has_ponged = false - local socket = net.newsocket(net.PAIR) - socket:bind("tcp://127.0.0.1:5555") - function socket:receive(stream) - print("Socket receive triggered") - has_ponged = true - local message = stream:readstring() - assert(message == "ping") - socket:send(function(stream2) - stream2:writestring("pong") - end) - end - function GAME.tick() - if has_ponged then - GAME.exit() - end - end - ]]) - writegame([[ - local socket = net.newsocket(net.PAIR) - socket:connect("tcp://127.0.0.1:5555") - function socket:receive(stream) - local message = stream:readstring() - assert(message == "pong") - end - socket:send(function(stream) - stream:writestring("ping") - end) - ]]) - assert_both_run() -end - ---test.net.protocol_pubsub = function() - --writeserver([[ - --local counter = 0 - --local max_count = 10000 --How long to live for, - ----since we can't detect when the user - ----sends the message - --local socket = net.newsocket(net.PUB) - --socket:bind("tcp://127.0.0.1:5555") - --function GAME.tick() - --if counter < max_count then - --counter = counter + 1 - --socket:send(function(stream) - --stream:writestring("ping") - --end) - --else - --GAME.exit() - --end - --end - --]]) - --writegame([[ - --local socket = net.newsocket(net.SUB) - --socket:connect("tcp://127.0.0.1:5555") - --local oldgameexit = GAME.exit - --socket:receive(function(stream) - --assert(stream:readstring() == "ping") - --oldgameexit() - --end) - --function GAME.exit() return end --Stop the client from exiting - --]]) ---end - -test.summary() + +--do return end +--local test = require("u-test") +if not package.path:find("spec/%?%.lua;") then + print("including spec") + package.path = "./spec/?.lua;" .. package.path +end +local common = require("common") +_G.assert = assert + +describe("gui library", function() + for k,v in pairs({ + buttons = "newbutton", + checkboxes = "newcheckbox", + colorselectors = "newcolorselector", + editboxes = "neweditbox", + openfiledialogs = "newfileopendialog", + images = "newiguiimage", + labels = "newlabel", + spinboxes = "newspinbox", + treeviews = "newtreeview", + windows = "newwindow", + }) do + it("should have a function to create " .. k,function() + common.writegame("assert(gui." .. v .. ")") + common.assert_game_runs() + end) + end + it("should have a function to check the screen's width",function() + common.writegame("assert(scrw)") + common.assert_game_runs() + end) + it("should have a function to check the screen's height", function() + common.writegame("assert(scrh)") + common.assert_game_runs() + end) +end) + + +local protocols = { + "PAIR", "BUS", "PUB", "SUB", "PULL", "PUSH", "REQ", "REP", "RESPOND", "SURVEY" +} +describe("network library",function() + for _,v in pairs(protocols) do + it("should have a constant for the " .. v .. " protocol",function() + common.writegame(string.format("assert(net.%s)",v)) + common.assert_game_runs() + end) + end + it("should have a function to create a new socket",function() + common.writegame("assert(net.newsocket)") + common.assert_game_runs() + end) + for _,v in pairs(protocols) do + for _,j in pairs{"bind","connect","send"} do + it(string.format("should be able to create a %s socket with a %s method",v,j)) + common.writegame(string.format([[ + local socket = net.newsocket(net.%s) + assert(socket.%s) + assert(type(socket.%s) == "function") + ]],v,j,j)) + common.assert_game_runs() + end + end + it("should be able to set up a PAIR connection and send data through #smoke",function() + common.writeserver([[ + local has_ponged = false + local socket = net.newsocket(net.PAIR) + socket:bind("tcp://127.0.0.1:5555") + function socket:receive(stream) + print("socket receive triggered") + has_ponged = true + local message = stream:readstring() + assert(message == "ping") + socket:send(function(stream2) + stream2:writestring("pong") + end) + end + local i = os.time() + function GAME.tick() + if has_ponged then + GAME.exit() + end + if i - os.time() > 5 then + error("Failed") + end + end + ]]) + common.writegame([[ + local socket = net.newsocket(net.PAIR) + socket:connect("tcp://127.0.0.1:5555") + function socket:receive(stream) + local message = stream:readstring() + assert(message == "pong") + end + socket:send(function(stream) + stream:writestring("ping") + end) + ]]) + common.assert_both_run() + end) +end) diff --git a/spec/test3_spec.lua b/spec/test3_spec.lua index 8861b0c..e0c4c93 100644 --- a/spec/test3_spec.lua +++ b/spec/test3_spec.lua @@ -1,97 +1,13 @@ -local game_bin = nil -if package.config:sub(1,1) == "/" then -- linux or osx - game_bin = "bin/client/bin/brokengine_client" - server_bin = "bin/server/bin/brokengine_server" -else - game_bin = "bin\\client\\bin\\brokengine_client.exe" - server_bin = "bin\\server\\bin\\brokengine_server.exe" +if not package.path:find("spec/%?%.lua;") then + print("including spec") + package.path = "./spec/?.lua;" .. package.path end +local common = require("common") +_G.assert = assert -function rungame() - f = io.popen(game_bin .. " spec/headless","r") - d = f:read("*all") - f:close() - return d -end - -function runboth() - --print("Running both") - --Do we have a race condition here? (Can client start and send it's message - --before the server is ready to accept? - f1 = io.popen(server_bin .. " spec/server","r") - f2 = io.popen(game_bin .. " spec/headless","r") - --print("Both ran...") - d1 = f1:read("*all") - d2 = f2:read("*all") - --print("Both read all") - f1:close() - f2:close() - --print("returning") - return d1, d2 -end - -function writegame(...) - f = io.open("spec/headless/init.lua","w") - data = {"GAME.crashy()"} - for _,v in pairs({...}) do - data[#data + 1] = v - end - data[#data + 1] = "\nGAME.exit()\n" - f:write(table.concat(data,"\n")) - f:close() -end - -function writeserver(...) - f = io.open("spec/server/init.lua","w") - data = {...} - data[#data + 1] = "\nGAME.exit()\n" - f:write(table.concat(data,"\n")) - f:close() -end - -function assert_game_runs() - test.is_not_nil(rungame():find("\nGoodbye\n$")) -end -function assert_both_run() - local a,b = runboth() - assert.is_not_nil(a:find("\nGoodbye\n$")) - assert.is_not_nil(b:find("\nGoodbye\n$")) -end -describe("networking",function() - it("should communicate with PAIR sockets",function() - writeserver([[ - local has_ponged = false - local socket = net.newsocket(net.PAIR) - socket:bind("tcp://127.0.0.1:5555") - function socket:receive(stream) - print("Socket receive triggered") - has_ponged = true - local message = stream:readstring() - assert(message == "ping") - socket:send(function(stream2) - stream2:writestring("pong") - end) - end - function GAME.tick() - if has_ponged then - GAME.exit() - end - end - ]]) - --print("writing game...") - writegame([[ - local socket = net.newsocket(net.PAIR) - socket:connect("tcp://127.0.0.1:5555") - function socket:receive(stream) - local message = stream:readstring() - assert(message == "pong") - end - socket:send(function(stream) - stream:writestring("ping") - end) - ]]) - --print("asserting both run...") - assert_both_run() +describe("physics library",function() + it("should have methods to create a physics box",function() + end) end) diff --git a/spec/test4_spec.lua b/spec/test4_spec.lua new file mode 100644 index 0000000..93c4e70 --- /dev/null +++ b/spec/test4_spec.lua @@ -0,0 +1,170 @@ +local game_bin = nil +if package.config:sub(1,1) == "/" then -- linux or osx + game_bin = "bin/client/bin/brokengine_client" +else + game_bin = "bin\\client\\bin\\brokengine_client.exe" +end + +function rungame() + f = io.popen(game_bin .. " spec/headless","r") + d = f:read("*all") + f:close() + return d +end + +function writegame(...) + f = assert(io.open("spec/headless/init.lua","w")) + data = {"GAME.crashy()"} + for _,v in pairs({...}) do + data[#data + 1] = v + end + data[#data + 1] = "\nGAME.exit()\n" + f:write(table.concat(data)) + f:close() +end + +function assert_game_runs() + local results = rungame() + assert.truthy(results:find("\nGoodbye\n$"), results) +end + +gui_api = { + button = { + func = "gui.newbutton", + params = { + { + name = "dimensions", + required = true, + type = "rect4d", + }, + { + name = "default_text", + required = true, + type = "string", + }, + { + name = "parent", + required = false, + type = "guielement", + }, + }, + callbacks = { + "onClick", "onFocus", "onUnfocus", "onHover", "onLeave" + } + }, + fileopendialog = { + func = "gui.newfileopendialog", + params = { + { + name = "title", + required = false, + type = "string", + }, + { + name = "path", + required = false, + type = "filepath", + }, + { + name = "parent", + required = false, + type = "guielement", + }, + { + name = "modal", + required = false, + type = "boolean", + } + }, + callbacks = { + "onDirectorySelect","onFileSelect","onCanceled" + } + }, + label = { + func = "gui.newlabel", + params = { + { + name = "pos", + required = true, + type = "rect4d", + }, + { + name = "text", + required = true, + type = "string", + }, + { + name = "parent", + required = false, + type = "guielement", + } + }, + callbacks = { + + } + }, +} + +--[[For some reason these can't be local, _ENV dosn't find them.]] +local function mr() + return string.format("%d",math.floor(math.random()*100)) +end +function generate_rect4d() + return string.format("{{%d,%d},{%d,%d}}",mr(),mr(),mr(),mr()) +end +function generate_string() + return "\"test!\"" +end +function generate_guielement() + return "gui.getroot()" +end +function generate_filepath() + return "\".\"" +end +function generate_boolean() + return "true" +end +describe("Brok[en]gine",function() + describe("gui system",function() + for k,v in pairs(gui_api) do + describe(k,function() + local paramstring = {} + local num_optional_args = 0 + local num_required_args = 0 + for i,j in pairs(v.params) do + assert(_ENV["generate_" .. j.type], "Could not find a generator for type: " .. j.type) + if j.required then + num_required_args = num_required_args + 1 + else + num_optional_args = num_optional_args + 1 + end + paramstring[#paramstring + 1] = _ENV["generate_" .. j.type]() + end + for i = num_required_args, num_required_args + num_optional_args do + it(string.format(" with %d params", i),function() + local truncated_params = {} + for j = 1, i do + truncated_params[j] = paramstring[j] + end + local game_file = string.format("%s(%s)",v.func,table.concat(truncated_params, ",")) + --print("running:",game_file) + writegame(game_file) + assert_game_runs() + end) + it(string.format(" 100 elemants with %d params", i),function() + local game_file = {} + for j = 1,100 do + local truncated_params = {} + for k = 1, i do + truncated_params[k] = paramstring[k] + end + game_file[#game_file + 1] = string.format("%s(%s)",v.func,table.concat(truncated_params, ",")) + end + writegame(table.concat(game_file,"\n")) + assert_game_runs() + end) + end + end) + end + end) +end) diff --git a/spec/test5_spec.lua b/spec/test5_spec.lua new file mode 100644 index 0000000..b4b9333 --- /dev/null +++ b/spec/test5_spec.lua @@ -0,0 +1,108 @@ +--[[ +physics things +]] +package.path = "./spec/?.lua;" .. package.path +_G.assert = assert +local common = require("common") + +local spawn_1_box = [[ +GAME.crashy() +local box = phys.newphysbox({8,8,8}, {0,0,0}, 0) +GAME.exit() +]] + +local spawn_several_boxes = [[ +GAME.crashy() +for i = 1,100 do + phys.newphysbox({8,8,8}, {0,10 * i,0}, 0) +end +GAME.exit() +]] + +describe("physics",function() + it("should be able to spawn a physics box on the client",function() + common.writegame(spawn_1_box) + common.assert_game_runs() + end) + it("should be able to spawn several physics boxes on the client", function() + common.writegame(spawn_several_boxes) + common.assert_game_runs() + end) + +end) + +local getpos_exists = [[ +GAME.crashy() +local box = phys.newphysbox({8,8,8}, {0,0,0}, 0) +local pos = box:getpos() +for i = 1,3 do + assert(pos[i] == 0, "Position is not 0") +end +GAME.exit() +]] +local getpos_works = [[ +GAME.crashy() +local box = phys.newphysbox({8,8,8}, {10,20,30}, 0) +local pos = box:getpos() +assert(pos[1] == 10) +assert(pos[2] == 20) +assert(pos[3] == 30) +GAME.exit() +]] +local setpos_exists = [[ +GAME.crashy() +local box = phys.newphysbox({8,8,8}, {10,20,30}, 0) +box:setpos({0,0,0}) +local pos = box:getpos() +for i = 1,3 do + assert(pos[i] == 0) +end +GAME.exit() +]] +local setpos_works = [[ +GAME.crashy() +local box = phys.newphysbox({8,8,8}, {0,0,0}, 0) +box:setpos({10,20,30}) +local pos = box:getpos() +assert(pos[1] == 10) +assert(pos[2] == 20) +assert(pos[3] == 30) +GAME.exit() +]] +local falls = [[ +GAME.crashy() +local box = phys.newphysbox({8,8,8}, {0,10,0}, 1) +local ticks = 0 +GAME.tick = function() + print("Tick running...") + if box:getpos()[2] < 0 then + print("Getpos[2] is less, it is ", box:getpos()[2]) + GAME.exit() + end + ticks = ticks + 1 + assert(ticks < 1) +end +]] +describe("physics box", function() + it("should have a .getpos() function",function() + common.writegame(getpos_exists) + common.assert_game_runs() + end) + it("should have a .getpos() function that returns the box's position",function() + common.writegame(getpos_works) + common.assert_game_runs() + end) + it("should have a .setpos() function",function() + common.writegame(setpos_exists) + common.assert_game_runs() + end) + it("should have a .setpos() function that sets the box's position",function() + common.writegame(setpos_works) + common.assert_game_runs() + end) + it("should fall when given mass",function() + --print("About to write should fall when given mass...") + common.writegame(falls) + common.assert_game_runs() + end) +end) diff --git a/src/client/callbackhandeler.cpp b/src/client/callbackhandeler.cpp index d522e84..b6c0321 100644 --- a/src/client/callbackhandeler.cpp +++ b/src/client/callbackhandeler.cpp @@ -18,9 +18,6 @@ using namespace gui; using namespace std; extern lua_State* L; -/*** -@module GAME -*/ std::map guielements; //For basic events @@ -90,8 +87,23 @@ bool GlobalEventReceiver::OnEvent(const SEvent& e){ printf("done getting gui element\n"); const char* fieldname; switch(get){ +/*** +(Callback)Called when an @{iguiwindow} is focused +If the function returns true, the element will not be focused. +@function iguiwindow:onFocus() +*/ case EGET_ELEMENT_FOCUSED: fieldname = "onFocus"; break; +/*** +(Callback)Called when an @{iguiwindow} is unfocused +If the function returns true, the element will not be unfocused. +@function iguiwindow:onUnfocus() +*/ case EGET_ELEMENT_FOCUS_LOST: fieldname = "onUnfocus"; break; +/*** +(Callback)Called when an @{iguielement is hovered over with the mouse. +If an element has child elements, you also get this call for each child element. +@function iguielement:onHover() +*/ case EGET_ELEMENT_HOVERED: fieldname = "onHover"; break; case EGET_ELEMENT_LEFT: fieldname = "onLeave"; break; case EGET_ELEMENT_CLOSED: fieldname = "onClose"; break; @@ -160,6 +172,14 @@ Detects when the mouse moves across the game. */ switch(se.Event){ case EMIE_MOUSE_MOVED:{ +/*** +(Callback)Detects mouse movement +Called whenever the mouse is moved +@function GAME.onMouseMove(x,y,button) +@tparam number x The x position that the mouse now occupies +@tparam number y The y position that the mouse now occupies +@tparam number button Will be EMIE_MOUSE_MOVED. +*/ return callMouse(L,"onMouseMove",se.X,se.Y,se.Event); } break; @@ -167,29 +187,74 @@ Detects when the mouse moves across the game. case EMIE_RMOUSE_PRESSED_DOWN: case EMIE_MMOUSE_PRESSED_DOWN:{ printf("Mouse down\n"); +/*** +(Callback)Detects mouse presses. +Called whenever the a mouse button has been pressed +@function GAME.onMouseDown(x,y,button) +@tparam number x The x position of the mouse +@tparam number y The y position of the mouse +@tparam number button Which mouse button was pressed. Will be one of: +EMIE_LMOUSE_PRESSED_DOWN, EMIE_RMOUSE_PRESSED_DOWN, or EMIE_MMOUSE_PRESSED_DOWN +*/ return callMouse(L,"onMouseDown",se.X,se.Y,se.Event); } break; case EMIE_LMOUSE_LEFT_UP: case EMIE_RMOUSE_LEFT_UP: case EMIE_MMOUSE_LEFT_UP:{ - printf("Mouse up\n"); +/*** +(Callback)Detects mouse presses. +Detects when the mouse has been released. +@function GAME.onMouseUp(x,y,button) +@tparam number x The x position of the mouse on the screen (in pixels) +@tparam number y The y position of the mouse +@tparam number button The mouse key that was clicked, will be one of: +EMIE_LMOUSE_LEFT_UP, EMIE_RMOUSE_LEFT_UP, or EMIE_MMOUSE_LEFT_UP. +*/ return callMouse(L,"onMouseUp",se.X,se.Y,se.Event); } break; case EMIE_MOUSE_WHEEL:{ +/*** +(Callback)Detects mouse scroll wheel. +Triggered whenever the scroll wheel moves up or down. +@function GAME.onMouseWheel(x,y,direction) +@tparam number x The x position of the mouse +@tparam number y The y position of the mouse +@tparam number direction The direction of the scroll wheel, -1, 0 or 1 +*/ return callMouse(L,"onMouseWheel",se.X,se.Y,se.Wheel); } break; case EMIE_RMOUSE_DOUBLE_CLICK: case EMIE_MMOUSE_DOUBLE_CLICK: case EMIE_LMOUSE_DOUBLE_CLICK:{ +/*** +(Callback)Detects double clicking. +Tirggered whenever the user double clicked in the screen. The speed for double +clicking is system defined, and may not be the same across platforms. +@function GAME.onDoubleClick(x,y,button) +@tparam number x The x position of the mouse +@tparam number y The y position of the mouse +@tparam number button Which button was double clicked. Will be one of: +EMIE_RMOUSE_DOUBLE_CLICK, EMIE_LMOUSE_DOUBLE_CLICK, or EMIE_MMOUSE_DOUBLE_CLICK +*/ return callMouse(L,"onDoubleClick",se.X,se.Y,se.Event); } break; case EMIE_RMOUSE_TRIPLE_CLICK: case EMIE_MMOUSE_TRIPLE_CLICK: case EMIE_LMOUSE_TRIPLE_CLICK:{ +/*** +(Callback)Detects triple clicking. +Triggered whenever the user tripple clicks on the screen. The speed for tripple +clicking is system defined, and may not be the same across platforms. +@function GAME.onTripleClick(x,y,button) +@tparam number x The x position of the mouse +@tparam number y The y position of the mouse +@tparam number button Which button was tripple clicked. Will be one of: +EMIE_RMOUSE_TRIPLE_CLICK, EMIE_MMOUSE_TRIPLE_CLICK, EMIE_LMOUSE_TRIPLE_CLICK +*/ return callMouse(L,"onTripleClick",se.X,se.Y,se.Event); } break; diff --git a/src/client/lua_api/gui/iguibutton.cpp b/src/client/lua_api/gui/iguibutton.cpp index 3d4580b..cdbea77 100644 --- a/src/client/lua_api/gui/iguibutton.cpp +++ b/src/client/lua_api/gui/iguibutton.cpp @@ -17,9 +17,6 @@ extern "C" { #include #include -/*** -@module gui -*/ using namespace irr; using namespace core; using namespace gui; @@ -30,16 +27,16 @@ char lhashkey[20]; /*** Creates a new button. Buttons may have the following fields set for callbacks: + .onClick(self) - .onFocus(self) - .onUnfocus(self) - .onHover(self) - .onLeave(self) -@function newbutton() + +It may additionally call any @{iguielement} callbacks + +@function gui.newbutton() @tparam rect dimensions The rectangle to place the button at. If the box has a parent, it is offset from the upper-left of the parent element. @tparam string default_text The default text to have in the button -@tparam ?iguielement parent The parent element of the button. +@tparam? iguielement parent The parent element of the button. @treturn iguibutton The button element */ //gui.newbutton({{sx,sy},{ex,ey}},"text"[,parent]) diff --git a/src/client/lua_api/gui/iguicheckbox.cpp b/src/client/lua_api/gui/iguicheckbox.cpp index 6413883..365b75d 100644 --- a/src/client/lua_api/gui/iguicheckbox.cpp +++ b/src/client/lua_api/gui/iguicheckbox.cpp @@ -8,9 +8,6 @@ extern "C" { #include "iguielement.hpp" #include -/*** -@module gui -*/ using namespace irr; using namespace gui; using namespace core; @@ -26,11 +23,11 @@ following fields, which they will call for callbacks: It may additionally call any @{iguielement} callbacks -@function newcheckbox() +@function gui.newcheckbox() @tparam rect dimensions The rectangle to place the box at. If the box has a parent, it is offset from the upper-left of the parent element. @tparam string default_text The default text to have in the edit box -@tparam ?iguielement parent The parent element of the edit box +@tparam? iguielement parent The parent element of the edit box @treturn iguieditbox The edit box element */ //new({startx,starty},{endx,endy},"checkbox_name"[,ud_parent]) @@ -59,6 +56,11 @@ int newiguicheckbox(lua_State* L){ return 1; } +/*** +Is the checkbox checked. +@function iguicheckbox:ischecked() +@treturn boolean Is this checkbox checked? +*/ //ischecked(self) int ischecked(lua_State *L){ lua_getfield(L,-1,"guielement"); @@ -69,6 +71,11 @@ int ischecked(lua_State *L){ return 1; } +/*** +Set the state of the checkbox. +@function iguicheckbox:setchecked(set) +@tparam boolean set Should this checkbox be checked? (false to uncheck) +*/ //setchecked(self, checked) int setchecked(lua_State *L){ int should = lua_toboolean(L,-1); diff --git a/src/client/lua_api/gui/iguicolorselector.cpp b/src/client/lua_api/gui/iguicolorselector.cpp index 8a61c6d..5a11394 100644 --- a/src/client/lua_api/gui/iguicolorselector.cpp +++ b/src/client/lua_api/gui/iguicolorselector.cpp @@ -10,9 +10,6 @@ extern "C" { #include "iguielement.hpp" #include -/*** -@module gui -*/ using namespace irr; using namespace gui; using namespace core; @@ -20,10 +17,11 @@ using namespace core; extern IrrlichtDevice* device; /*** -@function newcolorselector() -Creates a new checkbox +Creates a new Color selector. +Creates a dialog box that allows the user to select a color. TODO:Broken? +@function gui.newcolorselector() @tparam string title The title for this color selector -@tparam ?iguielement parent The parent element of the edit box +@tparam? iguielement parent The parent element of the edit box @treturn iguicolorselector The color selector element */ //newcolorselector("title"[,parent]) @@ -61,6 +59,12 @@ static const luaL_reg iguicolorselector_m[] = { {0,0}, }; +/*** +A dialog that allows the user to select a color +@class iguicolorselector +@inherits guielement +*/ + int iguicolorselector_register(lua_State* L){// luaL_newmetatable(L,"gui.colorselector");//m{gui.checkbox} luaL_register(L,NULL,iguielement_m); diff --git a/src/client/lua_api/gui/iguicombobox.cpp b/src/client/lua_api/gui/iguicombobox.cpp index 43c66f1..a9c4137 100644 --- a/src/client/lua_api/gui/iguicombobox.cpp +++ b/src/client/lua_api/gui/iguicombobox.cpp @@ -11,9 +11,6 @@ extern "C" { #include #include -/*** -@module gui -*/ using namespace irr; using namespace core; using namespace gui; @@ -24,10 +21,10 @@ extern IrrlichtDevice* device; Creates a new combo box. Buttons may have the following fields set for callbacks: `.onChange(self)` -@function newcombobox() +@function gui.newcombobox() @tparam rect dimensions The rectangle to place the button at. If the box has a parent, it is offset from the upper-left of the parent element. -@tparam ?iguielement parent The parent element of the button. +@tparam? iguielement parent The parent element of the button. @treturn iguicombobox The combo box element */ //gui.newcombobox({{sx,sy},{ex,ey}}[,parent]) @@ -60,7 +57,15 @@ static int newiguicombobox(lua_State* L){ return 1; } -//{combobox}.addItem(self,text,id) +/*** +Add an item to the combo box +Adds an option to this combo box, with a given id for when it it selected +@function iguicombobox:additem(text,id) +@tparam string text The text to add to the combo box +@tparam number id The id to return from getselected() when this option is +selected +*/ +//{combobox}.add(self,text,id) int additem(lua_State *L){ int id = lua_tonumber(L,-1); lua_pop(L,1);//self,text @@ -78,6 +83,12 @@ int additem(lua_State *L){ return 0; } +/*** +Get the selected item. +Returns the number for the selected item, set with add() +@function iguicombobox:get() +@treturn number The item number that is currently selected +*/ // {combobox}.getselected(self) int getselected(lua_State *L){ lua_getfield(L,-1,"guielement");//self,ud_guielement @@ -88,7 +99,13 @@ int getselected(lua_State *L){ return 1; } -//{combobox}.removeitem(self,id) +/*** +Remove an item +Removes an item from the combo box at the given id. Id's are assigned with add() +@function iguicombobox:remove() +@tparam number id The id number of the item to remove +*/ +//{combobox}.remove(self,id) int removeitem(lua_State *L){ int idx = lua_tonumber(L,-1);//self,id lua_pop(L,1);//self @@ -105,9 +122,9 @@ static const luaL_reg iguicombobox_f[] = { }; static const luaL_reg iguicombobox_m[] = { - {"addItem", additem}, - {"getSelected", getselected}, - {"removeItem", removeitem}, + {"add", additem}, + {"get", getselected}, + {"remove", removeitem}, {0,0}, }; diff --git a/src/client/lua_api/gui/iguieditbox.cpp b/src/client/lua_api/gui/iguieditbox.cpp index 7de3f37..409c2fc 100644 --- a/src/client/lua_api/gui/iguieditbox.cpp +++ b/src/client/lua_api/gui/iguieditbox.cpp @@ -12,10 +12,6 @@ extern "C" { #include #include -/*** -@module gui -*/ - using namespace irr; using namespace core; using namespace gui; @@ -23,11 +19,11 @@ using namespace gui; extern IrrlichtDevice* device; /*** -@function neweditbox() -Creates a new text entry box +Creates a new text entry box. +@function gui.neweditbox() @tparam rect dimensions The rectangle to place the box at. If the box has a parent, it is offset from the upper-left of the parent element. -@tparam ?iguielement parent The parent element of the edit box -@tparam ?string default_text The default text to have in the edit box +@tparam? iguielement parent The parent element of the edit box +@tparam? string default_text The default text to have in the edit box @treturn iguieditbox The edit box element */ //gui.neweditbox({{sx,sy},{ex,ey}}[,parent][,"default text"]) @@ -73,6 +69,12 @@ static int newiguieditbox(lua_State* L){ return 1; } +/*** +Set the edit box to multiline mode. +Allow / disallow the edit box to accept newlines. +@function iguieditbox:setmultiline(enable) +@tparam boolean enable Should the edit box allow newlines? +*/ //self:setmultiline(bool_enabled) int set_multiline(lua_State *L){ int should = lua_toboolean(L,-1); diff --git a/src/client/lua_api/gui/iguielement.cpp b/src/client/lua_api/gui/iguielement.cpp index db7669a..17ec4a5 100644 --- a/src/client/lua_api/gui/iguielement.cpp +++ b/src/client/lua_api/gui/iguielement.cpp @@ -1,5 +1,5 @@ /*This file defines some things that all igui stuff can do*/ -/*** +/* All gui elements inherit from iguielement. Some functions (like settext()) do different things for different elements. All gui elements can call the following callbacks: @@ -9,7 +9,6 @@ All gui elements can call the following callbacks: onHover(self) onLeave(self) -@classmod iguielement */ extern "C" { #include @@ -28,9 +27,10 @@ using namespace core; using namespace gui; extern IrrlichtDevice *device; + /*** Move an element (by an offset) from it's current position -@function guielement:move() +@function iguielement:move() @tparam vector2d position The offset to move this element by */ //move({element},{x,y}) -> nil @@ -51,7 +51,7 @@ int moveiguielement(lua_State* L){ /*** Set the visibility of this element -@function guielement:setvisible() +@function iguielement:setvisible() @tparam boolean visible Should this element be visible? */ int setvisible(lua_State *L){ @@ -69,7 +69,7 @@ int setvisible(lua_State *L){ /*** Find the rectangle that an element occupies -@function guielement:getabsrect() +@function iguielement:getabsrect() @treturn rect The rectangle that this element occupies */ //getabsrect({element})-> {{sx,sy},{ex,ey}} @@ -91,7 +91,7 @@ int getiguiclippingrect(lua_State* L){ /*** Find the rectangle that an element occupies that is visible to the user -@function guielement:getabsclippingrect() +@function iguielement:getabsclippingrect() @treturn rect The rectangle that this element occupies that is visible to the user */ //getabsclippingrect({element}) :: {{sx,sy},{ex,ey}} @@ -112,7 +112,7 @@ int getiguiabsclippingrect(lua_State *L){ /*** Find the relative rectangle that this element occupies -@function guielement:getrelrect() +@function iguielement:getrelrect() @treturn rect The rectangle that this element occupies relative to it's parent */ int getiguirelrect(lua_State *L){ @@ -135,7 +135,7 @@ Sets the text of the element This function may do different things to different gui elements. For example, on a window, it sets the title. On a button, it sets the button's text. -@function guielement:settext() +@function iguielement:settext() @tparam string text The text to set on the element */ //setText({guielement},"text") :: nil @@ -168,7 +168,7 @@ int setrelrect(lua_State *L){ /*** -@function guielement:gettext() +@function iguielement:gettext() @treturn string The caption text of the element. For input element like editboxes, this returns the text that the edit box contains. */ @@ -189,7 +189,7 @@ int getiguitext(lua_State* L){ /*** Removes a gui element, and any child elements -@function guielement:remove() +@function iguielement:remove() */ //remove({self}) int removeiguielement(lua_State* L){ diff --git a/src/client/lua_api/gui/iguifiledialog.cpp b/src/client/lua_api/gui/iguifiledialog.cpp index d717673..9b789cb 100644 --- a/src/client/lua_api/gui/iguifiledialog.cpp +++ b/src/client/lua_api/gui/iguifiledialog.cpp @@ -17,9 +17,6 @@ extern "C" { #include #include -/*** -@module gui -*/ using namespace irr; using namespace core; using namespace gui; @@ -27,17 +24,17 @@ using namespace gui; extern IrrlichtDevice* device; /*** -@function newfileopendialog() Creates a new dialog to open a file. The file creation window may have the following fields set for callbacks: .onDirectorySelect(self) .onFileSelect(self) .onCanceled(self) -@tparam ?string title The rectangle to place the button at. If the box has a parent, +@function gui.newfileopendialog() +@tparam? string title The rectangle to place the button at. If the box has a parent, it is offset from the upper-left of the parent element. -@tparam ?string path The path to open the file dialog to -@tparam ?iguielement parent The parent element of the button. -@tparam ?boolean modal If other gui elements can be interacted with before this element is closed +@tparam? string path The path to open the file dialog to +@tparam? iguielement parent The parent element of the button. +@tparam? boolean modal If other gui elements can be interacted with before this element is closed @treturn iguifileopendialog The button element */ //gui.newfileopendialog(["title"][,"path"][,parent][,modal]) diff --git a/src/client/lua_api/gui/iguiimage.cpp b/src/client/lua_api/gui/iguiimage.cpp index 267cbd2..81f6568 100644 --- a/src/client/lua_api/gui/iguiimage.cpp +++ b/src/client/lua_api/gui/iguiimage.cpp @@ -17,9 +17,6 @@ extern "C" { #include "../../callbackhandeler.hpp" #include -/*** -@module gui -*/ using namespace irr; using namespace video; using namespace gui; @@ -28,14 +25,14 @@ extern IrrlichtDevice* device; extern IGUIEnvironment* env; /*** -@function newiguiimage() +@function gui.newiguiimage() Creates a new guielement with an image. The size of the iguielement is the same as the itexture used for it's creation. @tparam vector2d position The upper-left hand corner of the element. it is offset from the upper-left of the parent element. @tparam number alpha The transparency of the element. @tparam itexture texture The texture to display on this element. -@tparam ?iguielement parent The parent element of the button. +@tparam? iguielement parent The parent element of the button. @treturn iguifileopendialog The button element */ //newiguiimage({startx,starty},alpha,{itexture}[,parent]) -> {guielement} @@ -70,6 +67,12 @@ static int newiguiimage(lua_State* L){ return 1; } +/*** +Set the color of the image +Sets the color offset (additive color) for the image. +@function iguiimage:setcolor(color c) +@tparam color color The color to set the image as +*/ //setcolor(self,{r,g,b,a}) int setcolor(lua_State* L){ long r,g,b,a; @@ -81,6 +84,12 @@ int setcolor(lua_State* L){ return 0; } +/*** +Set the image of the element +Sets the image for the element. TODO: Memory leak of old images? +@function iguiimage:setimage(itexture texture) +@tparam itexture texture The texture to set this image element to +*/ //setimage(self,itexture) int setimage(lua_State *L){ lua_getfield(L,-1,"texture");//{iguiimg},{itex} diff --git a/src/client/lua_api/gui/iguilabel.cpp b/src/client/lua_api/gui/iguilabel.cpp index 529d680..bcb1778 100644 --- a/src/client/lua_api/gui/iguilabel.cpp +++ b/src/client/lua_api/gui/iguilabel.cpp @@ -17,21 +17,18 @@ extern "C" { #include "../../callbackhandeler.hpp" #include -/*** -@module gui -*/ using namespace irr; using namespace gui; extern IrrlichtDevice* device; /*** -@function newlabel() +@function gui.newlabel() Creates a new label to display text. @tparam rect pos The position of the label, reletive to the upper-left of it's parent element, or the root window if parent is nil. @tparam string text The text to display on this label. -@tparam ?iguielement parent The parent element of the button. +@tparam? iguielement parent The parent element of the button. @treturn iguilabel The label element */ //gui.newlabel({{sx,sy},{ex,ey}},"text"[,parent]) :: {guielement} diff --git a/src/client/lua_api/gui/iguispinbox.cpp b/src/client/lua_api/gui/iguispinbox.cpp index 7cb1775..25ecbde 100644 --- a/src/client/lua_api/gui/iguispinbox.cpp +++ b/src/client/lua_api/gui/iguispinbox.cpp @@ -12,9 +12,6 @@ extern "C" { #include #include -/*** -@module gui -*/ using namespace irr; using namespace core; using namespace gui; @@ -22,13 +19,13 @@ using namespace gui; extern IrrlichtDevice* device; /*** -@function newspinbox() +@function gui.newspinbox() Creates a new spinbox @tparam rect dimensions The rectangle to place the button at. If the box has a parent, it is offset from the upper-left of the parent element. -@tparam ?string default_text The default text to display in the spinbox. -@tparam ?iguielement parent The parent element of the button. -@tparam ?boolean border Display a border around the spinbox +@tparam? string default_text The default text to display in the spinbox. +@tparam? iguielement parent The parent element of the button. +@tparam? boolean border Display a border around the spinbox @treturn iguibutton The button element */ //gui.newspinbox({{sx,sy},{ex,ey}}[,"text"][,parent][,border]) diff --git a/src/client/lua_api/gui/iguitreeview.cpp b/src/client/lua_api/gui/iguitreeview.cpp index 68aa3cc..3778a50 100644 --- a/src/client/lua_api/gui/iguitreeview.cpp +++ b/src/client/lua_api/gui/iguitreeview.cpp @@ -11,25 +11,21 @@ extern "C" { #include "client/callbackhandeler.hpp" #include -/*** -@module gui -*/ using namespace irr; using namespace core; using namespace gui; - extern IrrlichtDevice* device; /*** -@function newtreeview() +@function gui.newtreeview() Creates a new tree view @tparam dimensions rect The rectangle to place the tree view at. If the box has a parent, it is offset from the upper-left of the parent element. -@tparam ?iguielement parent The parent element of the button. -@tparam ?boolean draw_background Should we draw a background for the tree view? -@tparam ?boolean vertical_scroll Should there be a vertical scroll bar? -@tparam ?boolean horizonal_scroll Should there be a horizontal scroll bar? +@tparam? iguielement parent The parent element of the button. +@tparam? boolean draw_background Should we draw a background for the tree view? +@tparam? boolean vertical_scroll Should there be a vertical scroll bar? +@tparam? boolean horizonal_scroll Should there be a horizontal scroll bar? @treturn iguitreeview The tree view element */ //gui.newtreeview({{sx,sy},{ex,ey}},[,parent][,draw_background][,vertical_scroll][,horizontal_scroll]) diff --git a/src/client/lua_api/gui/iguiwindow.cpp b/src/client/lua_api/gui/iguiwindow.cpp index 236fd5d..70f26e4 100644 --- a/src/client/lua_api/gui/iguiwindow.cpp +++ b/src/client/lua_api/gui/iguiwindow.cpp @@ -17,18 +17,15 @@ extern "C" { #include "../../callbackhandeler.hpp" #include -/*** -@module gui -*/ using namespace irr; using namespace gui; /*** -@function newwindow() Creates a new gui window . +@function gui.newwindow() @tparam rect dimensions The rectangle to create the window at. @tparam string title_text The text to show in the title bar of the window -@tparam ?iguielement parent The parent element of the window. +@tparam? iguielement parent The parent element of the window. @treturn iguiwindow The window element In return to the usual gui element calls, IGUI window may call a `onClose()` callback. @@ -84,6 +81,11 @@ static const luaL_reg iguiwindow_m[] = { {0, 0}, }; +/*** +A window that you can add other gui elements to. +@class iguiwindow +@inherits iguielement +*/ int iguiwindow_register(lua_State* L, IrrlichtDevice* d){ luaL_newmetatable(L,"gui.window");//m{gui.window} lua_newtable(L); diff --git a/src/client/lua_api/io/ifilesystem.cpp b/src/client/lua_api/io/ifilesystem.cpp index 252b61b..12aab78 100644 --- a/src/client/lua_api/io/ifilesystem.cpp +++ b/src/client/lua_api/io/ifilesystem.cpp @@ -1,8 +1,5 @@ #include "ifilesystem.hpp" -/*** -@module io -*/ using namespace irr; using namespace io; @@ -11,7 +8,7 @@ extern IrrlichtDevice* device; /*** A list of files in the current direcotry. -@function list() +@function io.list() @treturn array The files and directories in the current directory. */ // io.list() @@ -36,7 +33,7 @@ int listfilesin(lua_State *L){ /*** Changes the current directory of the program -@function cd(dir) +@function io.cd(dir) @tparam string dir The directory to change to */ // io.cd("directory") @@ -52,10 +49,10 @@ int changedirectory(lua_State *L){ Logs some text with Irrlicht. `level` may be any of: io.LOG_DEBUG, io.LOG_INFO, io.LOG_WARN, io.LOG_ERROR, io.LOG_NONE -@function log(text,level[,hint]) +@function io.log(text,level[,hint]) @tparam string text The text to log @tparam log_level_enum level The log level -@tparam string hint An optional hint to supply with the log +@tparam? string hint An optional hint to supply with the log */ // io.log("text",level) // io.log("text",level[,"hint"]) @@ -83,7 +80,7 @@ int logmessage(lua_State *L){ Sets what output gets logged, and what gets ignored. level may be any of: io.LOG_DEBUG, io.LOG_INFO, io.LOG_WARN, io.LOG_ERROR, io.LOG_NONE -@function set_log_level(level) +@function io.set_log_level(level) @tparam number level the minimul level of log to capture */ //io.set_log_level(level) @@ -120,14 +117,35 @@ void ifilesystem_register(lua_State* L){ lua_getglobal(L,"io");//{io} luaL_register(L,NULL,ifilesystem_f); +/*** +Debugging log level +@field io.LOG_DEBUG +*/ lua_pushnumber(L,ELL_DEBUG); lua_setfield(L,-2,"LOG_DEBUG"); +/*** +Informational log level +@field io.LOG_INTO +*/ lua_pushnumber(L,ELL_INFORMATION); lua_setfield(L,-2,"LOG_INFO"); +/*** +Warning log level +@field io.LOG_WARN +*/ lua_pushnumber(L,ELL_WARNING); lua_setfield(L,-2,"LOG_WARN"); +/*** +Error log level +@field io.LOG_ERROR +*/ lua_pushnumber(L,ELL_ERROR); lua_setfield(L,-2,"LOG_ERROR"); +/*** +Nonetype log level. +Use this with @{io#set_log_level} if you don't want to log anything. +@field io.LOG_NONE +*/ lua_pushnumber(L,ELL_NONE); lua_setfield(L,-2,"LOG_NONE"); diff --git a/src/client/lua_api/load_gui.cpp b/src/client/lua_api/load_gui.cpp index 64b9711..18fe78f 100644 --- a/src/client/lua_api/load_gui.cpp +++ b/src/client/lua_api/load_gui.cpp @@ -1,6 +1,5 @@ -/*** +/* Utilities for drawing GUI things on the screen -@module gui */ #include @@ -47,11 +46,19 @@ int screenheight(lua_State* L); int getroot(lua_State *L); /*** +Get the width of the screen. +Get the width of the screen in pixels. This should have been set with the options +in @{deviceinit.lua}, but may change of the course of the application's life (ex, +if the user resizes the screen) @function gui.scrw() @treturn number The width of the screen */ /*** +Get the height of the screen. +Get the height of the screen in pixels. This should have been set with the options +in @{deviceinit.lua}, but may change of the course of the application's life (ex, +if the user resizes the screen) @function gui.scrh() @treturn number The height of the screen */ diff --git a/src/client/lua_api/load_scene.cpp b/src/client/lua_api/load_scene.cpp index c605581..f64fc26 100644 --- a/src/client/lua_api/load_scene.cpp +++ b/src/client/lua_api/load_scene.cpp @@ -11,8 +11,10 @@ extern "C" { #include "scene/icamera.hpp" #include "scene/imesh.hpp" #include "scene/ilight.hpp" +#include using namespace irr; +using namespace video; extern IrrlichtDevice* device; @@ -25,6 +27,9 @@ void load_scenefuncs(lua_State* L){ imesh_register(L); ilight_register(L); + //INode flags + set_const(L,EMF_WIREFRAME); + //lua_pop(L, 1); } diff --git a/src/client/lua_api/scene/icamera.cpp b/src/client/lua_api/scene/icamera.cpp index 003f2ad..34b3447 100644 --- a/src/client/lua_api/scene/icamera.cpp +++ b/src/client/lua_api/scene/icamera.cpp @@ -22,6 +22,20 @@ using namespace core; extern IrrlichtDevice* device; +/*** +Create a maya camera +Creates a camera that can be controlled with maya style controls by default, +click and drag rotates the camera, while right click and mouse up/down zooms +in or out. +@function scene.newmayacamera() +@treturn iscenemayacamera +*/ +/*** +A maya camera. +A camera that can be controlled similar to the 3d modeling software "Maya" +@class iscenemayacamera +@inherits iscenecamera +*/ static int newiscenemayacamera(lua_State* L){ printf("createing maya camera!\n"); ISceneManager* smgr = device->getSceneManager(); @@ -38,6 +52,20 @@ static int newiscenemayacamera(lua_State* L){ return 1; } +/*** +Create an fps camera. +Create a camera with default first person shooter controls. The camera and +be rotated with the mouse, and moved with the arrow keys. +@function scene.newfpscamera() +@treturn iscenefpscamera The camera +*/ +/*** +A camera with default FPS controls +An FPS camera can be controlled with the arrow keys, and rotated with the mouse +by default. +@class iscenefpscamera +@inherits iscenecamera +*/ // ifpscamera.new() static int newiscenefpscamera(lua_State* L){// ISceneManager* smgr = device->getSceneManager(); @@ -60,6 +88,21 @@ static int newiscenefpscamera(lua_State* L){// return 1; } +/*** +Create a new camera +Creates a new camera at the given position. +@function scene.newiscenecamera(vector3d position, vector3d lookat, iscenenode parent) +@tparam vector3d position The position to create the camera in +@tparam vector3d lookat A vector for the camera to look at. Use this to set it's rotation. +@tparam? iscenenode parent A node to parent this camera to. If the parent moves, the camera will move with it. +@treturn iscenecamera The camera +*/ +/*** +A camera. +The world is rendered through cameras. +@class iscenecamera +@inherits iscenenode +*/ //iscenecamera.new(Vector position, Vector lookat,{node=parent}) static int newiscenecamera(lua_State* L){ printf("Createing camera!\n"); @@ -98,6 +141,12 @@ static int newiscenecamera(lua_State* L){ return 1; } +/*** +Lock on +Should the camera be locked on to something? +@function iscenecamera:bindtarget(boolean bind) +@tparam boolean bind Should the camera be locked on to it's "lookat"? +*/ //camera:bind_target(bool) :: nil static int icamerabindtarget(lua_State *L){ int should_bind = lua_toboolean(L,-1);//{node=ud_cam},bool_shouldbind @@ -110,6 +159,12 @@ static int icamerabindtarget(lua_State *L){ return 0; } +/*** +Gets the target of a camera +Gets the vector that a camera is looking at +@function iscenecamera:gettarget() +@treturn vector3d The vector that the camera is looking at +*/ //camera:gettarget() :: v3f static int icameragettarget(lua_State *L){ lua_getfield(L,-1,"node"); @@ -120,6 +175,12 @@ static int icameragettarget(lua_State *L){ return 1; } +/*** +Set the camera's target +Forcefully set the rotation the camera should be looking +@function iscenecamera:settarget(vector3d target) +@tparam vector3d target The vector that the camera should be looking at +*/ //camera:settarget(v3f) static int icamerasettarget(lua_State *L){ double x,y,z; diff --git a/src/client/lua_api/scene/igeneric.cpp b/src/client/lua_api/scene/igeneric.cpp index dcac022..a0c33b3 100644 --- a/src/client/lua_api/scene/igeneric.cpp +++ b/src/client/lua_api/scene/igeneric.cpp @@ -14,14 +14,8 @@ using namespace core; using namespace scene; using namespace video; -/*** -@classmod iscenenode -*/ - extern IrrlichtDevice* device; - - /*** Get the position of a scene element. @function iscenenode:getpos() @@ -81,6 +75,68 @@ int iscenesetangle(lua_State* L){//{node=ud_ISceneNode},{x,y,z} return 0; } +/*** +Gets the material of a scene element. +To check if to materials are equal, compare their .texture fields, these hold +a light userdata. +@function iscenenode:getmaterial() +@treturn smaterial The material that was applied to this node +*/ +//iscenenode:getmaterial({node=ud_ISceneNode},texture_number=0) :: {texture=ud_itexture} +int iscenegetmaterial(lua_State *L){ + int args = lua_gettop(L); + u32 layer = 0; + if(args == 2){ + layer = lua_tonumber(L,-1); + lua_pop(L,1); + } + lua_getfield(L,-1,"node"); + ISceneNode *i = (ISceneNode*)lua_touserdata(L,-1); + lua_pop(L,2);// + SMaterial mat = i->getMaterial(layer); + ITexture *tex = mat.getTexture(0); + printf("got texutre:%p\n",(void*)tex); + lua_newtable(L);//{} + lua_pushlightuserdata(L,tex);//{},ud_texture + lua_setfield(L,-2,"texture");//{material} + luaL_getmetatable(L,"video.smaterial");//{material},{material_m} + lua_setmetatable(L,-2);//{material} + return 1; +} + +/*** +Gets the number of materials on a scene node. +@function iscenenode:getmaterialcount() +@treturn number The number of materials on this node +*/ +//iscenenode:getmaterialcount() +int iscenegetmaterialcount(lua_State *L){ + lua_getfield(L,-1,"node"); + ISceneNode *i = (ISceneNode*)lua_touserdata(L,-1); + lua_pop(L,2);// + u32 count = i->getMaterialCount(); + lua_pushnumber(L,count); + return 1; +} + +/*** +Sets a flag on the material +@function iscenenode:setmaterialflag(flag,on) +@tparam number flag The flag to modify +@tparam boolean on Should the flag be set +*/ +//iscenenode:setmaterialflag(flag,on) +int iscenesetmaterialflag(lua_State *L){ + int on = lua_toboolean(L,-1); + E_MATERIAL_FLAG flag = (E_MATERIAL_FLAG)lua_tonumber(L,-2); + lua_pop(L,2); + lua_getfield(L,-1,"node"); + ISceneNode *i = (ISceneNode*)lua_touserdata(L,-1); + lua_pop(L,2);// + i->setMaterialFlag(flag,on == 1); + return 0; +} + /*** Set the mateiral of a scene element. @function iscenenode:setmaterial() @@ -88,7 +144,6 @@ Set the mateiral of a scene element. */ //iscenesetmaterialtexture({node=ud_ISceneNode},{texture=ud_itexture},texture_number=0) int iscenesetmaterial(lua_State *L){ - printf("Calling generic iscenesetmaterial function\n"); int args = lua_gettop(L); u32 layer = 0; if(args == 3){ @@ -220,6 +275,9 @@ extern const luaL_reg igeneric_m[] = { {"getang", iscenegetangle}, {"setang", iscenesetangle}, {"setmaterialtexture", iscenesetmaterial}, + {"getmaterial", iscenegetmaterial}, + {"getmaterialcount", iscenegetmaterialcount}, + {"setmaterialflag", iscenesetmaterialflag}, {"getname", iscenegetname}, {"setname", iscenesetname}, {"setscale", iscenesetscale}, diff --git a/src/client/lua_api/scene/ilight.cpp b/src/client/lua_api/scene/ilight.cpp index 1e292ee..e405443 100644 --- a/src/client/lua_api/scene/ilight.cpp +++ b/src/client/lua_api/scene/ilight.cpp @@ -23,6 +23,21 @@ using namespace core; extern IrrlichtDevice* device; +/*** +Create a light +Creates a light that illuminates the surrounding objects dynamically. +@function scene.newlight(number radius, vector3d position) +@tparam number radius The radius that the light should shine +@tparam vector3d position The position to create the light at +@treturn iscenelight The created light +*/ +/*** +A light. +Lights illuminate the scene nodes arounded them based on mesh vertexes. You +probably want to bake the lightmap instead of using light nodes. +@class iscenelight +@inherits iscenenode +*/ //{} :: scene.newlight(radius, {v3 position}) static int newiscenelight(lua_State* L){ printf("Createing light!\n"); @@ -48,6 +63,12 @@ static int newiscenelight(lua_State* L){ } +/*** +Sets the light type +Different light types illuminate the surrounding meshes in different ways. +@function iscenelight:settype(number type) +@tparam number type The type the light should be +*/ //settype(self,const) int settype(lua_State *L){ video::E_LIGHT_TYPE type = (video::E_LIGHT_TYPE)lua_tonumber(L,-1);//self,type @@ -60,8 +81,6 @@ int settype(lua_State *L){ } static const luaL_reg ilight_m[] = { - {"getpos", iscenegetpos}, - {"setpos", iscenesetpos}, {"settype", settype}, {0, 0}, }; @@ -72,8 +91,20 @@ void ilight_register(lua_State* L){ lua_pushcfunction(L,newiscenelight);//{scene},newiscenelight() lua_setfield(L,-2,"newlight");//{scene} +/*** +A point light +@field scene.ELT_POINT +*/ set_const(L,ELT_POINT); +/*** +A spot light +@field scene.ELT_SPOT +*/ set_const(L,ELT_SPOT); +/*** +A sun light +@field scene.ELT_DIRECTIONAL +*/ set_const(L,ELT_DIRECTIONAL); lua_pop(L,1);// @@ -81,6 +112,7 @@ void ilight_register(lua_State* L){ luaL_newmetatable(L,"scene.ilight");//scene.ilight lua_newtable(L);//scene.ilight,{} luaL_register(L, NULL, ilight_m);//scene.ilight,{} + luaL_register(L, NULL, igeneric_m); lua_setfield(L,-2,"__index");//scene.ilight lua_pop(L,1); diff --git a/src/client/lua_api/scene/imesh.cpp b/src/client/lua_api/scene/imesh.cpp index 8ed357c..479da15 100644 --- a/src/client/lua_api/scene/imesh.cpp +++ b/src/client/lua_api/scene/imesh.cpp @@ -16,9 +16,6 @@ extern "C" { #include "igeneric.hpp" #include -/*** -@module scene -*/ using namespace irr; using namespace scene; using namespace core; diff --git a/src/client/lua_api/video/iimage.cpp b/src/client/lua_api/video/iimage.cpp index 4c7795d..3655b64 100644 --- a/src/client/lua_api/video/iimage.cpp +++ b/src/client/lua_api/video/iimage.cpp @@ -4,10 +4,6 @@ #include -/*** -@module video -*/ - using namespace irr; using namespace video; @@ -17,7 +13,7 @@ extern IVideoDriver* driver; /*** Creates a new irrlicht image. A newly created image will be fully white by default. -@function newiimage(format, size) +@function video.newiimage(format, size) @tparam enum_color_format format The format for the image @tparam vec2d size The size of the image @treturn iimage The image @@ -44,7 +40,7 @@ int newiimage(lua_State* L){ Creates a new irrlicht image. Creates a new irrlicht image from a file. The format and width/height will be taken from the image file. -@function newiimagefromfile(path) +@function video.newiimagefromfile(path) @tparam string path The file path of the image file @treturn iimage The loaded image */ @@ -138,7 +134,7 @@ int getiimagepixel(lua_State* L){ /*** Returns the dimensions of the image @function iimage:getDimensions() -@treturn vec2i dimensions The dimensions of the image +@treturn vec2i The dimensions of the image */ //getdimensions({self}) int getiimagedimensions(lua_State *L){ @@ -162,10 +158,29 @@ void iimage_register(lua_State* L){ driver = device->getVideoDriver(); lua_getglobal(L,"video");//{} +/*** +1 bit alpha, 5 bits red, blue, and green (16 bit) +@field video.ECF_A1R5G5B5 +*/ set_const(L,ECF_A1R5G5B5); +/*** +5 bit red, 6 bit green, 5 bit blue +@field video.ECF_R5G6B5 +*/ set_const(L,ECF_R5G6B5); +/*** +8 bit red, blue, green, and alpha +@field video.ECF_A8R8G8B8 +*/ set_const(L,ECF_A8R8G8B8); +/*** +1 channel with 16 bit floating point. +1 channel 16 bit floating point. Uses the red channel. Floating point images may only be used for render targets. +@field video.ECF_R16F +@see @{render_targets} +*/ set_const(L,ECF_R16F); +//TODO: finish documenting these set_const(L,ECF_G16R16F); set_const(L,ECF_A16B16G16R16F); set_const(L,ECF_R32F); diff --git a/src/client/lua_api/video/smaterial.cpp b/src/client/lua_api/video/smaterial.cpp index 510748c..4ed6a46 100644 --- a/src/client/lua_api/video/smaterial.cpp +++ b/src/client/lua_api/video/smaterial.cpp @@ -9,7 +9,15 @@ extern "C" { using namespace irr::video; -/*This probably needs a _gc metamethod*/ +/*** +Creates a new material. +Creates a new material that can then be used on an @{iscenenode} +WARNING: this item is not currently garbage collected, be careful not to make +more smaterials than you need. +@function video.newsmaterial() +@treturn smaterial The new material +*/ +/*TODO: This probably needs a _gc metamethod*/ //newsmaterial() int newsmaterial(lua_State* L){ @@ -24,6 +32,14 @@ int newsmaterial(lua_State* L){ return 1; } +/*** +Sets a texture for this material. +Sets a texture for the material on the given index. For more information on +what each texture of a material does, see the irrlicht documentation. +@function smaterial:settexture(index,texture) +@tparam number index The index of the texture in the material +@tparam itexture texture The texture to use +*/ //setTexture(self,int_num,{ITexture texture}) int setTexture(lua_State* L){ lua_getfield(L,-1,"texture"); @@ -38,6 +54,13 @@ int setTexture(lua_State* L){ return 0; } +/*** +Sets a flag on this material. +Sets the given flag on the material +@function smaterial:setflag(flag,state) +@tparam number flag The flag to set, see @{video} for flags. +@tparam boolean state The state to set the flag in +*/ //{Material},flag,state int setFlag(lua_State* L){ int b = lua_toboolean(L,-1);//{material},flag,state @@ -52,8 +75,8 @@ int setFlag(lua_State* L){ } static const luaL_reg smaterial_m[] = { - {"setTexture", setTexture}, - {"setFlag", setFlag}, + {"settexture", setTexture}, + {"setflag", setFlag}, {0,0}, }; @@ -73,6 +96,30 @@ void smaterial_register(lua_State* L){ lua_getglobal(L,"video");//{} + /*** + A table of constants for the material class. + @field EMF_WIREFRAME - enable wireframe + @field EMF_POINTCLOUD - displays the texture as a pointcloud instead of a solid face + @field EMF_GOURAUD_SHADING + @field EMF_LIGHTING + @field EMF_ZBUFFER + @field EMF_ZWRITE_ENABLE + @field EMF_BACK_FACE_CULLING + @field EMF_FRONT_FACE_CULLING + @field EMF_BILINEAR_FILTER + @field EMF_TRILINEAR_FILTER + @field EMF_ANISOTROPIC_FILTER + @field EMF_FOG_ENABLE + @field EMF_NORMALIZE_NORMALS + @field EMF_TEXTURE_WRAP + @field EMF_ANTI_ALIASING + @field EMF_COLOR_MASK + @field EMF_COLOR_MATERIAL + @field EMF_USE_MIP_MAPS + @field EMF_BLEND_OPERATION + @field EMF_POLYGON_OFFSET + @table .video. + */ set_const(L,EMF_WIREFRAME); set_const(L,EMF_POINTCLOUD); set_const(L,EMF_GOURAUD_SHADING); diff --git a/src/client/main.cpp b/src/client/main.cpp index 98b2f61..2d93828 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -129,8 +129,8 @@ int main(int argc, char *argv[]){ //Create a new lua state, this gets shared everywhere //Set the path for lua - putenv("LUA_PATH=?.lua"); - putenv("LUA_CPATH=../bin/?.dll"); + putenv((char*)"LUA_PATH=../data/?.lua"); + putenv((char*)"LUA_CPATH=../bin/?.dll"); lua_State *state = luaL_newstate(); L = state; printf("Created lua state at %p\n",L); diff --git a/src/server/lua_api/load_io.cpp b/src/server/lua_api/load_io.cpp index 278d7a7..0a20311 100644 --- a/src/server/lua_api/load_io.cpp +++ b/src/server/lua_api/load_io.cpp @@ -10,54 +10,55 @@ extern "C" { #include #include -#define epath "../data" -#define epathlen sizeof(epath) +//#define epath "../data" +//#define epathlen sizeof(epath) /*Add an io.dir(path) function, which lists all the files in (path)*/ -int dirpath(lua_State *L){ - if(!lua_isstring(L,-1)){ - lua_pushstring(L,"io.dir() requires a string as argument #1"); - lua_error(L); - } - size_t pathstrlen; - const char *pathstr = lua_tolstring(L,-1,&pathstrlen); - //printf("got pathstr: %s\n",pathstr); - //char tpathstr[pathstrlen + epathlen + 1 + 1]; //+1 for null, +1 for / - //memcpy(tpathstr,epath,epathlen); - //tpathstr[epathlen] = '/'; - //memcpy(tpathstr+epathlen,pathstr,pathstrlen); - //tpathstr[pathstrlen + epathlen + 1] = '\0'; - //printf("tpathstr is: \"%s\"\n",tpathstr); - //lua_pop(L,1); - DIR *dir; - struct dirent *ent; - const char *tpathstr = pathstr; - dir = opendir(tpathstr); - if(dir == NULL){ - perror("Cannot open"); - lua_pushstring(L,"Failed to open directory: "); - lua_pushstring(L,tpathstr); - lua_concat(L,2); - lua_error(L); - } - int i = 1; - ent = readdir(dir); - lua_newtable(L); - while( (ent = readdir(dir)) != NULL){ - lua_pushinteger(L,i); - lua_pushstring(L,ent->d_name); - lua_settable(L,-3); - i++; - } - closedir(dir); - return 1; -} +//UPDATE: Moved to shared code +//int dirpath(lua_State *L){ + //if(!lua_isstring(L,-1)){ + //lua_pushstring(L,"io.dir() requires a string as argument #1"); + //lua_error(L); + //} + //size_t pathstrlen; + //const char *pathstr = lua_tolstring(L,-1,&pathstrlen); + ////printf("got pathstr: %s\n",pathstr); + ////char tpathstr[pathstrlen + epathlen + 1 + 1]; //+1 for null, +1 for / + ////memcpy(tpathstr,epath,epathlen); + ////tpathstr[epathlen] = '/'; + ////memcpy(tpathstr+epathlen,pathstr,pathstrlen); + ////tpathstr[pathstrlen + epathlen + 1] = '\0'; + ////printf("tpathstr is: \"%s\"\n",tpathstr); + ////lua_pop(L,1); + //DIR *dir; + //struct dirent *ent; + //const char *tpathstr = pathstr; + //dir = opendir(tpathstr); + //if(dir == NULL){ + //perror("Cannot open"); + //lua_pushstring(L,"Failed to open directory: "); + //lua_pushstring(L,tpathstr); + //lua_concat(L,2); + //lua_error(L); + //} + //int i = 1; + //ent = readdir(dir); + //lua_newtable(L); + //while( (ent = readdir(dir)) != NULL){ + //lua_pushinteger(L,i); + //lua_pushstring(L,ent->d_name); + //lua_settable(L,-3); + //i++; + //} + //closedir(dir); + //return 1; +//} void load_iofuncs(lua_State* L){ lua_getglobal(L,"io"); - lua_pushcfunction(L,dirpath); - lua_setfield(L,-2,"dir"); + //lua_pushcfunction(L,dirpath); + //lua_setfield(L,-2,"dir"); lua_pop(L,1); } diff --git a/src/shared/lua_api/load_common.cpp b/src/shared/lua_api/load_common.cpp index 1eca598..188cd30 100644 --- a/src/shared/lua_api/load_common.cpp +++ b/src/shared/lua_api/load_common.cpp @@ -5,6 +5,13 @@ extern "C" { #include #include } +//Open group +#include //for io.dir("file/path") +#include //required before sys/stat.h on windows +#include //for io.time("path/to.file") +#include +#include //For better errors + using namespace std::chrono; //Gets the time @@ -16,6 +23,45 @@ int get_time(lua_State* L){ return 1; } +char *epath; +size_t epathlen; +/*Add an io.dir(path) function, which lists all the files in (path)*/ +int dirpath(lua_State *L){ + if(!lua_isstring(L,-1)){ + lua_pushstring(L,"io.dir() requires a string as argument #1"); + lua_error(L); + } + size_t pathstrlen; + const char *pathstr = lua_tolstring(L,-1,&pathstrlen); + char tpathstr[pathstrlen + epathlen + 1 + 1]; //+1 for null, +1 for / + memcpy(tpathstr,epath,epathlen); + tpathstr[epathlen] = '/'; + memcpy(tpathstr+epathlen+1,pathstr,pathstrlen); + tpathstr[pathstrlen + epathlen + 1] = '\0'; + lua_pop(L,1); + DIR *dir; + struct dirent *ent; + dir = opendir(tpathstr); + if(dir == NULL){ + perror("Cannot open"); + lua_pushstring(L,"Failed to open directory: "); + lua_pushstring(L,tpathstr); + lua_concat(L,2); + lua_error(L); + } + int i = 1; + ent = readdir(dir); + lua_newtable(L); + while( (ent = readdir(dir)) != NULL){ + lua_pushinteger(L,i); + lua_pushstring(L,ent->d_name); + lua_settable(L,-3); + i++; + } + closedir(dir); + return 1; +} + void loadCommonLibs(lua_State* L){ lua_getglobal(L,"GAME"); lua_pushcfunction(L,make_crashy); @@ -23,6 +69,11 @@ void loadCommonLibs(lua_State* L){ lua_pop(L,1); lua_pushcfunction(L,get_time); lua_setglobal(L,"get_time"); + + lua_getglobal(L,"io"); + lua_pushcfunction(L,dirpath); + lua_setfield(L,-2,"dir"); + lua_pop(L,1); } void gameloop_common(lua_State* L){ diff --git a/src/shared/lua_api/load_net.cpp b/src/shared/lua_api/load_net.cpp index b377cc5..bff55cf 100644 --- a/src/shared/lua_api/load_net.cpp +++ b/src/shared/lua_api/load_net.cpp @@ -1,11 +1,11 @@ -/*** +/* +TODO:Fix documentation or find a better home for this example code. The net library Exposes various structs, constants, and functions for passing messages A list of protocols that can be used when creating sockets. The number values below are only for refrence. You should use net.PAIR, net.BUS, ect. -@module net @usage --Server local s = net.newsocket(net.REP) @@ -67,7 +67,7 @@ extern "C" { /*** 1 to 1 protocol. -@field PAIR 1 +@field net.PAIR */ #define PAIR 1 @@ -75,63 +75,63 @@ extern "C" { Many to many protocol. When this socket sends messages, it does not receive a copy of the message it just sent. -@field BUS 2 +@field net.BUS */ #define BUS 2 /*** Publish protocol. The first half of the pub/sub protocol. -@field PUB 3 +@field net.PUB */ #define PUB 3 /*** Subscribe protocol The second half of the pub/sub protocol. -@field SUB 4 +@field net.SUB */ #define SUB 4 /*** Pull protocol. The first half of the push/pull protocol. -@field PULL 5 +@field net.PULL */ #define PULL 5 /*** Push protocol. The second half of the push/pull protocol. -@field PUSH 6 +@field net.PUSH */ #define PUSH 6 /*** Request protocol. The first half of the request/reply protocol. -@field REQ 7 +@field net.REQ */ #define REQ 7 /*** Reply protocol. The second half of the request/reply protocol. -@field REP 8 +@field net.REP */ #define REP 8 /*** Respond protocol. The second half of the survey/respond protocol. -@field RESPOND 9 +@field net.RESPOND */ #define RESPOND 9 /*** Survey protocol. The first half of the survey/respond protocol. -@field SURVEY 10 +@field net.SURVEY */ #define SURVEY 10 @@ -597,8 +597,8 @@ int netclose(lua_State* L){//{socket} } /*** -@field fd -@table net.socket +The opaque socket descriptor for this socket. +@field socket.fd The descriptor @domain shared */ diff --git a/src/shared/lua_api/phys/bcollider.cpp b/src/shared/lua_api/phys/bcollider.cpp index 91c34fd..caefd3e 100644 --- a/src/shared/lua_api/phys/bcollider.cpp +++ b/src/shared/lua_api/phys/bcollider.cpp @@ -1,3 +1,10 @@ +/* +A wrapper for the btCollisionObject class. +Most of the methods that bullet exposes for the btCollisionObject are wrapped +here, any subclass of btCollisionObject should register methods defined +here in it's metatable's __index. +*/ + extern "C" { #include #include diff --git a/src/shared/lua_api/phys/bghostobject.cpp b/src/shared/lua_api/phys/bghostobject.cpp index 63f790c..5657b5f 100644 --- a/src/shared/lua_api/phys/bghostobject.cpp +++ b/src/shared/lua_api/phys/bghostobject.cpp @@ -109,7 +109,7 @@ int bghostconvexsweep(lua_State *L){ btVector3 hw, hn; hw = cb->m_hitPointWorld; hn = cb->m_hitNormalWorld; - btCollisionObject *co = cb->m_hitCollisionObject; + const btCollisionObject *co = cb->m_hitCollisionObject; lua_newtable(L);//{} lua_pushboolean(L,cb->hasHit() ? 1 : 0); @@ -118,12 +118,17 @@ int bghostconvexsweep(lua_State *L){ lua_setfield(L,-2,"pos"); pushvector3d(L,hn.x(),hn.y(),hn.z()); lua_setfield(L,-2,"normal"); + lua_getglobal(L,"phys");//{},{phys} lua_getfield(L,-1,"colliders");//{},{phys},{phys.colliders} - lua_pushlightuserdata(L,co);//{},{phys},{phys.colliders},ud_collisionobject - lua_gettable(L,-2);//{},{phys},{phys.colliders},ud_collisionobject,{rb} or nil - lua_setfield(L,-5,"what");//{},{phys},{phys.colliders},ud_collisionobject - lua_pop(L,3);//{} + lua_pushlightuserdata(L,(void*)co);//{},{phys},{phys.colliders},ud_collisionobject + lua_gettable(L,-2);//{},{phys},{phys.colliders},{rb} or nil + if(lua_isnil(L,-1)){ + lua_pop(L,3);//{} + }else{ + lua_setfield(L,-4,"what");//{},{phys},{phys.colliders} + lua_pop(L,2);//{} + } delete cb; return 1; diff --git a/src/shared/lua_api/phys/bphysbox.cpp b/src/shared/lua_api/phys/bphysbox.cpp index 569f3f9..66f112d 100644 --- a/src/shared/lua_api/phys/bphysbox.cpp +++ b/src/shared/lua_api/phys/bphysbox.cpp @@ -107,7 +107,7 @@ int newbphysbox(lua_State* L){ //Set it's metatable luaL_getmetatable(L, "phys.physbox");//{},{phys.physbox} lua_setmetatable(L, -2);//{} - + return 1; } diff --git a/src/shared/lua_api/phys/bphysgeneric.cpp b/src/shared/lua_api/phys/bphysgeneric.cpp index 4500ce0..eed9112 100644 --- a/src/shared/lua_api/phys/bphysgeneric.cpp +++ b/src/shared/lua_api/phys/bphysgeneric.cpp @@ -8,11 +8,6 @@ extern "C" { #include #include -/*** -@module phys -*/ - - /*Physics things from lua have the form of: { type = "rigidbody" @@ -243,6 +238,7 @@ int applyimpulse(lua_State *L){ popvector3d(L,&x,&y,&z); btRigidBody *r = popRigidBody(L); r->applyImpulse(btVector3(x,y,z),btVector3(ox,oy,oz)); + r->activate(); return 0; } @@ -265,6 +261,14 @@ int setrotation(lua_State *L){ return 0; } +//rigidbody:getmass() :: number +int getmass(lua_State *L){ + btRigidBody *r = popRigidBody(L); + double m = r->getMass(); + lua_pushnumber(L,m); + return 1; +} + /* @@ -310,6 +314,7 @@ extern const luaL_reg brigidbody_m[] = { {"setangfactor", setangfactor}, {"setflags", setflags}, {"setrotation", setrotation}, + {"getmass", getmass}, //{"testcontact", testcontact}, {NULL, NULL} }; diff --git a/src/shared/lua_api/phys/bphysmodel.cpp b/src/shared/lua_api/phys/bphysmodel.cpp index 0c8e3bf..375d68b 100644 --- a/src/shared/lua_api/phys/bphysmodel.cpp +++ b/src/shared/lua_api/phys/bphysmodel.cpp @@ -24,6 +24,10 @@ extern "C" { extern btDiscreteDynamicsWorld* World; extern std::list Objects; +//btRigidBody* load_obj(tinyobj_attrib_t attrib, tinyobj_shape_t *shapes, size_t num){ + //btTriangleMesh *trimesh = new btTriangleMesh(); +//} + //TODO: This will break in the future, see github.com/syoyo/tinyobjloader-c/issues/16 //"physicfile",mass[,position][,lookat] :: ud_rigidbody void makebphysmodel(lua_State *L){ @@ -67,6 +71,9 @@ void makebphysmodel(lua_State *L){ if(err != TINYOBJ_SUCCESS){ printf("Tinyobj failed to load model:%s\n",ppath); } + //for(size_t s = 0; s < meshcount; s++){ + //btRigidBody *rb = load_obj(attrib,shapes,s); + //} //u32 meshcount = pmesh->getMeshBufferCount(); //__mingw_printf("attrib.num_vertices: %u\n",attrib.num_vertices); //__mingw_printf("attrib.num_faces: %u\n",attrib.num_faces); @@ -81,7 +88,7 @@ void makebphysmodel(lua_State *L){ float v2 = vs[1]; float v3 = vs[2]; vertexes[i] = btVector3(v1,v2,v3); - printf("Adding vertex %lld at (%f,%f,%f)\n",i,v1,v2,v3); + //printf("Adding vertex %lld at (%f,%f,%f)\n",i,v1,v2,v3); } //printf("Finished finding or adding vertexes\n"); for(size_t i = 0; i < attrib.num_faces - 1; i+= 3){ //0 - y to num_faces - 1 @@ -94,14 +101,14 @@ void makebphysmodel(lua_State *L){ v2 = vertexes[i2.v_idx]; v3 = vertexes[i3.v_idx]; trimesh->addTriangle(vertexes[i1.v_idx],vertexes[i2.v_idx],vertexes[i3.v_idx],false);//Some triangles are "the wrong way round", - printf("Adding triangle:(%d,%d,%d)\n",i1.v_idx,i2.v_idx,i3.v_idx); - //trimesh->addTriangle(vertexes[i3.v_idx],vertexes[i2.v_idx],vertexes[i1.v_idx],true);//double-side all triangles + //printf("Adding triangle:(%d,%d,%d)\n",i1.v_idx,i2.v_idx,i3.v_idx); + trimesh->addTriangle(vertexes[i3.v_idx],vertexes[i2.v_idx],vertexes[i1.v_idx],true);//double-side all triangles } //printf("Finished adding triangle indicies\n"); //printf("Done building trimesh\n"); - //btGImpactShapeInterface *shape = new btGImpactMeshShape(trimesh); - btConvexTriangleMeshShape *shape = new btConvexTriangleMeshShape(trimesh); - //shape->updateBound(); + //btConvexTriangleMeshShape *shape = new btConvexTriangleMeshShape(trimesh); + btGImpactShapeInterface *shape = new btGImpactMeshShape(trimesh); + shape->updateBound(); //btCollisionShape *shape = new btBvhTriangleMeshShape(trimesh,true); btTransform tr; tr.setIdentity(); -- cgit v1.2.3-70-g09d2