From a88882a683a8e4e2e00e367edd10ed0ceebff958 Mon Sep 17 00:00:00 2001 From: VilacaGabriel Date: Tue, 23 Sep 2025 03:16:27 -0300 Subject: [PATCH 1/3] =?UTF-8?q?adiciona=20ficha=20de=20Tormenta=2020=20ver?= =?UTF-8?q?s=C3=A3o=20Jogo=20do=20Ano?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugins/Sheets/Ficha Tormente20 Jogo do Ano | 1 + 1 file changed, 1 insertion(+) create mode 160000 Plugins/Sheets/Ficha Tormente20 Jogo do Ano diff --git a/Plugins/Sheets/Ficha Tormente20 Jogo do Ano b/Plugins/Sheets/Ficha Tormente20 Jogo do Ano new file mode 160000 index 00000000..67fb0ca2 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormente20 Jogo do Ano @@ -0,0 +1 @@ +Subproject commit 67fb0ca278fed89807c509b5e583c6abab0870e7 From 7891898a603514733fb4c87297146ed9c6f4e1bd Mon Sep 17 00:00:00 2001 From: VilacaGabriel Date: Wed, 24 Sep 2025 15:45:29 -0300 Subject: [PATCH 2/3] =?UTF-8?q?ajusta=20estrutura=20para=20seguir=20padr?= =?UTF-8?q?=C3=B5es=20do=20Firecast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module.xml | 15 + sdk/README.md | 10 + sdk/async.lua | 486 +++++++ sdk/audio.lua | 2 + sdk/audioCore.dlua | 194 +++ sdk/btree.dlua | 141 ++ sdk/btree_private.dlua | 849 ++++++++++++ sdk/delayedLoad.dlua | 42 + sdk/dialogs.lua | 1 + sdk/fireDrive.lua | 3 + sdk/fireDriveCore.dlua | 261 ++++ sdk/firecast.lua | 1 + sdk/gui.lua | 1 + sdk/internet.lua | 3 + sdk/internetCore.dlua | 188 +++ sdk/locale.lua | 19 + sdk/localeCore.dlua | 99 ++ sdk/log.lua | 39 + sdk/ndb.lua | 929 +++++++++++++ sdk/ndb_observer.dlua | 51 + sdk/ndb_transaction.dlua | 53 + sdk/plugins.lua | 6 + sdk/pluginsCore.dlua | 243 ++++ sdk/rrpg.lua | 442 +++++++ sdk/rrpgDialogs.lua | 519 ++++++++ sdk/rrpgEventMessages.lua | 236 ++++ sdk/rrpgEventMessagesAdapters.lua | 308 +++++ sdk/rrpgEvents.lua | 133 ++ sdk/rrpgGUI.lua | 2060 +++++++++++++++++++++++++++++ sdk/rrpgGUI_grid.dlua | 244 ++++ sdk/rrpgLFM.lua | 428 ++++++ sdk/rrpgObjs.lua | 775 +++++++++++ sdk/rrpgRequests.lua | 83 ++ sdk/rrpgSharedObjects.lua | 149 +++ sdk/rrpgUtil.lua | 485 +++++++ sdk/rrpgUtil_async.dlua | 78 ++ sdk/rrpgWrappers.lua | 1185 +++++++++++++++++ sdk/scene.lua | 13 + sdk/sceneCore.dlua | 146 ++ sdk/sceneWrappers.dlua | 1123 ++++++++++++++++ sdk/sdk3.lang | 11 + sdk/serpent.dlua | 172 +++ sdk/slaxdom.dlua | 49 + sdk/slaxml.dlua | 257 ++++ sdk/system.lua | 3 + sdk/systemCore.dlua | 51 + sdk/utils.lua | 1 + sdk/utils.serializer.dlua | 339 +++++ sdk/vhd.lua | 77 ++ sdk/vkCodes.dlua | 190 +++ 50 files changed, 13193 insertions(+) create mode 100644 module.xml create mode 100644 sdk/README.md create mode 100644 sdk/async.lua create mode 100644 sdk/audio.lua create mode 100644 sdk/audioCore.dlua create mode 100644 sdk/btree.dlua create mode 100644 sdk/btree_private.dlua create mode 100644 sdk/delayedLoad.dlua create mode 100644 sdk/dialogs.lua create mode 100644 sdk/fireDrive.lua create mode 100644 sdk/fireDriveCore.dlua create mode 100644 sdk/firecast.lua create mode 100644 sdk/gui.lua create mode 100644 sdk/internet.lua create mode 100644 sdk/internetCore.dlua create mode 100644 sdk/locale.lua create mode 100644 sdk/localeCore.dlua create mode 100644 sdk/log.lua create mode 100644 sdk/ndb.lua create mode 100644 sdk/ndb_observer.dlua create mode 100644 sdk/ndb_transaction.dlua create mode 100644 sdk/plugins.lua create mode 100644 sdk/pluginsCore.dlua create mode 100644 sdk/rrpg.lua create mode 100644 sdk/rrpgDialogs.lua create mode 100644 sdk/rrpgEventMessages.lua create mode 100644 sdk/rrpgEventMessagesAdapters.lua create mode 100644 sdk/rrpgEvents.lua create mode 100644 sdk/rrpgGUI.lua create mode 100644 sdk/rrpgGUI_grid.dlua create mode 100644 sdk/rrpgLFM.lua create mode 100644 sdk/rrpgObjs.lua create mode 100644 sdk/rrpgRequests.lua create mode 100644 sdk/rrpgSharedObjects.lua create mode 100644 sdk/rrpgUtil.lua create mode 100644 sdk/rrpgUtil_async.dlua create mode 100644 sdk/rrpgWrappers.lua create mode 100644 sdk/scene.lua create mode 100644 sdk/sceneCore.dlua create mode 100644 sdk/sceneWrappers.dlua create mode 100644 sdk/sdk3.lang create mode 100644 sdk/serpent.dlua create mode 100644 sdk/slaxdom.dlua create mode 100644 sdk/slaxml.dlua create mode 100644 sdk/system.lua create mode 100644 sdk/systemCore.dlua create mode 100644 sdk/utils.lua create mode 100644 sdk/utils.serializer.dlua create mode 100644 sdk/vhd.lua create mode 100644 sdk/vkCodes.dlua diff --git a/module.xml b/module.xml new file mode 100644 index 00000000..7163e34d --- /dev/null +++ b/module.xml @@ -0,0 +1,15 @@ + + + + IDENTIFICADOR_UNICO_DO_PLUGIN + + 1.0 + + + Nome curto do seu plugin. Exemplo: DnD 5 + Descrição do plugin aqui. Exemplo: Adiciona suporte a abas para o sistema ETC, com tais recursos, para tais propósitos ... + Seu nome aqui + http://www.seu.site.com.br + Facebook? Twitter? E-Mail? + + diff --git a/sdk/README.md b/sdk/README.md new file mode 100644 index 00000000..dc558bad --- /dev/null +++ b/sdk/README.md @@ -0,0 +1,10 @@ +# API do SDK 3 (Software Development Kit) + +O motor de funcionamento do SDK3 é dividido entre duas entidades: + +- Código binário em pascal, embutido no rrpg.exe ou FirecastMobile +- Código lua que faz a ponte entre seu código .lua e o código binário. + +Esta pasta contém o código lua que faz a ponte entre os dois mundos! + +Observação: Quando você realiza o comando "rdk p", o conteúdo desta pasta é copiado para a subpasta /sdk do seu projeto. \ No newline at end of file diff --git a/sdk/async.lua b/sdk/async.lua new file mode 100644 index 00000000..a7b78d8a --- /dev/null +++ b/sdk/async.lua @@ -0,0 +1,486 @@ +local Log = require("log.lua"); + +local _ASYNC_EXEC_AWAIT_CO_RET = "_co:await"; +local _ASYNC_EXEC_IDLE_COROUTINE_RET = "_co:idle"; + +Async = {}; +Async.Promise = {}; + +Promise = Async.Promise; + +Async._ASYNC_EXEC_AWAIT_CO_RET = _ASYNC_EXEC_AWAIT_CO_RET; + +local _asyncExecution = {idleCoroutines = {}, + idleCoroutinesCount = 0, + maxIdleCoroutines = 8}; + +function Async.haveNativeBackendSupport() + return true; +end; + +--- Base Promise MetaTable + +local BasePromiseMetatable = {} +BasePromiseMetatable.__index = BasePromiseMetatable; + +function BasePromiseMetatable:thenFinally(callback) + local wrappedContinuationCallback = + function(ignoredParameter) + if callback ~= nil then + return callback(); + end; + end; + + return self:thenDo(wrappedContinuationCallback, wrappedContinuationCallback); +end; + +function BasePromiseMetatable:onSuccess(callback) + return self:thenDo(callback, nil); +end; + +function BasePromiseMetatable:onError(callback) + return self:thenDo(nil, callback); +end; + +function BasePromiseMetatable:thenResolve(promiseResolution) + return self:thenDo( + function(...) + return promiseResolution:setSuccess(...); + end, + + function(errorMsg) + return promiseResolution:setFailure(errorMsg); + end); +end; + +function BasePromiseMetatable:unwrap() + local ret = table.pack(self:peek()); + + if ret[1] then + if ret[2] then + return table.unpack(ret, 3); + else + reraise(ret[3]); + end; + else + return self; + end; +end; + +function BasePromiseMetatable:await() + return Async.await(self); +end; + +function BasePromiseMetatable:pawait() + return Async.pawait(self); +end; + +--- Concrete Promise MetaTable + +local PromiseMetatable = {}; +setmetatable(PromiseMetatable, BasePromiseMetatable); +PromiseMetatable.__index = PromiseMetatable; + +function PromiseMetatable:peek() + if _async_promise_peek ~= nil then + return _async_promise_peek(self.handle); + else + return false; + end; +end; + +function PromiseMetatable:thenDo(successCallback, errorCallback) + local thenDoHandle = _async_promise_thenDo(self.handle, successCallback, errorCallback); + return Promise.wrap(thenDoHandle); +end; + +-- PromiseResolution Metatable + +local PromiseResolutionMetatable = {}; +PromiseResolutionMetatable.__index = PromiseResolutionMetatable; + +function PromiseResolutionMetatable:setSuccess(...) + return _async_promiseResolution_setSuccess(self.handle, ...); +end; + +function PromiseResolutionMetatable:setFailure(...) + return _async_promiseResolution_setFailure(self.handle, ...); +end; + +function PromiseResolutionMetatable:setUserAborted() + return _async_promiseResolution_setUserAborted(self.handle); +end; + +-- Promises Creation + +function Promise.__newBaseStubPromise() + local p = {} + setmetatable(p, BasePromiseMetatable); + return p; +end; + +function Promise.__newStubSuccessPromise(data) + local p = Promise.__newBaseStubPromise(); + local previousThenDo = p.thenDo; + + function p:peek() + return true, true, data; + end; + + function p:thenDo(successCallback, errorCallback) + if type(successCallback) == "function" then + successCallback(data); + end; + + return previousThenDo(p, successCallback, errorCallback) + end; + + return p; +end; + +function Promise.__newStubFailedPromise(errorMsg) + local p = Promise.__newBaseStubPromise(); + local previousThenDo = p.thenDo; + + function p:peek() + return true, false, errorMsg; + end; + + function p:thenDo(successCallback, errorCallback) + if type(errorCallback) == "function" then + errorCallback(errorMsg); + end; + + return previousThenDo(p, successCallback, errorCallback) + end; + + return p; +end; + +function Promise.__newStubPendingPromise() + local p = Promise.__newBaseStubPromise(); + + p.__resolved = false; + + -- Promise interface + + function p:peek() + if self.__resolved then + return true, p.__success, table.unpack(p.__data); + else + return false; + end; + end; + + function p:thenDo(successCallback, errorCallback) + if self.__resolved then + if self.__success and type(successCallback) == "function" then + successCallback(table.unpack(self.__data)); + elseif not self.__success and type(errorCallback) == "function" then + errorCallback(table.unpack(self.__data)); + end; + else + if type(errorCallback) == "function" then + errorCallback("No API Support"); + end; + end; + + return Async.Promise.failed("No API Support"); + end; + + -- PromiseResolution interface + + function p:setSuccess(...) + if not self.__resolved then + self.__resolved = true; + self.__success = true; + self.__data = table.pack(...); + else + return false; + end; + end; + + function p:setFailure(errorMsg) + if not self.__resolved then + self.__resolved = true; + self.__success = false; + self.__data = {errorMsg}; + else + return false; + end; + end; + + function p:setUserAborted() + return self:setFailure("UserAbortedException"); + end; + + return p; +end; + +function Promise.wrap(handle) + local p = {} + setmetatable(p, PromiseMetatable); + p.handle = handle; + return p; +end; + +function Promise.wrapPromiseResolution(handle) + local r = {}; + setmetatable(r, PromiseResolutionMetatable); + r.handle = handle; + + return r; +end; + +function _asyncExecution.__asyncExecAwaitPromise(co, promise) + promise:thenDo( + function (...) + _asyncExecution.resume(co, true, ...); + end, + + function (errorMsg) + _asyncExecution.resume(co, false, errorMsg); + end); +end; + +function _asyncExecution.resume(co, ...) + local retData = table.pack(coroutine.resume(co, ...)); + + if not retData[1] then + Log.e("Async.execute", "coroutine execution failure: " .. tostring(retData[2])); + else + if retData[2] == _ASYNC_EXEC_IDLE_COROUTINE_RET then + _asyncExecution.releaseIdleCoroutine(co); + elseif retData[2] == _ASYNC_EXEC_AWAIT_CO_RET then + local r, errorMessage = pcall(_asyncExecution.__asyncExecAwaitPromise, co, retData[3]); + + if not r then + _asyncExecution.resume(co, false, errorMessage); + end; + elseif coroutine.status(co) == "dead" then + Log.e("Async.execute", "Coroutine died before expected"); + else + Log.e("Async.execute", "Unhandled coroutine.yield case: " .. tostring(retData[2])); + end; + end; +end; + +function _asyncExecution.entrypoint(mustExecute, fn, arguments, promiseResolution) + while mustExecute do + local ret = table.pack(pcall(fn, table.unpack(arguments))); + + if ret[1] then + promiseResolution:setSuccess(table.unpack(ret, 2)); + else + promiseResolution:setFailure(ret[2]); + Log.w("Async.execute", tostring(ret[2])); + require("dialogs.lua").showErrorMessage(ret[2]); + end; + + fn, arguments, promiseResolution, ret = nil, nil, nil, nil; + + -- fn, arguments, promiseResolution and ret are used below as parameter just to avoid rdk command line linter warning + mustExecute, fn, arguments, promiseResolution = coroutine.yield(_ASYNC_EXEC_IDLE_COROUTINE_RET, fn and arguments and promiseResolution and ret); + end; +end; + +function _asyncExecution.createIdleCoroutine() + return coroutine.create(_asyncExecution.entrypoint); +end; + +function _asyncExecution.acquireIdleCoroutine() + if _asyncExecution.idleCoroutinesCount > 0 then + local co = _asyncExecution.idleCoroutines[_asyncExecution.idleCoroutinesCount]; + _asyncExecution.idleCoroutinesCount = _asyncExecution.idleCoroutinesCount - 1; + return co; + else + return _asyncExecution.createIdleCoroutine(); + end; +end; + +function _asyncExecution.releaseIdleCoroutine(co) + if _asyncExecution.idleCoroutinesCount < _asyncExecution.maxIdleCoroutines then + _asyncExecution.idleCoroutinesCount = _asyncExecution.idleCoroutinesCount + 1; + _asyncExecution.idleCoroutines[_asyncExecution.idleCoroutinesCount] = co; + else + coroutine.resume(co, false, nil, nil, nil); + end; +end; + +-- Exported API to the Firecast Executable + +function __async_start_execution(fn, ...) + return Async.execute(fn, ...); +end; + +-- Async.Promise public API + +function Promise.resolved(...) + if Async.haveNativeBackendSupport() then + return Promise.wrap(_async_promise_newResolved(...)); + else + return Promise.__newStubSuccessPromise(...); + end; +end; + +function Promise.withError(errorMsg) + if Async.haveNativeBackendSupport() then + return Promise.wrap(_async_promise_newWithException(errorMsg)); + else + return Promise.__newStubFailedPromise(errorMsg); + end; +end; + +function Promise.toResolve() + local promiseHandle, promiseResolutionHandle = _async_promise_newToResolve(); + + local promise = Promise.wrap(promiseHandle); + local promiseResolution = Promise.wrapPromiseResolution(promiseResolutionHandle); + + return promise, promiseResolution; +end; + +function Promise.toHandle(promise, successCallback, failureCallback) + assert(promise ~= nil); + + local outerPromise, outerResolution = Promise.toResolve(); + + promise:thenDo( + function (...) + if successCallback ~= nil then + local ret = table.pack(pcall(successCallback, ...)); + + if ret[1] then + outerResolution:setSuccess(table.unpack(ret, 2)); + else + outerResolution:setFailure(ret[2]); + end; + else + outerResolution:setSuccess(...); + end; + end, + + function (originalErrorMsg) + if failureCallback ~= nil then + local ret = table.pack(pcall(failureCallback, originalErrorMsg)); + + if ret[1] then + outerResolution:setSuccess(table.unpack(ret, 2)); + else + outerResolution:setFailure(ret[2]); + end; + else + outerResolution:setFailure(originalErrorMsg); + end; + end); + + return outerPromise; +end; + +function Promise.isPromise(value) + return (type(value) == "table") and + (value.thenDo ~= nil) and + (value.onError ~= nil) and + (value.await ~= nil); +end; + +function Promise.all(...) + local normalized = {}; + local argsTable = table.pack(...); + + for i = 1, #argsTable, 1 do + local item = argsTable[i]; + + if Promise.isPromise(item) then + normalized[#normalized + 1] = item.handle; + else + for j = 1, #item, 1 do + local subItem = item[j]; + + if Promise.isPromise(subItem) then + normalized[#normalized + 1] = subItem.handle; + end; + end; + end; + end; + + return Promise.wrap(_async_promise_newAll(normalized)); +end; + +-- Async library public API + +function Async.await(promise) + if (coroutine.isyieldable ~= nil) and not coroutine.isyieldable() then + error("Is not possible to await outside a coroutine. Please consider using the Async.execute function"); + end; + + if not Promise.isPromise(promise) then + return promise; + end; + + local ret = table.pack(promise:peek()); + + if ret[1] then + if ret[2] then + if #ret >= 3 then + return table.unpack(ret, 3); + else + return nil; + end; + else + local traceMessage = ret[3] .. "\n" .. debug.traceback(coroutine.running(), nil, 2); + reraise(traceMessage); + end; + end; + + ret = table.pack(coroutine.yield(_ASYNC_EXEC_AWAIT_CO_RET, promise)); + + if ret[1] then + if #ret >= 2 then + return table.unpack(ret, 2); + else + return nil; + end; + else + local traceMessage = ret[2] .. "\n" .. debug.traceback(coroutine.running(), nil, 2); + reraise(traceMessage); + end; +end; + +function Async.pawait(promise) + if (coroutine.isyieldable ~= nil) and not coroutine.isyieldable() then + error("Is not possible to pawait outside a coroutine. Please consider using the Async.execute function"); + end; + + if not Promise.isPromise(promise) then + return true, promise; + end; + + local ret = table.pack(promise:peek()); + + if ret[1] then + return table.unpack(ret, 2); + else + return coroutine.yield(_ASYNC_EXEC_AWAIT_CO_RET, promise); + end; +end; + +function Async.execute(fn, ...) + local co = _asyncExecution.acquireIdleCoroutine(); + local promise, resolution = Async.Promise.pending(); + + _asyncExecution.resume(co, true, fn, table.pack(...), resolution); + + return promise; +end; + +Promise.withException = Promise.withError; +Promise.failed = Promise.withError; +Promise.pending = Promise.toResolve; +Promise.succeeded = Promise.resolved; +Promise.resolve = Promise.resolved; +Promise.reject = Promise.withError; +await = Async.await; +pawait = Async.pawait; + +return Async \ No newline at end of file diff --git a/sdk/audio.lua b/sdk/audio.lua new file mode 100644 index 00000000..7f84d685 --- /dev/null +++ b/sdk/audio.lua @@ -0,0 +1,2 @@ +Audio = require("delayedLoad.dlua").new("audioCore.dlua"); +return Audio; diff --git a/sdk/audioCore.dlua b/sdk/audioCore.dlua new file mode 100644 index 00000000..e42afa46 --- /dev/null +++ b/sdk/audioCore.dlua @@ -0,0 +1,194 @@ +local Async = require("async.lua"); +local Objs = require("rrpgObjs.lua"); + +local audioLib = Objs.objectFromHandle(_obj_newObject("TRRPGAudioLibWrapper")); +assert(audioLib ~= nil); + +if audioLib.props == nil then + audioLib.props = {}; +end; + +-- AudioStream Class wrapper + +function audioLib._newAudioStreamWrapperFromStreamReader(streamReader) + local objHandle = _obj_invokeEx(audioLib.handle, 'CreateAudioStream', streamReader); + return audioLib._newAudioStreamWrapperFromObjectHandle(objHandle); +end; + +function audioLib._newAudioStreamWrapperFromObjectHandle(objHandle) + local stream = Objs.objectFromHandle(objHandle); + stream.props = stream.props or {}; + stream.eves = stream.eves or {}; + + function stream:getLength() + return _obj_invokeEx(self.handle, "GetLengthInSecs"); + end; + + function stream:getPosition() + return _obj_invokeEx(self.handle, "GetPositionInSecs"); + end; + + function stream:setPosition(newPosition) + return _obj_invokeEx(self.handle, "SetPositionInSecs", newPosition); + end; + + function stream:waitEOF() + return Async.Promise.wrap(_obj_invokeEx(self.handle, 'WaitEOF')); + end; + + stream.props["enabled"] = {readProp="Enabled", writeProp="Enabled", tipo="bool"}; + stream.props["eof"] = {readProp="IsEOF", tipo="bool"}; + stream.props["length"] = {getter="getLength", tipo="float"}; + stream.props["position"] = {getter="getPosition", setter="setPosition", tipo="float"}; + stream.props["volume"] = {readProp="Volume", writeProp="Volume", tipo="float"}; + + stream.eves["onEOF"] = ""; + return stream; +end; + +-- AudioTrack Class wrapper + +function audioLib._audioTrackWrapperFromHandle(audioStream, objHandle) + local track = Objs.objectFromHandle(objHandle); + track.props = track.props or {}; + track.eves = track.eves or {}; + + rawset(track, "_attachedStream", audioStream); + + function track:getAudioStream() + return rawget(self, "_attachedStream"); + end; + + function track:remove() + return Async.Promise.wrap(_obj_invokeEx(self.handle, 'AsyncRemoveTrack')); + end; + + function track:waitRemoval() + return Async.Promise.wrap(_obj_invokeEx(self.handle, 'WaitRemoval')); + end; + + track.props["audioStream"] = {getter = "getAudioStream", tipo="table"}; + track.props["removed"] = {readProp = "Removed", tipo="bool"}; + + track.eves["onRemoved"] = ""; + return track; +end; + +function audioLib._newNullAudioTrackWrapper(audioStream) + local track = Objs.newPureLuaObject(); + track.props = {}; + + rawset(track, "audioStream", audioStream); + rawset(track, "removed", true); + + function track:remove() + return Async.Promise.resolved(); + end; + + function track:waitRemoval() + return Async.Promise.resolved(); + end; + + return track; +end; + +-- AudioPlayer Class internal utility + +local function __keepStrongReferenceToTrackUntilRemoved(track) + track:waitRemoval():thenFinally( + function() + track = nil; + end) +end; + +local function __keepStrongReferenceToTrackPromiseUntilRemoved(trackPromise) + trackPromise:thenDo( + function (track) + __keepStrongReferenceToTrackUntilRemoved(track); + end); +end; + +-- AudioPlayer Class wrapper + +function audioLib._audioPlayerWrapperFromHandle(objHandle) + local sa = Objs.objectFromHandle(objHandle); + + function sa:asyncAddTrack(audioStream, params) + local trackHandlePromise = Async.Promise.wrap(_obj_invokeEx(self.handle, 'AsyncCreateAudioTrack', audioStream.handle, params)); + + return trackHandlePromise:thenDo( + function(trackHandle) + return audioLib._audioTrackWrapperFromHandle(audioStream, trackHandle); + end); + end; + + function sa:play(source, volume) + local streamPromise = audioLib.asyncLoadAudioStream(source); + + local trackPromise = streamPromise:thenDo( + function(audioStream) + if type(volume) == "number" then + audioStream.volume = volume; + end; + + local trackPromise = self:asyncAddTrack(audioStream, {autoRemoveOnEOF=true}); + __keepStrongReferenceToTrackPromiseUntilRemoved(trackPromise); + return trackPromise; + end); + + return trackPromise; + end; + + return sa; +end; + +function audioLib._newNullAudioPlayerWrapper(errorMessage) + local sa = Objs.newPureLuaObject(); + + if errorMessage == nil then + errorMessage = "No API Support"; + end; + + function sa:asyncAddTrack(audioStream, params) + return Async.Promise.failed(errorMessage); + end; + + function sa:play(source, volume) + return Async.Promise.failed(errorMessage); + end; + + return sa; +end; + +-- AudioLib public API + +function audioLib.asyncLoadAudioStream(source) + local loadPromise = Async.Promise.wrap(_obj_invokeEx(audioLib.handle, 'AsyncLoadStreamReader', source)); + + return loadPromise:thenDo( + function(streamReader) + return audioLib._newAudioStreamWrapperFromStreamReader(streamReader); + end); +end; + +function audioLib:getDefaultPlayer() + local cachedPlayer = rawget(audioLib, "__cachedDefaultAudioPlayer"); + + if cachedPlayer == nil then + local handle = _obj_invokeEx(self.handle, 'CreateGlobalAudioPlayer'); + cachedPlayer = audioLib._audioPlayerWrapperFromHandle(handle); + + assert(cachedPlayer ~= nil); + rawset(audioLib, "__cachedDefaultAudioPlayer", cachedPlayer); + end; + + return cachedPlayer; +end; + +function audioLib.play(source, volume) + return audioLib.defaultPlayer:play(source, volume); +end; + +audioLib.props["defaultPlayer"] = {getter="getDefaultPlayer", tipo="table"}; + +return audioLib; \ No newline at end of file diff --git a/sdk/btree.dlua b/sdk/btree.dlua new file mode 100644 index 00000000..14b21fcf --- /dev/null +++ b/sdk/btree.dlua @@ -0,0 +1,141 @@ +local BTreeInner = require("btree_private.dlua"); +local BTree = {}; + +local function DEFAULT_BTREE_COMPARER(left, right) + if left < right then + return -1; + elseif left > right then + return 1; + else + return 0; + end; +end; + +function BTree.new(theComparer) + local bt = {}; + + -- Atributos privados + bt.comparer = theComparer or DEFAULT_BTREE_COMPARER; + bt.raiz = nil; + bt.count = 0; + + local comparer = bt.comparer; + + -- métodos privados + + for k, v in pairs(BTreeInner) do + bt[k] = v; + end; + + -- Funções Públicas + + function bt:inserir(chave, valor) + if self.raiz == nil then + self.raiz = self:alocarPagina(); + end; + + local inserirEm, indiceInserir = self:innerLocalizarForInsert(self.raiz, chave); + + if inserirEm == nil then + error("InnerLocalizarForInsert retornou nil"); + end; + + if (indiceInserir <= inserirEm.countChaves) and (comparer(inserirEm.chaves[indiceInserir].valorChave, chave) == 0) then + error("Esta chave já existe"); + end; + + self:innerInsertCollated(inserirEm, indiceInserir, chave, valor); + end; + + function bt:alterar(chave, valor) + local pEncontrado, indice = self:innerLocateCollated(self.raiz, chave); + + if pEncontrado ~= nil then + pEncontrado.chaves[indice].valor = valor; + else + error("Esta chave não existe para que seu valor seja alterado"); + end; + end; + + function bt:inserirOuAlterar(chave, valor) + + if self.raiz == nil then + self.raiz = self:alocarPagina(); + end; + + local inserirEm, indiceInserir = self:innerLocalizarForInsert(self.raiz, chave); + + if inserirEm == nil then + error("InnerLocalizarForInsert retornou nil"); + end; + + if (indiceInserir <= inserirEm.countChaves) and (comparer(inserirEm.chaves[indiceInserir].valorChave, chave) == 0) then + inserirEm.chaves[indiceInserir].valor = valor; + else + self:innerInsertCollated(inserirEm, indiceInserir, chave, valor); + end; + end; + + function bt:remover(chave) + local pEncontrado, indice = self:innerLocateCollated(self.raiz, chave); + + if pEncontrado ~= nil then + pEncontrado.chaves[indice].valorChave = nil; + pEncontrado.chaves[indice].valor = nil; + self:innerDelete(pEncontrado, indice); + self.count = self.count - 1; + end; + end; + + function bt:limpar() + self.raiz = nil; + self.count = 0; + end; + + function bt:existe(chave) + local pEncontrado = self:innerLocateCollated(self.raiz, chave); + return (pEncontrado ~= nil); + end; + + function bt:tryGet(chave) + local pEncontrado, indice = self:innerLocateCollated(self.raiz, chave); + + if pEncontrado ~= nil then + return true, pEncontrado.chaves[indice].valor; + else + return false, nil; + end; + end; + + function bt:menorChave() + if self.root == nil then + return nil; + end; + + local pEncontrada, indice = self:innerFindLowest(self.raiz); + + if pEncontrada ~= nil then + return pEncontrada.chaves[indice].valorChave, pEncontrada.chaves[indice].valor; + end; + end; + + function bt:maiorChave() + if self.root == nil then + return nil; + end; + + local pEncontrada, indice = self:innerFindHighest(self.raiz); + + if pEncontrada ~= nil then + return pEncontrada.chaves[indice].valorChave, pEncontrada.chaves[indice].valor; + end; + end; + + function bt:navigator() + return self:createNavigator(); + end; + + return bt; +end; + +return BTree; \ No newline at end of file diff --git a/sdk/btree_private.dlua b/sdk/btree_private.dlua new file mode 100644 index 00000000..c91c3cbb --- /dev/null +++ b/sdk/btree_private.dlua @@ -0,0 +1,849 @@ +local BTreeIN = {}; + +local ARV_GRAU = 4; +local MAX_CHAVES = (ARV_GRAU * 2) - 1; +local MAX_FILHOS = (ARV_GRAU * 2); + +local MIN_CHAVES = ARV_GRAU - 1; + + +-- Funções privadas + +local function pagina_setCountChaves(pagina, count) + if count < pagina.countChaves then + for i = count + 1, pagina.countChaves, 1 do + pagina.chaves[i].valorChave = nil; + pagina.chaves[i].valor = nil; + end; + end; + + pagina.countChaves = count; +end; + +function BTreeIN:alocarPagina() + local pagina = {countChaves=0, filhos={}, pai=nil, indiceNoPai=1}; + local chaves = {}; + + for i = 1, MAX_CHAVES, 1 do + chaves[i] = {valorChave = nil, valor = nil}; + end; + + pagina.chaves = chaves; + return pagina; +end; + + +function BTreeIN:innerLocalizarForInsert(paginaOrigem, chaveALocalizar) + local comp, pOrg, min, max, meio; + + pOrg = paginaOrigem; + + while pOrg ~= nil do + min = 1; + max = pOrg.countChaves; + + while min <= max do + meio = math.ceil((min + max) / 2); + comp = self.comparer(chaveALocalizar, pOrg.chaves[meio].valorChave); + + if comp == 0 then + return pOrg, meio; + elseif comp < 0 then + max = meio - 1; + else + min = meio + 1; + end; + end; + + if pOrg.filhos[min] ~= nil then + pOrg = pOrg.filhos[min]; + else + return pOrg, min; + end; + end; + + return nil, -1; +end; + +function BTreeIN:innerAlocarEspaco(pagina, indiceEspaco) + local mediana, indiceNoPai, countToLeft, countToRight, countSemMediana, qtRetirado; + local novoIrmaoEsq, oPai; + + if pagina.countChaves >= MAX_CHAVES then + -- Vamos precisar dividir a página em 2 páginas. + mediana = math.ceil(pagina.countChaves / 2); + oPai = pagina.pai; + + if oPai == nil then + -- Estamos na raiz; + oPai = self:alocarPagina(); + self.raiz = oPai; + end; + + indiceNoPai = pagina.indiceNoPai; + + -- Subir Mediana + oPai, indiceNoPai = self:innerAlocarEspaco(oPai, indiceNoPai); + oPai.chaves[indiceNoPai].valorChave = pagina.chaves[mediana].valorChave; + oPai.chaves[indiceNoPai].valor = pagina.chaves[mediana].valor; + + novoIrmaoEsq = self:alocarPagina(); + + -- Copiar as chaves que estão antes da mediana para o novo irmão da esquerda + + countSemMediana = pagina.countChaves - 1; + countToLeft = math.ceil(countSemMediana / 2); + countToRight = countSemMediana - countToLeft; + qtRetirado = pagina.countChaves - countToRight; + + for i = 1, countToLeft, 1 do + novoIrmaoEsq.chaves[i].valorChave = pagina.chaves[i].valorChave; + novoIrmaoEsq.chaves[i].valor = pagina.chaves[i].valor; + end; + + for i = 1, countToLeft + 1, 1 do + novoIrmaoEsq.filhos[i] = pagina.filhos[i]; + + if novoIrmaoEsq.filhos[i] ~= nil then + novoIrmaoEsq.filhos[i].pai = novoIrmaoEsq; + end; + end; + + -- Reduzir o tamanho da Direita + + for i = 1, countToRight, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + qtRetirado].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + qtRetirado].valor; + end; + + for i = 1, countToRight + 1, 1 do + pagina.filhos[i] = pagina.filhos[i + qtRetirado]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + for i = countToRight + 2, MAX_FILHOS, 1 do + pagina.filhos[i] = nil; + end; + + pagina_setCountChaves(novoIrmaoEsq, countToLeft); + pagina_setCountChaves(pagina, countToRight); + + -- Ligar os pontos no OPai + oPai.filhos[indiceNoPai] = novoIrmaoEsq; + oPai.filhos[indiceNoPai + 1] = pagina; + + novoIrmaoEsq.pai = oPai; + novoIrmaoEsq.indiceNoPai = indiceNoPai; + + pagina.pai = oPai; + pagina.indiceNoPai = indiceNoPai + 1; + + if indiceEspaco > mediana then + indiceEspaco = indiceEspaco - qtRetirado; + else + pagina = novoIrmaoEsq; + end; + end; + + for i = pagina.countChaves + 1, indiceEspaco + 1, -1 do + pagina.chaves[i].valorChave = pagina.chaves[i - 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i - 1].valor; + end; + + for i = pagina.countChaves + 2, indiceEspaco + 2, -1 do + pagina.filhos[i] = pagina.filhos[i - 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina.filhos[indiceEspaco + 1] = nil; + pagina_setCountChaves(pagina, pagina.countChaves + 1); + return pagina, indiceEspaco; +end; + +function BTreeIN:innerInsertCollated(inserirEm, indice, chave, valor) + inserirEm, indice = self:innerAlocarEspaco(inserirEm, indice); + inserirEm.chaves[indice].valorChave = chave; + inserirEm.chaves[indice].valor = valor; + self.count = self.count + 1; +end; + +function BTreeIN:innerLocateCollated(paginaOrigem, chaveALocalizar) + local comp, min, max, meio, pOrg; + + pOrg = paginaOrigem; + + while pOrg ~= nil do + min = 1; + max = pOrg.countChaves; + + while min <= max do + meio = math.ceil((min + max) / 2); + comp = self.comparer(chaveALocalizar, pOrg.chaves[meio].valorChave); + + if comp == 0 then + return pOrg, meio; + elseif comp < 0 then + max = meio - 1; + else + min = meio + 1; + end; + end; + + pOrg = pOrg.filhos[min]; + end; + + return nil, nil; +end; + +function BTreeIN:innerFindLowest(pagina) + local pOrg = pagina; + + while (pOrg ~= nil) and (pOrg.countChaves > 0) do + if pOrg.filhos[1] ~= nil then + pOrg = pOrg.filhos[1]; + else + return pOrg, 1; + end; + end; +end; + +function BTreeIN:innerFindHighest(pagina) + local pOrg = pagina; + + while (pOrg ~= nil) and (pOrg.countChaves > 0) do + local ind = pOrg.countChaves; + + if pOrg.filhos[ind + 1] ~= nil then + pOrg = pOrg.filhos[ind + 1]; + else + return pOrg, ind; + end; + end; +end; + +function BTreeIN:destruirPagina(_) + -- faz nada +end; + +function BTreeIN:innerDeletePucharDeCima(pagina, indice) + local retIndice; + local oPai, irmaoEsq, irmaoDir, paginaAux; + local indiceTemp, qtACopiar, tempChave, tempValor; + + oPai = pagina.pai; + retIndice = indice; + + if oPai == nil then + -- Estamos na raiz, não temos irmao nem pai. nao temos de onde puxar + -- Remover a chave + + for i = indice, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + -- Mover os filhos + + for i = indice + 1, pagina.countChaves do + pagina.filhos[i] = pagina.filhos[i + 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(pagina, pagina.countChaves - 1); + return pagina, indice, retIndice; + end; + + if pagina.indiceNoPai > 1 then + irmaoEsq = oPai.filhos[pagina.indiceNoPai - 1]; + else + irmaoEsq = nil; + end; + + if pagina.indiceNoPai < oPai.countChaves + 1 then + irmaoDir = oPai.filhos[pagina.indiceNoPai + 1]; + else + irmaoDir = nil; + end; + + + if (irmaoDir ~= nil) and (irmaoDir.countChaves > MIN_CHAVES) then + -- Vamos pegar uma chave do irmão da direita + -- Remover a chave do indice + + for i = indice, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + for i = indice + 1, pagina.countChaves, 1 do + pagina.filhos[i] = pagina.filhos[i + 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar a chave do pai; + pagina.chaves[pagina.countChaves].valorChave = oPai.chaves[pagina.indiceNoPai].valorChave; + pagina.chaves[pagina.countChaves].valor = oPai.chaves[pagina.indiceNoPai].valor; + + -- Pegar os primeiros filhos do irmão da direita + paginaAux = irmaoDir.filhos[1]; + pagina.filhos[pagina.countChaves + 1] = paginaAux; + + if paginaAux ~= nil then + paginaAux.pai = pagina; + paginaAux.indiceNoPai = pagina.countChaves + 1; + end; + + -- Mover a chave do irmao direita para o pai + + oPai.chaves[pagina.indiceNoPai].valorChave = irmaoDir.chaves[1].valorChave; + oPai.chaves[pagina.indiceNoPai].valor = irmaoDir.chaves[1].valor; + + -- excluir a chave do irmao da direita + + for i = 1, irmaoDir.countChaves - 1, 1 do + irmaoDir.chaves[i].valorChave = irmaoDir.chaves[i + 1].valorChave; + irmaoDir.chaves[i].valor = irmaoDir.chaves[i + 1].valor; + end; + + for i = 1, irmaoDir.countChaves, 1 do + irmaoDir.filhos[i] = irmaoDir.filhos[i + 1]; + + if irmaoDir.filhos[i] ~= nil then + irmaoDir.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(irmaoDir, irmaoDir.countChaves - 1); + return pagina, indice, retIndice; + end; + + if (irmaoEsq ~= nil) and (irmaoEsq.countChaves > MIN_CHAVES) then + -- Não conseguimos negociar com o irmão da direita. Vamos tentar no da esquerda + -- Remover a chave do Indice abrindo espaço no inicio para caber a Chave do Pai + qtACopiar = 1; + + -- Copiar os que estão do lado esquerdo da chave que vai ser apagada + for i = indice + qtACopiar, qtACopiar + 2, -1 do + pagina.chaves[i - 1].valorChave = pagina.chaves[i - qtACopiar - 1].valorChave; + pagina.chaves[i - 1].valor = pagina.chaves[i - qtACopiar - 1].valor; + end; + + for i = indice + qtACopiar, qtACopiar + 1, -1 do + pagina.filhos[i] = pagina.filhos[i - qtACopiar]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar a chave do pai + pagina.chaves[1].valorChave = oPai.chaves[pagina.indiceNoPai - 1].valorChave; + pagina.chaves[1].valor = oPai.chaves[pagina.indiceNoPai - 1].valor; + + -- Pegar os ultimos filhos do irmao da esquerda + paginaAux = irmaoEsq.filhos[irmaoEsq.countChaves + 1]; + pagina.filhos[1] = paginaAux; + + if paginaAux ~= nil then + paginaAux.pai = pagina; + paginaAux.indiceNoPai = 1; + end; + + oPai.chaves[pagina.indiceNoPai - 1].valorChave = irmaoEsq.chaves[irmaoEsq.countChaves].valorChave; + oPai.chaves[pagina.indiceNoPai - 1].valor = irmaoEsq.chaves[irmaoEsq.countChaves].valor; + pagina_setCountChaves(irmaoEsq, irmaoEsq.countChaves - 1); + return pagina, indice, retIndice; + end; + + -- Se chegou aqui, os irmãos não podem doar uma chave. Devemos mesclar + + if irmaoDir ~= nil then + -- Mesclar com o irmão da direita + + -- Obtendo a chave que vai vir de cima + tempChave = oPai.chaves[pagina.indiceNoPai].valorChave; + tempValor = oPai.chaves[pagina.indiceNoPai].valor; + + -- Remover a chave do indice + for i = indice, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + for i = indice + 1, pagina.countChaves, 1 do + pagina.filhos[i] = pagina.filhos[i + 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar uma chave do pai + pagina.chaves[pagina.countChaves].valorChave = tempChave; + pagina.chaves[pagina.countChaves].valor = tempValor; + + -- Copiar as chaves e filhos do irmão + qtACopiar = irmaoDir.countChaves; + + for i = pagina.countChaves + 1, pagina.countChaves + qtACopiar, 1 do + pagina.chaves[i].valorChave = irmaoDir.chaves[i - pagina.countChaves].valorChave; + pagina.chaves[i].valor = irmaoDir.chaves[i - pagina.countChaves].valor; + end; + + for i = pagina.countChaves + 1, pagina.countChaves + qtACopiar + 1, 1 do + pagina.filhos[i] = irmaoDir.filhos[i - pagina.countChaves]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].pai = pagina; + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(pagina, pagina.countChaves + irmaoDir.countChaves); + + if oPai.countChaves > MIN_CHAVES then + -- Remover a chave + + for i = pagina.indiceNoPai, oPai.countChaves - 1, 1 do + oPai.chaves[i].valorChave = oPai.chaves[i + 1].valorChave; + oPai.chaves[i].valor = oPai.chaves[i + 1].valor; + end; + + -- Mover os filhos + + for i = pagina.indiceNoPai + 1, oPai.countChaves, 1 do + oPai.filhos[i] = oPai.filhos[i + 1]; + + if oPai.filhos[i] ~= nil then + oPai.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(oPai, oPai.countChaves - 1); + else + --local novoIndiceNoPai; + --oPai, novoIndiceNoPai = self:innerDeletePucharDeCima(oPai, pagina.indiceNoPai); + --pagina.indiceNoPai = novoIndiceNoPai; + self:innerDeletePucharDeCima(oPai, pagina.indiceNoPai); + + if oPai.countChaves == 0 then + self.raiz = pagina; + pagina.pai = nil; + pagina.indiceNoPai = 1; + self:destruirPagina(oPai); + --oPai = nil; + end; + end; + + self:destruirPagina(irmaoDir); + return pagina, indice, retIndice; + end; + + if irmaoEsq ~= nil then + --self.deveValidar = true; + + -- Mesclar com o irmão da esquerda + tempChave = oPai.chaves[pagina.indiceNoPai - 1].valorChave; + tempValor = oPai.chaves[pagina.indiceNoPai - 1].valor; + + -- Remover a chave do indice abrinco espaco no inicio para caber a chave do pai + chaves do irmao da esquerda + qtACopiar = irmaoEsq.countChaves; + + -- Copiar os que estão do lado direito da chave que vai ser apagada + + for i = pagina.countChaves + qtACopiar, indice + qtACopiar + 1, -1 do + pagina.chaves[i].valorChave = pagina.chaves[i - qtACopiar].valorChave; + pagina.chaves[i].valor = pagina.chaves[i - qtACopiar].valor; + end; + + for i = pagina.countChaves + qtACopiar + 1, indice + qtACopiar + 1, -1 do + pagina.filhos[i] = pagina.filhos[i - qtACopiar]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar os que estão do lado esquerdo da chave que vai ser apagada + for i = indice + qtACopiar, qtACopiar + 2, -1 do + pagina.chaves[i].valorChave = pagina.chaves[i - qtACopiar - 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i - qtACopiar - 1].valor; + end; + + for i = indice + qtACopiar, qtACopiar + 1, -1 do + pagina.filhos[i + 1] = pagina.filhos[i - qtACopiar]; + + if pagina.filhos[i + 1] ~= nil then + pagina.filhos[i + 1].indiceNoPai = i + 1; + end; + end; + + -- Copiar a chave do pai + pagina.chaves[irmaoEsq.countChaves + 1].valorChave = tempChave; + pagina.chaves[irmaoEsq.countChaves + 1].valor = tempValor; + + -- copiar as chaves e filhos do irmão da esquerda + + for i = 1, irmaoEsq.countChaves, 1 do + pagina.chaves[i].valorChave = irmaoEsq.chaves[i].valorChave; + pagina.chaves[i].valor = irmaoEsq.chaves[i].valor; + end; + + for i = 1, irmaoEsq.countChaves + 1, 1 do + pagina.filhos[i] = irmaoEsq.filhos[i]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].pai = pagina; + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(pagina, pagina.countChaves + irmaoEsq.countChaves); + + if oPai.countChaves > MIN_CHAVES then + -- Remover a chave + + for i = pagina.indiceNoPai, oPai.countChaves - 1, 1 do + oPai.chaves[i].valorChave = oPai.chaves[i + 1].valorChave; + oPai.chaves[i].valor = oPai.chaves[i + 1].valor; + end; + + -- Mover os filhos + + for i = pagina.indiceNoPai - 1, oPai.countChaves, 1 do + oPai.filhos[i] = oPai.filhos[i + 1]; + + if oPai.filhos[i] ~= nil then + oPai.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(oPai, oPai.countChaves - 1); + else + indiceTemp = pagina.indiceNoPai - 1; + --oPai, indiceTemp = self:innerDeletePucharDeCima(oPai, indiceTemp); + oPai = self:innerDeletePucharDeCima(oPai, indiceTemp); + + if oPai.countChaves == 0 then + self.raiz = pagina; + pagina.pai = nil; + pagina.indiceNoPai = 1; + self:destruirPagina(oPai); + oPai = nil; + end; + end; + + if oPai ~= nil then + oPai.filhos[irmaoEsq.indiceNoPai] = pagina; + end; + + pagina.indiceNoPai = irmaoEsq.indiceNoPai; + self:destruirPagina(irmaoEsq); + return pagina, indice, retIndice; + end; + + error("Ops, não deveria ter chegado até aqui"); +end; + +function BTreeIN:innerDelete(pagina, indiceEspaco) + local oPai, filhoEsq, filhoDir; + local pagToDelete; + local indiceToDelete; + + oPai = pagina.pai; + + if (pagina.filhos[indiceEspaco] == nil) and (pagina.filhos[indiceEspaco + 1] == nil) then + -- É uma página folha + + if (oPai ~= nil) and (pagina.countChaves <= MIN_CHAVES) then + -- Não é root e vai atingir limite minimo + indiceToDelete = indiceEspaco; + --pagina, indiceToDelete = self:innerDeletePucharDeCima(pagina, indiceToDelete) + self:innerDeletePucharDeCima(pagina, indiceToDelete) + else + for i = indiceEspaco, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + pagina_setCountChaves(pagina, pagina.countChaves - 1); + end; + else + -- Página nó + filhoEsq = pagina.filhos[indiceEspaco]; + filhoDir = pagina.filhos[indiceEspaco + 1]; + + if filhoDir ~= nil then + pagToDelete, indiceToDelete = self:innerFindLowest(filhoDir); + + if pagToDelete ~= nil then + pagina.chaves[indiceEspaco].valorChave = pagToDelete.chaves[indiceToDelete].valorChave; + pagina.chaves[indiceEspaco].valor = pagToDelete.chaves[indiceToDelete].valor; + self:innerDelete(pagToDelete, indiceToDelete); + return; + else + error("Ops"); + end; + end; + + if filhoEsq ~= nil then + pagToDelete, indiceToDelete = self:innerFindHighest(filhoEsq); + + if pagToDelete ~= nil then + pagina.chaves[indiceEspaco].valorChave = pagToDelete.chaves[indiceToDelete].valorChave; + pagina.chaves[indiceEspaco].valor = pagToDelete.chaves[indiceToDelete].valor; + self:innerDelete(pagToDelete, indiceToDelete); + return; + else + error("Ops"); + end; + end; + + error("Ops. Não era para ter chegado ate aqui"); + end; +end; + +function BTreeIN:checarPagina(p, min, max) + local vMin , vMax; + local last = nil; + + for i = 1, p.countChaves, 1 do + if (min ~= nil) and (self.comparer(p.chaves[i].valorChave, min) < 0) then + error("Ops. Existe uma falha na ordem das paginas, min"); + end; + + if (max ~= nil) and (self.comparer(p.chaves[i].valorChave, max) > 0) then + error("Ops. Existe uma falha na ordem das paginas, max"); + end; + + if i > 1 then + if self.comparer(p.chaves[i].valorChave, last) <= 0 then + error("Ops. os numeros de uma página não estão ordenados de forma crescente"); + end; + end; + + last = p.chaves[i].valorChave; + end; + + -- Checar Filhos + + for i = 1, p.countChaves + 1, 1 do + if p.filhos[i] ~= nil then + if i == 1 then + vMax = p.chaves[i].valorChave; + self:checarPagina(p.filhos[i], min, vMax); + elseif i == p.countChaves + 1 then + vMin = p.chaves[i - 1].valorChave; + self:checarPagina(p.filhos[i], vMin, max); + else + vMin = p.chaves[i - 1].valorChave; + vMax = p.chaves[i].valorChave; + self:checarPagina(p.filhos[i], vMin, vMax); + end; + end; + end; + + if p.pai ~= nil then + if p.pai.filhos[p.indiceNoPai] ~= p then + error("Indice no pai de uma pagina esta errada"); + end; + end; +end; + +function BTreeIN:validate(errPrefix) + local ok, err = pcall(self.checarPagina, self, self.raiz, nil, nil); + + if not ok then + --error(err .. "\n\n: " .. tableToStr(self.raiz, true)); + error((errPrefix or "") .. err); + end; +end; + + +function BTreeIN.createNavigator(bt) + local nav = {}; + + local fPaginaAtual = nil; + local fIndiceAtual = -1; + local fEof = true; + local fBof = true; + + function nav:first() + local pagina, indice; + local raiz = bt.raiz; + + if raiz ~= nil then + pagina, indice = bt:innerFindLowest(raiz); + end; + + if pagina ~= nil then + fPaginaAtual = pagina; + fIndiceAtual = indice; + fEof = false; + fBof = true; + else + fPaginaAtual = nil; + fIndiceAtual = -1; + fEof = true; + fBof = true; + end; + end; + + function nav:last() + local pagina, indice; + local raiz = bt.raiz; + + if raiz ~= nil then + pagina, indice = bt:innerFindHighest(raiz); + end; + + if pagina ~= nil then + fPaginaAtual = pagina; + fIndiceAtual = indice; + fEof = true; + fBof = false; + else + fPaginaAtual = nil; + fIndiceAtual = -1; + fEof = true; + fBof = true; + end; + end; + + function nav:next() + local pagAtual, pagEncontrada, oPai; + local indAtual, indEncontrado, indPai; + + pagAtual = fPaginaAtual; + indAtual = fIndiceAtual; + + if (pagAtual == nil) or (indAtual == -1) then + fEof = true; + return; + end; + + if pagAtual.filhos[indAtual + 1] ~= nil then + pagEncontrada, indEncontrado = bt:innerFindLowest(pagAtual.filhos[indAtual + 1]); + + fEof = false; + fBof = false; + fPaginaAtual = pagEncontrada; + fIndiceAtual = indEncontrado; + else + if indAtual < pagAtual.countChaves then + fIndiceAtual = fIndiceAtual + 1; + else + -- Já estamos apontando para o último desta página. vamos procurar recursivamente nos pais + oPai = pagAtual.pai; + indPai = pagAtual.indiceNoPai; + + local deveProcurar = true; + + while deveProcurar do + if oPai == nil then + fEof = true; + deveProcurar = false; + else + if indPai <= oPai.countChaves then + fPaginaAtual = oPai; + fIndiceAtual = indPai; + deveProcurar = false; + else + indPai = oPai.indiceNoPai; + oPai = oPai.pai; + end; + end; + end; + end; + end; + end; + + function nav:previous() + local pagAtual, pagEncontrada, oPai; + local indAtual, indEncontrado, indPai; + + pagAtual = fPaginaAtual; + indAtual = fIndiceAtual; + + if (pagAtual == nil) or (indAtual == -1) then + fBof = true; + return; + end; + + if pagAtual.filhos[indAtual] ~= nil then + pagEncontrada, indEncontrado = bt:innerFindHighest(pagAtual.filhos[indAtual]); + + fEof = false; + fBof = false; + fPaginaAtual = pagEncontrada; + fIndiceAtual = indEncontrado; + else + if indAtual > 1 then + fIndiceAtual = fIndiceAtual - 1; + else + -- Já estamos apontando para o último desta página. vamos procurar recursivamente nos pais + oPai = pagAtual.pai; + indPai = pagAtual.indiceNoPai; + + local deveProcurar = true; + + while deveProcurar do + if oPai == nil then + fBof = true; + deveProcurar = false; + else + if indPai > 1 then + fPaginaAtual = oPai; + fIndiceAtual = indPai - 1; + deveProcurar = false; + else + indPai = oPai.indiceNoPai; + oPai = oPai.pai; + end; + end; + end; + end; + end; + end; + + function nav:key() + if fPaginaAtual ~= nil then + return fPaginaAtual.chaves[fIndiceAtual].valorChave; + else + return nil; + end; + end; + + function nav:value() + if fPaginaAtual ~= nil then + return fPaginaAtual.chaves[fIndiceAtual].valor; + else + return nil; + end; + end; + + function nav:eof() + return fEof; + end; + + function nav:bof() + return fBof; + end; + + nav:first(); + return nav; +end; + +return BTreeIN; \ No newline at end of file diff --git a/sdk/delayedLoad.dlua b/sdk/delayedLoad.dlua new file mode 100644 index 00000000..fbd8902d --- /dev/null +++ b/sdk/delayedLoad.dlua @@ -0,0 +1,42 @@ +local dLoadHelper = {}; + +function dLoadHelper.new(moduleName) + local interface = {}; + local moduleObject = nil; + + local metaTable = { + __index = function(table, key) + if moduleObject == nil then + moduleObject = require(moduleName); + end; + + if moduleObject ~= nil then + local r = moduleObject[key]; + + if type(r) == "function" then + rawset(table, key, r); + end; + + return r; + else + return nil; + end; + end, + + __newindex = function(table, key, value) + if moduleObject == nil then + moduleObject = require(moduleName); + end; + + rawset(table, key, value); + end; + }; + + rawset(interface, "__isDelayedLoad", true); + rawset(interface, "__delayedLoadModuleName", moduleName); + + setmetatable(interface, metaTable); + return interface; +end; + +return dLoadHelper; \ No newline at end of file diff --git a/sdk/dialogs.lua b/sdk/dialogs.lua new file mode 100644 index 00000000..2acdf45d --- /dev/null +++ b/sdk/dialogs.lua @@ -0,0 +1 @@ +return require("rrpgDialogs.lua"); \ No newline at end of file diff --git a/sdk/fireDrive.lua b/sdk/fireDrive.lua new file mode 100644 index 00000000..77c93b17 --- /dev/null +++ b/sdk/fireDrive.lua @@ -0,0 +1,3 @@ +fireDrive = require("delayedLoad.dlua").new("fireDriveCore.dlua"); +FireDrive = fireDrive; +return fireDrive; diff --git a/sdk/fireDriveCore.dlua b/sdk/fireDriveCore.dlua new file mode 100644 index 00000000..b63ac244 --- /dev/null +++ b/sdk/fireDriveCore.dlua @@ -0,0 +1,261 @@ +require("rrpg.lua"); +local plugins = require("plugins.lua"); +local fdmodule = "RRPG.FIRECAST.FMXModule"; + +plugins.requirePlugin(fdmodule); + +local fireDrive = {}; + +local _uploads = {}; +local _uploadsIdGenerator = 0; + +local function unsetupUpload(uploadId) + local upload =_uploads[uploadId]; + + if upload ~= nil then + plugins.unlistenPM(upload.pmListenerId); + upload.pmListenerId = nil; + _uploads[uploadId] = nil; + end; +end; + +local function fdManageItem(destName, metadata, onSuccess, onProgress, onFailure) + _uploadsIdGenerator = _uploadsIdGenerator + 1; + local esteId = _uploadsIdGenerator; + local esteUpload = {}; + local msg = {}; + + _uploads[esteId] = esteUpload; + esteUpload.destName = destName; + esteUpload.metadata = metadata; + esteUpload.onSuccess = onSuccess; + esteUpload.onProgress = onProgress; + esteUpload.onFailure = onFailure; + esteUpload.pmListener = "L" .. _rrpg_generateUniqueStrID(); + esteUpload.pmListenerId = plugins.listenPM(esteUpload.pmListener, + function (receivedMsg) + plugins.replyPM(receivedMsg, nil); + + if receivedMsg.kind == "progress" then + if onProgress ~= nil then + onProgress(receivedMsg.currentBytes, receivedMsg.maxBytes); + end; + elseif receivedMsg.kind == "error" then + unsetupUpload(esteId); + + if onFailure ~= nil then + onFailure(receivedMsg.errorMsg); + end; + elseif receivedMsg.kind == "end" then + unsetupUpload(esteId); + + if onSuccess ~= nil then + onSuccess(receivedMsg.successData); + end; + elseif receivedMsg.kind == "uploadId" then + esteUpload.remoteUploadId = receivedMsg.uploadId; + end; + end); + + msg.destName = destName; + msg.metadata = metadata; + msg.uploadId = esteId; + msg.pmListener = esteUpload.pmListener; + + plugins.sendPM(fdmodule, "fireDrive:manageItem", msg, + function (_) + + end, + + function (r) + if onFailure ~= nil then + unsetupUpload(esteId); + onFailure(r); + end; + end); + + return esteId; +end; + +local function tryGetMimeFromFileName(fileName) + local ext = string.match(fileName, "%.[^%.\\/]+$"); + + if ext ~= nil then + local r, mime = _util_tryGetMimeFromExtension(ext); + + if r then + return mime; + else + return 'application/octet-stream'; + end; + else + return 'application/octet-stream'; + end; +end; + +local function fdExecuteUpload(params) + if type(params) ~= "table" then + error("fdExecuteUpload - params was not informed"); + end; + + if type(params.stream) ~= "table" then + error("fireDrive upload - stream was not informed"); + end; + + local metadata = {}; + params.stream.position = 0; + + if params.stream.size > 128 * 1024 * 1024 then + if params.onFailure then + params.onFailure("FILE TOO BIG"); + end; + + return nil; + end; + + metadata.headers = {}; + + if params.isQuickUpload then + params.destName = params.suggestedFileName; + metadata.headers.operation = "quickUpload"; + else + metadata.headers.operation = "create"; + metadata.headers.kind = "file"; + end; + + metadata.blobs = {}; + metadata.blobs[1] = {name="content", streamSharedId = params.stream:share(), mimeType = params.mimeType or tryGetMimeFromFileName(params.destName)}; + + if params.isQuickUpload and not _util_isValidMimeType(metadata.blobs[1].mimeType) then + error("INVALID MIME TYPE: " .. tostring(metadata.blobs[1].mimeType)); + end; + + local ret = fdManageItem(params.destName, metadata, params.onSuccess, params.onProgress, params.onFailure); + metadata.blobs[1].data = nil; + return ret; +end; + +function fireDrive.uploadFile(destName, stream, onSuccess, onProgress, onFailure, mimeType) + local params = {}; + params.destName = destName; + params.stream = stream; + params.onSuccess = onSuccess; + params.onProgress = onProgress; + params.onFailure = onFailure; + params.mimeType = mimeType; + + return fdExecuteUpload(params); +end; + +function fireDrive.upload(...) + return fireDrive.uploadFile(...); +end; + +function fireDrive.quickUpload(suggestedFileName, mimeType, stream, onSuccess, onProgress, onFailure) + local params = {}; + params.stream = stream; + params.onSuccess = onSuccess; + params.onProgress = onProgress; + params.onFailure = onFailure; + params.mimeType = mimeType; + params.isQuickUpload = true; + params.suggestedFileName = suggestedFileName; + + return fdExecuteUpload(params); +end; + +function fireDrive.abortOperation(operationId) + local upload = _uploads[operationId]; + + if upload ~= nil then + plugins.sendPM(fdmodule, "fireDrive:abortOperation", {uploadId = upload.remoteUploadId}); + end; + + unsetupUpload(operationId); +end; + +function fireDrive.createDirectory(directoryName, onSuccess, onFailure) + local metadata = {}; + metadata.headers = {}; + metadata.headers.operation = "create"; + metadata.headers.kind = "directory"; + + return fdManageItem(directoryName, metadata, onSuccess, nil, onFailure); +end; + +function fireDrive.delete(destName, onSuccess, onFailure) + local metadata = {}; + metadata.headers = {}; + metadata.headers.operation = "delete"; + return fdManageItem(destName, metadata, onSuccess, nil, onFailure); +end; + +function fireDrive.rename(existingFileName, newFileName, onSuccess, onFailure) + local metadata = {}; + metadata.headers = {}; + metadata.headers.operation = "rename"; + metadata.headers.newFileName = newFileName; + return fdManageItem(existingFileName, metadata, onSuccess, nil, onFailure); +end; + +function fireDrive.getFiles(directory, callback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:enumerateFiles", {dir=directory}, + function(r) + if callback ~= nil then + callback(r); + end; + end, + + function(r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +function fireDrive.refresh(refreshCallback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:refresh", nil, + function (r) + if refreshCallback ~= nil then + refreshCallback(r); + end; + end, + + function (r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +function fireDrive.getFileInfo(fileName, callback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:getFileInfo", {fileName=fileName}, + function (r) + if callback ~= nil then + callback(r); + end; + end, + + function (r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +function fireDrive.getSpaceInfo(callback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:getSpaceInfo", nil, + function (r) + if callback ~= nil then + callback(r); + end; + end, + + function (r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +return fireDrive; \ No newline at end of file diff --git a/sdk/firecast.lua b/sdk/firecast.lua new file mode 100644 index 00000000..1a3a8b17 --- /dev/null +++ b/sdk/firecast.lua @@ -0,0 +1 @@ +return require('rrpg.lua'); \ No newline at end of file diff --git a/sdk/gui.lua b/sdk/gui.lua new file mode 100644 index 00000000..60ae87f6 --- /dev/null +++ b/sdk/gui.lua @@ -0,0 +1 @@ +return require("rrpgGUI.lua"); \ No newline at end of file diff --git a/sdk/internet.lua b/sdk/internet.lua new file mode 100644 index 00000000..05ae4b0f --- /dev/null +++ b/sdk/internet.lua @@ -0,0 +1,3 @@ +internet = require("delayedLoad.dlua").new("internetCore.dlua"); +Internet = internet; +return internet; diff --git a/sdk/internetCore.dlua b/sdk/internetCore.dlua new file mode 100644 index 00000000..0a3811d8 --- /dev/null +++ b/sdk/internetCore.dlua @@ -0,0 +1,188 @@ +local objs = require("rrpgObjs.lua"); +local utils = require("rrpgUtil.lua"); +local Async = require("async.lua"); + +local lInternet = {}; +local _downloadIdGenerator = 1; +local _downloads = {}; +local internet = lInternet; + +function internet.asyncDownload(url, cacheMode, progressCallback) + local promise, resolution = Async.Promise.pending(); + assert((promise ~= nil) and (resolution ~= nil)); + + internet.download(url, + function (stream, contentType) + assert(resolution ~= nil); + assert(stream ~= nil); + + resolution:setSuccess(stream, contentType); + end, + function (errorMessage) + assert(resolution ~= nil); + resolution:setFailure(errorMessage); + end, + progressCallback, + cacheMode); + + return promise; +end; + +function internet.download(url, finishCallback, errorCallback, progressCallback, cacheMode) + local urlGetter = objs.objectFromHandle(_obj_newObject("TLuaURLGetter")); + + _downloadIdGenerator = _downloadIdGenerator + 1; + local idDownload = _downloadIdGenerator; + + objs.registerHandle(urlGetter.handle, urlGetter); + + urlGetter:addEventListener("OnDados", + function(streamObjectHandle, contentType) + _downloads[idDownload] = nil; + local stream = utils.streamFromHandle(streamObjectHandle); + + if finishCallback ~= nil then + finishCallback(stream, contentType); + end; + end); + + urlGetter:addEventListener("OnError", + function(errorMsg) + _downloads[idDownload] = nil; + + if errorCallback ~= nil then + errorCallback(errorMsg); + end; + end); + + urlGetter:addEventListener("OnProgress", + function(downloadedBytes, totalBytes) + + if progressCallback ~= nil then + local ret = progressCallback(downloadedBytes, totalBytes); + + if ret == false then + internet.stopDownload(idDownload); + end; + end; + end); + + if type(cacheMode) == "string" then + _obj_setProp(urlGetter.handle, "CacheMode", cacheMode); + end; + + _downloads[idDownload] = urlGetter; + _obj_invoke(urlGetter.handle, "StartDownload", url); + return idDownload; +end; + +function internet.stopDownload(downloadId) + local urlGetter = _downloads[downloadId]; + + if urlGetter ~= nil then + _obj_invoke(urlGetter.handle, "StopDownload"); + end; +end; + +local __requestsStrongReference = {}; + +function internet.newHTTPRequest(method, url) + local r = objs.objectFromHandle(_obj_newObject("TLuaHTTPRequest")); + objs.registerHandle(r.handle, r); + + if r.props == nil then + r.props = {}; + end; + + if r.eves == nil then + r.eves = {}; + end; + + if type(method) ~= "string" then + method = "GET"; + end; + + function r:getUrl() return _obj_getProp(self.handle, "URL"); end; + function r:setUrl(v) _obj_setProp(self.handle, "URL", v); end; + + function r:getMethod() return _obj_getProp(self.handle, "HTTPMethod"); end; + function r:setMethod(v) _obj_setProp(self.handle, "HTTPMethod", v); end; + + function r:setRequestHeader(header, value) _obj_invoke(self.handle, "SetRequestHeader", header, tostring(value or "")); end; + function r:getRequestHeader(header) return _obj_invoke(self.handle, "GetRequestHeader", header); end; + + function r:getResponseHeader(header) return _obj_invoke(self.handle, "GetResponseHeader", header); end; + function r:getAllResponseHeaders() return _obj_invoke(self.handle, "GetAllResponseHeaders"); end; + function r:getResponseText() return _obj_getProp(self.handle, "ResponseText"); end; + function r:getResponseStream() return utils.streamFromHandle(_obj_invokeEx(self.handle, "GetResponseStreamHandle")); end; + function r:getStatus() return _obj_getProp(self.handle, "Status"); end; + function r:getStatusText() return _obj_getProp(self.handle, "StatusText"); end; + + function r:open(openMethod, openURL) + self.method = openMethod; + self.url = openURL; + end; + + function r:send(body) + __requestsStrongReference[self] = true; -- manter uma referência forte ate o fim da requisicao + local tBody = type(body); + + if tBody == "table" then + if body.handle == nil then + body = tableToStr(body); + end; + elseif body ~= nil then + body = tostring(body); + end; + + if self.__refResponseEventId == nil then + self.__refResponseEventId = self:addEventListener("onResponse", + function() + __requestsStrongReference[self] = nil; -- Remover referencia forte + end); + end; + + if self.__refOnErrorEventId == nil then + self.__refOnErrorEventId = self:addEventListener("onError", + function() + __requestsStrongReference[self] = nil; -- Remover referencia forte + end); + end; + + _obj_invokeEx(self.handle, "Send", body); + end; + + function r:abort() _obj_invoke(self.handle, "Abort"); end; + + r.props["url"] = {setter = "setUrl", getter = "getUrl", tipo = "string"}; + r.props["method"] = {setter = "setMethod", getter = "getMethod", tipo = "string"}; + + r.props["responseText"] = {getter = "getResponseText", tipo = "string"}; + r.props["responseStream"] = {getter = "getResponseStream", tipo = "table"}; + r.props["status"] = {getter = "getStatus", tipo = "int"}; + r.props["statusText"] = {getter = "getStatusText", tipo = "string"}; + r.props["allResponseHeaders"] = {getter = "getAllResponseHeaders", tipo = "string"}; + + r.eves["onError"] = "errorMsg"; + r.eves["onResponse"] = ""; + r.eves["onSendProgress"] = "currentBytes, maxBytes"; + r.eves["onReceiveProgress"] = "currentBytes, maxBytes"; + + r.method = method; + + if url ~= nil then + r.url = url; + end; + + return r; +end; + +function internet.httpEncode(str) + return _internet_HTTPEncode(str); +end; + +function internet.httpDecode(str) + return _internet_HTTPDecode(str); +end; + +return lInternet; \ No newline at end of file diff --git a/sdk/locale.lua b/sdk/locale.lua new file mode 100644 index 00000000..d4afe9ae --- /dev/null +++ b/sdk/locale.lua @@ -0,0 +1,19 @@ +Locale = require("delayedLoad.dlua").new("localeCore.dlua"); + +function LANG(idTxt) + return Locale.lang(idTxt); +end + +function lang(idTxt) + return Locale.lang(idTxt); +end + +function tryLang(idTxt) + return Locale.tryLang(idTxt); +end + +function tryLANG(idTxt) + return Locale.tryLang(idTxt); +end + +return Locale; diff --git a/sdk/localeCore.dlua b/sdk/localeCore.dlua new file mode 100644 index 00000000..cbba73cc --- /dev/null +++ b/sdk/localeCore.dlua @@ -0,0 +1,99 @@ +local Objs = require("rrpgObjs.lua"); +local Locale = {}; + +function Locale.lang(txtId) + return _system_locale_lang(txtId); +end; + +function Locale.tryLang(txtId) + return _system_locale_tryLang(txtId); +end; + +function Locale.loadLangTexts(langTexts) + return _system_locale_loadLangTexts(langTexts); +end; + +function Locale.withDesiredAutoEval(callback, desiredEnabled, ...) + assert(type(callback) == 'function', "callback parameter is not a function"); + + local wasAutoEvalEnabled = Locale.getIsAutoStringEvalEnabled(); + Locale.setIsAutoStringEvalEnabled(desiredEnabled); + + local r = table.pack(pcall(callback, ...)); + + Locale.setIsAutoStringEvalEnabled(wasAutoEvalEnabled); + + if not r[1] then + reraise(r[2]); + else + return table.unpack(r, 2); + end; +end + +function Locale.withEval(callback, ...) + return Locale.withDesiredAutoEval(callback, true, ...); +end; + +function Locale.withNoEval(callback, ...) + return Locale.withDesiredAutoEval(callback, false, ...); +end; + +function Locale.getIsAutoStringEvalEnabled() + return _system_locale_getCurrentThreadAutomaticLocalizedStringEvaluation(); +end; + +function Locale.setIsAutoStringEvalEnabled(enabled) + return _system_locale_setCurrentThreadAutomaticLocalizedStringEvaluation(not not enabled); +end; + +function Locale.eval(...) + return _system_locale_eval(...); +end; + +function Locale.autoEval(...) + return _system_locale_autoEval(...); +end; + +function Locale.__createNullLocalizedTexts() + local nullTxts = {}; + + function nullTxts:lang(textId) + error("No API Support"); + end; + + function nullTxts:tryLang(textId) + return nil; + end; + + function nullTxts:loadTexts(langTexts) + end; + + function nullTxts:addText(localeId, textId, text) + end; + + return nullTxts; +end; + +function Locale.newLocalizedTexts() + local txts = Objs.objectFromHandle(_obj_newObject("TLuaLocalizedTexts")); + + function txts:addText(localeId, textId, text) + return _obj_invokeEx(self.handle, "AddText", localeId, textId, text); + end; + + function txts:lang(textId) + return _obj_invokeEx(self.handle, "Lang", textId); + end; + + function txts:loadTexts(langTexts) + return _obj_invokeEx(self.handle, "LoadTexts", langTexts); + end; + + function txts:tryLang(textId) + return _obj_invokeEx(self.handle, "TryLang", textId); + end; + + return txts; +end; + +return Locale; \ No newline at end of file diff --git a/sdk/log.lua b/sdk/log.lua new file mode 100644 index 00000000..35d31848 --- /dev/null +++ b/sdk/log.lua @@ -0,0 +1,39 @@ +require("system.lua"); + +Log = {} + +function Log.haveNativeBackendSupport() + return System.checkAPIVersion(87, 3) +end; + +function Log.v(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_v(tag, msg); + end; +end; + +function Log.d(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_d(tag, msg); + end; +end; + +function Log.i(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_i(tag, msg); + end; +end; + +function Log.w(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_w(tag, msg); + end; +end; + +function Log.e(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_e(tag, msg); + end; +end; + +return Log \ No newline at end of file diff --git a/sdk/ndb.lua b/sdk/ndb.lua new file mode 100644 index 00000000..a292e42f --- /dev/null +++ b/sdk/ndb.lua @@ -0,0 +1,929 @@ +local objs = require("rrpgObjs.lua"); +local vhd = require("vhd"); +require("utils.lua"); +ndb = {} +NDB = ndb; + +local localNDB = {}; + +local _localOpenNDBs = {} +setmetatable(_localOpenNDBs, objs.weakMetatable); + +function localNDB.ndbFromHandle(handle) + local ctrl; + + if handle ~= nil then + ctrl = objs.tryFindFromHandle(handle); + + if ctrl ~= nil then + return ctrl; + end; + else + return nil; + end; + + ctrl = objs.objectFromHandle(handle); + ctrl.__dbFlag = true; + + objs.registerHandle(handle, ctrl); + return ctrl; +end; + +-- [[ Node class ]] -- + +localNDB.Node = objs.newClass(); + +function localNDB.Node:initialize() + rawset(self, "__nodeFlag", true); +end; + +function localNDB.Node:findChild(nodeName) + local nh = _ndb_findChild(self.handle, nodeName); + return localNDB.openNode(nh); +end; + +function localNDB.Node:getFacade() + local nodeFacade = rawget(self, "__nodeFacade"); + + if nodeFacade == nil then + nodeFacade = localNDB.newNodeFacadeFor(self); + rawset(self, "__nodeFacade", nodeFacade); + end; + + return nodeFacade; +end; + +function localNDB.Node:getAttribute(name) + return _ndb_getAttribute(self.handle, name); +end; + +function localNDB.Node:setAttribute(name, value) + return _ndb_setAttribute(self.handle, name, value); +end; + +function localNDB.Node:clearNode() + return _obj_invoke(self.handle, "ClearNode"); +end; + +function localNDB.Node:getAttributesNames() + return _ndb_getAttributesNames(self.handle); +end; + +function localNDB.Node:getAllAttributes() + return _ndb_getAllAttributes(self.handle); +end; + +function localNDB.Node:getChildCount() + return _ndb_getChildCount(self.handle); +end; + +function localNDB.Node:getChild(indice) + return localNDB.openNode(_ndb_getChild(self.handle, indice)); +end; + +function localNDB.Node:getAllChilds() + local ret = {}; + local count = self:getChildCount(); + + for i = 0, count - 1, 1 do + ret[i + 1] = self:getChild(i); + end; + + return ret; +end; + +function localNDB.Node:addChild(nodeName) + return localNDB.openNode(_ndb_addChild(self.handle, nodeName)); +end; + +function localNDB.Node:delete() + _obj_invoke(self.handle, "Delete"); +end; + +function localNDB.Node:getName() + return _ndb_getNodeName(self.handle); +end; + +function localNDB.Node:getPersistedAttributeValue(attributeName) + return _ndb_getPersistedAttributeValue(self.handle, attributeName); +end; + +function localNDB.Node:exportXML() + return _obj_invoke(self.handle, "ExportToXMLString"); +end; + +function localNDB.Node:importXML(xmlString) + return _obj_invoke(self.handle, "ImportXMLString", (tostring(xmlString)) or ""); +end; + +function localNDB.Node:getLocalID() + return _obj_getProp(self.handle, "LocalID"); +end; + +function localNDB.Node:beginUpdate() + _obj_invoke(self.handle, "BeginUpdate"); +end; + +function localNDB.Node:endUpdate() + _obj_invoke(self.handle, "EndUpdate"); +end; + +function localNDB.Node:getState() + return _obj_getProp(self.handle, "ProviderState"); +end; + +function localNDB.Node:setPermission(selKind, selId, permission, allowance) + return _obj_invokeEx(self.handle, "SetPermission", selKind, selId, permission, allowance); +end; + +function localNDB.Node:getPermission(selKind, selId, permission) + return _obj_invokeEx(self.handle, "GetPermission", selKind, selId, permission); +end; + +function localNDB.Node:testPermission(permission) + return _obj_invokeEx(self.handle, "TestPermission", permission); +end; + +function localNDB.Node:enumPermissions() + return _obj_invokeEx(self.handle, "EnumPermissions"); +end; + +function localNDB.nodeFromHandle(nodeHandle) + local node; + + if nodeHandle == nil then + return nil; + end; + + node = objs.tryFindFromHandle(nodeHandle); + + if node ~= nil then + return node; + end; + + node = localNDB.Node.fromHandle(nodeHandle); + node.__nodeDatabase = localNDB.ndbFromHandle(_ndb_getNDBHandleOfNode(nodeHandle)); + + objs.registerHandle(nodeHandle, node); + return node; +end; + +function localNDB.copyNodeToAnother(nodeDest, nodeSrc, ctxCtrl) + if nodeDest.handle == nodeSrc.handle then + return; + end; + + if ctxCtrl == nil then + ctxCtrl = {}; -- avoid circular reference + end; + + if ctxCtrl[nodeSrc.handle] then + return; + else + ctxCtrl[nodeSrc.handle] = true; + end; + + nodeDest:beginUpdate(); + + tryFinally( + function() + nodeDest:clearNode(); + + local allAtts = nodeSrc:getAllAttributes(); + + for k, v in pairs(allAtts) do + localNDB.assignPropValueToNode(nodeDest, k, v); + end; + + local allChilds = nodeSrc:getAllChilds(); + local newChild, srcChild; + + for _, v in pairs(allChilds) do + srcChild = v; + + if not ctxCtrl[srcChild.handle] then + newChild = nodeDest:addChild(srcChild:getName()); + localNDB.copyNodeToAnother(newChild, srcChild, ctxCtrl); + end; + end; + end, + + function() + nodeDest:endUpdate(); + end); +end; + +function localNDB.copyTableToNode(nodeDest, tableValue) + nodeDest:clearNode(); + + for k, v in pairs(tableValue) do + localNDB.assignPropValueToNode(nodeDest, k, v); + end; +end; + +function localNDB.assignPropValueToNode(node, prop, value) + prop = tostring(prop); + + -- Limpando propriedade + if value == nil then + _obj_invoke(node.handle, "RemoveAtributeAndChildNodes", prop); + return; + end; + + if type(value) == "function" then + -- Tipo inválido para setar + require("locale.lua"); + error(string.format(lang("sdk3.err.ndb.functionAssign"), tostring(prop))); + return; + end; + + if type(value) == "table" then + -- Setando um Table/Child Node + _obj_invoke(node.handle, "BeginUpdate"); + + node:setAttribute(prop, nil); -- remover atributo de mesmo nome se existir + local childNode = node:findChild(prop); + + if childNode == nil then + childNode = node:addChild(prop); -- Nodo não existe, vamos criar um + end; + + if rawget(value, "__nodeFlag") then + -- é um node + localNDB.copyNodeToAnother(childNode, value); + elseif rawget(value, "__nodeFacadeFlag") then + -- é um node facade + localNDB.copyNodeToAnother(childNode, value.__node); + else + -- Aparentemente é um table comum + localNDB.copyTableToNode(childNode, value); + end; + + _obj_invoke(node.handle, "EndUpdate"); + else + -- Setando um Atributo + --_obj_invoke(node.handle, "BeginUpdate"); + _obj_invoke(node.handle, "RemoveChildNodes", prop); -- remover todos os child nodes de mesmo nome + node:setAttribute(prop, value); + --_obj_invoke(node.handle, "EndUpdate"); + end; +end; + +local NodeFacadeMetatable = { + --[[ getter padrão de propriedades dos objetos. Chamado quando tentou gettar uma propriedade que não existe ]]-- + __index = function(table, key) + local v = rawget(table, key); + + if (v ~= nil) then + return v; + end; + + local node = rawget(table, "__node"); + + if node ~= nil then + local childNode = node:findChild(key); + + if childNode ~= nil then + -- Achamos um child node com este nome. + return childNode:getFacade(); + end; + + return node:getAttribute(key); + end; + + return nil; + end, + + --[[ setter padrão de propriedades dos objetos. Chamado quando tentou settar uma propriedade que não existe ]]-- + __newindex = function(table, key, value) + local node = rawget(table, "__node"); + + if node ~= nil then + localNDB.assignPropValueToNode(node, key, value); + end; + end, +}; + +function localNDB.newNodeFacadeFor(nodeObj) + local nodeFacade = {__node = nodeObj, __nodeFacadeFlag = true}; + setmetatable(nodeFacade, NodeFacadeMetatable); + return nodeFacade; +end; + +function localNDB.openNode(nodeHandle) + local nodeObj; + + if nodeHandle == nil then + return nil; + end; + + nodeObj = objs.tryFindFromHandle(nodeHandle); + + if nodeObj == nil then + nodeObj = localNDB.nodeFromHandle(nodeHandle); + end; + + return nodeObj; +end; + +function localNDB.openNodeFacade(nodeHandle) + local nodeObj = localNDB.openNode(nodeHandle); + + if nodeObj ~= nil then + return nodeObj:getFacade(); + else + return nil; + end; +end; + +function localNDB.getNodeObjectFromFacade(nodeFacade) + return rawget(nodeFacade, "__node"); +end; + +function _export_ndb_openNodeFacade(nodeHandle) + return localNDB.openNodeFacade(nodeHandle); +end; + +-- Funções exportadas + +function ndb.openNodeDatabaseFromHandle(nodeDatabaseHandle) + return localNDB.ndbFromHandle(nodeDatabaseHandle); +end; + +function ndb.load(fileName, userName) + local expandedName = vhd.expandFileName(fileName); + + if #expandedName > 0 then + if string.sub(expandedName, 1, 1) ~= "/" then + expandedName = "/" .. expandedName; + end; + end; + + if type(userName) ~= "string" then + userName = ""; + end; + + local openDB = _localOpenNDBs[expandedName]; + + if openDB ~= nil then + return ndb.getRoot(openDB); + end; + + openDB = ndb.openNodeDatabaseFromHandle(_obj_newObject("TLocalLuaNodeDatabase")); + _obj_invoke(openDB.handle, "SetupLocalFile", expandedName, userName); + _localOpenNDBs[expandedName] = openDB; + return ndb.getRoot(openDB); +end; + +function ndb.newMemNodeDatabase(initialContent) + local openDB = ndb.openNodeDatabaseFromHandle(_obj_newObject("TLuaMemoryNodeDatabase", initialContent)); + return ndb.getRoot(openDB); +end; + +function ndb.getRoot(node) + if type(node) ~= "table" then + return nil; + end; + + if node.__nodeFlag then + return localNDB.openNodeFacade(_ndb_getTheRoot(node.handle)); + elseif node.__nodeFacadeFlag then + return ndb.getRoot(rawget(node, "__node")); + elseif node.__dbFlag then + return localNDB.openNodeFacade(_ndb_getRoot(node.handle)); + else + return nil; + end; +end; + +function ndb.getParent(node) + if type(node) ~= "table" then + return nil; + end; + + if node.__nodeFlag then + return localNDB.openNodeFacade(_ndb_getParent(node.handle)); + elseif node.__nodeFacadeFlag then + return ndb.getParent(rawget(node, "__node")); + else + return nil; + end; +end; + +function ndb.openNodeFacade(nodeHandle) + return localNDB.openNodeFacade(nodeHandle); +end; + +function ndb.getChildNodes(nodeObj) + if (nodeObj == nil) then + return {}; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local nodesCtrls = node:getAllChilds(); + local ret = {}; + + for i = 1, #nodesCtrls, 1 do + ret[i] = nodesCtrls[i]:getFacade(); + end; + + return ret; + else + return {}; + end; +end; + +function ndb.getAttributes(nodeObj) + if (nodeObj == nil) then + return {}; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getAllAttributes(); + else + return {}; + end; +end; + +function ndb.isNodeObject(value) + if type(value) ~= "table" then + return false; + end; + + return rawget(value, "__nodeFacadeFlag"); +end; + +function ndb.getNodeHandle(nodeObject) + if ndb.isNodeObject(nodeObject) then + return nodeObject.__node.handle; + else + return nil; + end; +end; + +function ndb.createChildNode(nodeObj, childName) + if (nodeObj == nil) then + return nil; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:addChild(childName):getFacade(); + else + return nil; + end; +end; + +function ndb.deleteNode(nodeObj) + if (nodeObj == nil) then + return; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:delete(); + end; +end; + +function ndb.clearNode(nodeObj) + if (nodeObj == nil) then + return; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:clearNode(); + end; +end; + +function ndb.getNodeName(nodeObj) + if (nodeObj == nil) then + return nil; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getName(); + else + return nil; + end; +end; + +function ndb.getPersistedAttributeValue(nodeObj, attributeName) + if (nodeObj == nil) then + return nil; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getPersistedAttributeValue(attributeName); + else + return nil; + end; +end; + +function ndb.exportXML(nodeObj) + if (nodeObj == nil) then + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.exportToXML.invalidPar")); + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:exportXML(); + else + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.exportToXML.invalidPar")); + end; +end; + +function ndb.importXML(nodeObj, xmlString) + if (nodeObj == nil) then + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.importXML.invalidPar")); + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:importXML(xmlString); + else + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.importXML.invalidPar")); + end; +end; + +function ndb.copy(destNodeObj, srcNodeObj) + if (destNodeObj == nil) then + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.copy.invalidPar2")); + end; + + local srcNode; + local dstNode = localNDB.getNodeObjectFromFacade(destNodeObj); + + if srcNodeObj ~= nil then + srcNode = localNDB.getNodeObjectFromFacade(srcNodeObj); + else + srcNode = nil; + end; + + if dstNode ~= nil then + if srcNode ~= nil then + local xmlString = srcNode:exportXML(); + dstNode:importXML(xmlString); + else + dstNode:clearNode(); + end; + else + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.copy.invalidPar2")); + end; +end; + +function ndb.beginUpdate(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:beginUpdate(); + end; + end; +end; + +function ndb.endUpdate(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:endUpdate(); + end; + end; +end; + +function ndb.getState(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getState(); + end; + end; + + return "closed"; +end; + +local _observerBib = nil; + +function ndb.newObserver(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + if _observerBib == nil then + _observerBib = require("ndb_observer.dlua"); + end; + + return _observerBib.newObserver(node.handle, nodeObj); + end; + end; + + return nil; +end; + +function ndb.setPermission(node, selKind, selId, permission, allowance) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:setPermission(tostring(selKind), tostring(selId), tostring(permission), allowance); + end; + end; +end; + +function ndb.getPermission(node, selKind, selId, permission) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:getPermission(tostring(selKind), tostring(selId), tostring(permission)); + end; + end; + + return nil; +end; + +function ndb.testPermission(node, permission) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:testPermission(tostring(permission)); + end; + end; + + return false; +end; + +function ndb.enumPermissions(node) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:enumPermissions(); + end; + end; + + return {}; +end; + +function ndb.resetPermissions(node) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + _obj_invoke(nodeObj.handle, "ResetPermissions"); + end; + end; + + return {}; +end; + +local _transactionBib = nil; + +function ndb.newTransaction(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + if _transactionBib == nil then + _transactionBib = require("ndb_transaction.dlua"); + end; + + return _transactionBib.newTransaction(node.handle, nodeObj); + end; + end; + + return nil; +end; + +function ndb.pushTransaction(nodeObj, transaction) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local trHandle; + + if transaction ~= nil then + trHandle = transaction.handle or 0; + else + trHandle = 0; + end; + + _obj_invoke(node.handle, "PushTransaction", trHandle); + end; + end; +end; + +function ndb.popTransaction(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + _obj_invoke(node.handle, "PopTransaction"); + end; + end; +end; + +function ndb.getServerUTCTime(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return _obj_getProp(node.handle, "ServerUTCTime"); + end; + end; +end; + +function ndb.editPermissions(nodeObj) + if nodeObj == nil then + return; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local plugins = require("plugins.lua"); + local ndbmodule = "RRPG.FIRECAST.FMXModule"; + plugins.sendPM(ndbmodule, "ndbHost:editPermissions", {localNodeID=node:getLocalID()}, nil, nil); + end; +end; + +function ndb.loadNodeFromLocalID(localNodeID) + return _ndb_tryLoadNodeFromLocalID(localNodeID); +end; + +local _Serializer = nil; + +function ndb.broadcastMessage(nodeObj, messageId, message, loopBack) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + if _Serializer == nil then + _Serializer = require("utils.serializer.dlua"); + end; + + if loopBack == nil then + loopBack = false; + end; + + _obj_invokeEx(node.handle, "LUABroadcastMessage", messageId, _Serializer.serialize(message), loopBack); + end; + end; +end; + +function ndb.newBroadcastListener(nodeObj, messageId, callback) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local obj = objs.objectFromHandle(_obj_newObject("TLuaNDBBroadcastReceiver")); + obj.eves = obj.eves or {}; + obj.eves["onReceiveBroadcast"] = "sender, messageId, messageText"; + + _obj_invoke(obj.handle, "SetupReceiver", node.handle, messageId or ""); + + obj.onReceiveBroadcast = function(sender, returnedMessageId, messageText) + if callback ~= nil then + if _Serializer == nil then + _Serializer = require("utils.serializer.dlua"); + end; + + local success, message = pcall(_Serializer.deserialize, messageText); + + if not success then + message = messageText; + end; + + callback(sender, returnedMessageId, message); + end; + end; + return obj; + end; + end; +end; + +function ndb.onReady(nodeObj, callback, failCallback) + local function scheduleFailReturn() + if failCallback ~= nil then + setTimeout(failCallback, 1, nil); + end; + end; + + if nodeObj == nil then + scheduleFailReturn(); + return; + end; + + local state = ndb.getState(nodeObj); + + if state == "open" then + -- Already loaded + + if callback ~= nil then + setTimeout(callback, 1, nodeObj); + end; + + return; + end; + + -- Not loaded yet, letz monitor + local nodeInternObj = localNDB.getNodeObjectFromFacade(nodeObj); + local ndbObj = localNDB.ndbFromHandle(_ndb_getNDBHandleOfNode(nodeInternObj.handle)); + local jaNotificou = false; + local listenerProvider = nil; + local listenerLoaded = nil; + + local function checkState() + if not jaNotificou then + state = ndb.getState(nodeObj); + + if state == "open" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, nodeObj); + end; + elseif state == "closed" then + jaNotificou = true; + scheduleFailReturn(); + end; + + if jaNotificou then + ndbObj:removeEventListener(listenerProvider); + ndbObj:removeEventListener(listenerLoaded); + end; + end; + end; + + listenerProvider = ndbObj:addEventListener("OnProviderStateChange", checkState); + listenerLoaded = ndbObj:addEventListener("OnLoaded", checkState); + + checkState(); +end; + +-- OVERRIDE de funções nativas para funcionar com o NDB + +local oldPairsFunc = pairs; +local oldIPairsFunc = ipairs; + +local function _prepareNodeFacadePairsState(nodeFacade) + local node = nodeFacade.__node; + local state = node:getAllAttributes(); + + local childs = node:getAllChilds(); + + for _, v in oldPairsFunc(childs) do + local name = v:getName(); + local nodeForName = node:findChild(name); + + if nodeForName ~= nil then + state[name] = nodeForName; + end; + end; + + return state; +end; + +function pairs(obj) + if (obj ~= nil) and rawget(obj, "__nodeFacadeFlag") then + -- Node Façade + local state = _prepareNodeFacadePairsState(obj); + return oldPairsFunc(state); + else + return oldPairsFunc(obj); + end; +end; + +function ipairs(obj) + if (obj ~= nil) and rawget(obj, "__nodeFacadeFlag") then + -- Node Façade + local state = _prepareNodeFacadePairsState(obj); + return oldIPairsFunc(state); + else + return oldIPairsFunc(obj); + end; +end; + +return ndb; \ No newline at end of file diff --git a/sdk/ndb_observer.dlua b/sdk/ndb_observer.dlua new file mode 100644 index 00000000..e7a80b54 --- /dev/null +++ b/sdk/ndb_observer.dlua @@ -0,0 +1,51 @@ +local objs = require("rrpgObjs.lua"); +local nO = {}; + +local _observerProps = {}; +local _observerEves = {}; + +_observerProps["enabled"] = {setter = "setEnabled", getter = "getEnabled", tipo="bool"}; + +_observerEves["onChildAdded"] = "node"; +_observerEves["onChildRemoved"] = "node"; +_observerEves["onDeepChildAdded"] = "node"; +_observerEves["onDeepChildRemoved"] = "node"; +_observerEves["onDeleted"] = "node"; +_observerEves["onChanged"] = "node, attribute, oldValue"; +_observerEves["onDeepChanged"] = "node, attribute, oldValue"; +_observerEves["onUserChanged"] = "node, attribute, oldValue"; +_observerEves["onDeepUserChanged"] = "node, attribute, oldValue"; +_observerEves["onPersistedChanged"] = "node, attribute, oldValue"; +_observerEves["onDeepPersistedChanged"] = "node, attribute, oldValue"; +_observerEves["onPermissionListChanged"] = "node"; +_observerEves["onDeepPermissionListChanged"] = "node"; +_observerEves["onFinalPermissionsCouldBeChanged"] = "node"; +_observerEves["onStateChanged"] = "node"; + +local function _observerFromHandle(handle) + local obj = objs.tryFindFromHandle(handle); + + if obj ~= nil then + return obj; + end; + + obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + + function obj:getEnabled() return _obj_getProp(self.handle, "Enabled"); end; + function obj:setEnabled(v) _obj_setProp(self.handle, "Enabled", v); end; + + + obj.props = _observerProps; + obj.eves = _observerEves; + return obj; +end; + +function nO.newObserver(nodeHandle, nodeObj) + local observer = _observerFromHandle(_obj_newObject("TLuaNodeObserver")); + _obj_invokeEx(observer.handle, "SetNodeHandle", nodeHandle); + rawset(observer, "node", nodeObj); + return observer; +end; + +return nO; \ No newline at end of file diff --git a/sdk/ndb_transaction.dlua b/sdk/ndb_transaction.dlua new file mode 100644 index 00000000..6ea1b512 --- /dev/null +++ b/sdk/ndb_transaction.dlua @@ -0,0 +1,53 @@ +local objs = require("rrpgObjs.lua"); +local nO = {}; + +local _transactionProps = {}; +local _transactionEves = {}; +local _transactionMethods = {}; + +function _transactionMethods.commit(tr) + _obj_invoke(tr.handle, "Commit"); +end; + +function _transactionMethods.rollback(tr) + _obj_invoke(tr.handle, "Rollback"); +end; + +function _transactionMethods.createUndoData(tr) + local handle = _obj_invoke(tr.handle, "CreateUndoData"); + local obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + return obj; +end; + +function _transactionMethods.applyUndoData(tr, undoData) + _obj_invoke(tr.handle, "ApplyUndoData", undoData.handle); +end; + +local function _transactionFromHandle(handle) + local obj = objs.tryFindFromHandle(handle); + + if obj ~= nil then + return obj; + end; + + obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + + for k, v in pairs(_transactionMethods) do + rawset(obj, k, v); + end; + + obj.props = _transactionProps; + obj.eves = _transactionEves; + return obj; +end; + +function nO.newTransaction(nodeHandle, nodeObj) + local transaction = _transactionFromHandle(_obj_newObject("TLuaNodeTransaction")); + _obj_invokeEx(transaction.handle, "InitializeFromNodeHandle", nodeHandle); + rawset(transaction, "node", nodeObj); + return transaction; +end; + +return nO; \ No newline at end of file diff --git a/sdk/plugins.lua b/sdk/plugins.lua new file mode 100644 index 00000000..6c014411 --- /dev/null +++ b/sdk/plugins.lua @@ -0,0 +1,6 @@ +local rrpg = require("rrpg.lua"); +local plugins = require("delayedLoad.dlua").new("pluginsCore.dlua"); + +rrpg.plugins = plugins; +rrpg.Plugins = plugins; +return plugins; diff --git a/sdk/pluginsCore.dlua b/sdk/pluginsCore.dlua new file mode 100644 index 00000000..520efd1e --- /dev/null +++ b/sdk/pluginsCore.dlua @@ -0,0 +1,243 @@ +require("rrpgObjs.lua"); +require("utils.lua"); +require("rrpg.lua"); +local plugins = {}; +local serializer = nil; + +function plugins.getInstalledDataTypes() + local retorno = _rrpg_plugins_getInstalledDataTypes(); + + if type(retorno) == "table" then + return retorno; + else + return {}; + end; +end; + +function plugins.getInstalledPlugins() + local retorno = _rrpg_plugins_getInstalledPlugins(); + + if type(retorno) == "table" then + return retorno; + else + return {}; + end; +end; + +function plugins.getRPKDetails(stream) + if type(stream) == "table" then + return _rrpg_plugins_getPackageInfos(stream.handle); + else + return nil; + end; +end; + +function plugins.installPlugin(stream, ignoreIfOlder) + if type(stream) ~= "table" then + return false, "Invalid stream parameter"; + end; + + ignoreIfOlder = not (not ignoreIfOlder); + return _rrpg_plugins_installPluginPackage(stream.handle, ignoreIfOlder); +end; + +function plugins.uninstallPlugin(moduleId) + return _rrpg_plugins_uninstallPluginPackage(moduleId); +end; + +local pmListenersByName = {}; +local pmGeneratorId = 0; +local pmPrefixID = _rrpg_generateUniqueStrID() .. "_"; +local pmSent = {}; + +local function __convertIncomingPMData(data) + if serializer == nil then + serializer = require("utils.serializer.dlua"); + end; + + return serializer.deserialize(data); +end; + +local function __convertOutgoingPMData(data) + if serializer == nil then + serializer = require("utils.serializer.dlua"); + end; + + return serializer.serialize(data); +end; + +function plugins.sendPM(moduleId, pmName, data, returnCallback, failureCallback) + pmGeneratorId = pmGeneratorId + 1; + local esteId = pmPrefixID .. tostring(pmGeneratorId); + local pmObject = {}; + pmObject.returnCallback = returnCallback; + pmObject.failureCallback = failureCallback; + + --[[if type(data) ~= "table" then + data = {data=data}; + end;]] + + data = __convertOutgoingPMData(data); + pmSent[esteId] = pmObject; + + local ret, msg = _rrpg_plugins_sendPM(esteId, moduleId, pmName, data); + + if not ret then + pmSent[esteId] = nil; + + if failureCallback ~= nil then + failureCallback(msg); + end; + end; +end; + +function plugins.replyPM(message, data) + if not message.__replied then + message.__replied = true; + _rrpg_plugins_sendPMReply(message.__msgId, message.moduleId, true, __convertOutgoingPMData(data)); + end; +end; + +function plugins.replyPMFailure(message, failureData) + if not message.__replied then + message.__replied = true; + _rrpg_plugins_sendPMReply(message.__msgId, message.moduleId, false, __convertOutgoingPMData(failureData)); + end; +end; + +function plugins.setLatePMReply(message) + message.__isLateReply = true; +end; + +function plugins.listenPM(pmName, callback) + local listener = pmListenersByName[pmName]; + + if listener ~= nil then + listener.callback = callback; + return pmName; + end; + + listener = {}; + listener.callback = callback; + listener.pmName = pmName; + pmListenersByName[pmName] = listener; + return pmName; +end; + +function plugins.unlistenPM(listenerId) + local listener = pmListenersByName[listenerId]; -- listenerId é o pmName + + if listener ~= nil then + pmListenersByName[listenerId] = nil; + listener.callback = nil; + end; +end; + +function plugins.requirePlugin(moduleId) + return _rrpg_plugins_requirePlugin(moduleId); +end; + +function __export_plugins_handlePMResponse(msgId, success, data) + local pmObject = pmSent[msgId]; + + if pmObject ~= nil then + pmSent[msgId] = nil; + data = __convertIncomingPMData(data); + + if success then + if pmObject.returnCallback ~= nil then + pmObject.returnCallback(data); + end; + else + if pmObject.failureCallback ~= nil then + pmObject.failureCallback(data); + end; + end; + end; +end; + +function __export_plugins_handlePMResponse(msgId, success, data) + local pmObject = pmSent[msgId]; + + if pmObject ~= nil then + pmSent[msgId] = nil; + data = __convertIncomingPMData(data); + + if success then + if pmObject.returnCallback ~= nil then + pmObject.returnCallback(data); + end; + else + if pmObject.failureCallback ~= nil then + pmObject.failureCallback(data); + end; + end; + + return true; + else + return false; + end; +end + +function __export_plugins_handleIncomingPM(fromModuleId, msgId, pmName, data) + local listener = pmListenersByName[pmName]; + + if listener ~= nil and listener.callback ~= nil then + local message = {}; + data = __convertIncomingPMData(data); + + if type(data) ~= "table" then + data = {data=data}; + end; + + for k, v in pairs(data) do + message[k] = v; + end; + + message.moduleId = fromModuleId; + message.__msgId = msgId; + + setTimeout( + function() + local r, ret = pcall(listener.callback, message); + + if r then + if not message.__isLateReply and not message.__replied then + plugins.replyPM(message, ret); + end; + else + plugins.replyPMFailure(message, ret); + end; + end, 0); + + return true; + else + return false; + end; +end + +function plugins.getInstalledTablesDock() + return _rrpg_plugins_getInstalledTablesDock(); +end; + +function plugins.activateTablesDock(mesa, moduleId, name, storedInfo) + return _rrpg_plugins_activateTablesDock(mesa.objectID, moduleId, name, storedInfo or ""); +end; + +function plugins.deactivateTablesDock(mesa, moduleId, name) + return _rrpg_plugins_deactivateTablesDock(mesa.objectID, moduleId, name); +end; + +function plugins.getIsTablesDockActive(mesa, moduleId, name) + return _rrpg_plugins_getIsTablesDockActive(mesa.objectID, moduleId, name); +end; + +function plugins.getActiveTablesDockStoredInfo(mesa, moduleId, name) + return _rrpg_plugins_getActiveTablesDockStoredInfo(mesa.objectID, moduleId, name); +end; + +function plugins.getListOfActiveTablesDockOnMesa(mesa) + return _rrpg_plugins_getListOfActiveTablesDockOnMesa(mesa.objectID); +end; + +return plugins; \ No newline at end of file diff --git a/sdk/rrpg.lua b/sdk/rrpg.lua new file mode 100644 index 00000000..0e7300c4 --- /dev/null +++ b/sdk/rrpg.lua @@ -0,0 +1,442 @@ +require("rrpgEvents.lua"); +local ndb = require("ndb.lua"); +local objs = require("rrpgObjs.lua"); +local rrpgWrappers = require("rrpgWrappers.lua"); +local Async = require("async.lua") + +--[[ API do RRPG ]]-- + +rrpg = objs.objectFromHandle(_obj_newObject("TRRPGMainWrapper")); +RRPG = rrpg; +Firecast = rrpg; + +local localRRPG = rrpg; +objs.registerHandle(rrpg.handle); + +rawset(rrpg, "listeners", {generator = 0}); +rawset(rrpg, "dataTypes", {}); +rawset(rrpg, "forms", {}); +rawset(rrpg, "props", {}); + +function rrpg:getMesas() + local hs = _rrpg_GetMesasIDs(); + local mesas = {}; + local idx = 1; + + for i = 1, #hs, 1 do + local mesaObj = localRRPG.contextObjectFromID(hs[i]); + + if (mesaObj ~= nil) then + mesas[idx] = mesaObj; + idx = idx + 1; + end; + end + + return mesas; +end; + +local propsRolagem = { + possuiAlgumDado = {getter="getPossuiAlgumDado", tipo="bool"}, + isRolado = {getter="getIsRolado", tipo="bool"}, + resultado = {getter="getResultado", tipo="int"}, + asString = {getter="getAsString", tipo="string"}, + tipo = {getter="getTipo", tipo="enum", + values={"direta", "storyteller"}} +}; + +local function newRolagemObject() + local rolObj = objs.objectFromHandle(_obj_newObject("TRRPGLuaRolagem")); + + function rolObj:getTipo() return _obj_getProp(self.handle, "TipoRolagem"); end; + + function rolObj:_readOps() + local nOps = {}; + local idxAtual = 1; + local rolado = _obj_getProp(self.handle, "IsRolado"); + + _obj_invoke(self.handle, "NavigatorBegin"); + + while (not _obj_getProp(self.handle, "IsNavigatorEOF")) do + local sOp = {}; + sOp.tipo = string.lower(_obj_getProp(self.handle, "NavigatorTipoOperacao")); + + if sOp.tipo == "dado" then + sOp.quantidade = _obj_getProp(self.handle, "NavigatorDadosQuantidade"); + local faceStr = _obj_getProp(self.handle, "NavigatorDadosFace"); + local faceAsNumber = tonumber(faceStr); + + if faceAsNumber ~= nil then + sOp.face = faceAsNumber; + else + sOp.face = faceStr; + end; + + if rolado then + sOp.resultados = _obj_getProp(self.handle, "NavigatorGetResultadoDados"); + else + sOp.resultados = {}; + end; + elseif sOp.tipo == "comparacao" then + sOp.comparacao = _obj_getProp(self.handle, "NavigatorComparacao"); + elseif sOp.tipo == "imediato" then + sOp.valor = _obj_getProp(self.handle, "NavigatorGetImediatoValue"); + end; + + nOps[idxAtual] = sOp; + idxAtual = idxAtual + 1; + + _obj_invoke(self.handle, "NavigatorNext"); + end + + rawset(self, "ops", nOps); + end; + + function rolObj:interpretarString(str) local ret = _obj_invoke(self.handle, "InterpretarString", str or ""); self:_readOps(); return ret; end; + + function rolObj:getPossuiAlgumDado() + local lOps = rawget(self, "ops"); + + if lOps ~= nil then + for i, k in pairs(lOps) do + if k.tipo == "dado" then + return true; + end; + end; + end; + + return false; + end; + + function rolObj:getIsRolado() return _obj_getProp(self.handle, "IsRolado"); end; + function rolObj:getResultado() return _obj_getProp(self.handle, "Resultado"); end; + function rolObj:getAsString() return _obj_getProp(self.handle, "RolagemAsStr"); end; + + function rolObj:concatenar(rolDir) + local rolDirObj; + + if type(rolDir) == "string" then + rolDirObj = localRRPG.interpretarRolagem(rolDir); + elseif type(rolDir) == "table" then + rolDirObj = rolDir; + elseif type(rolDir) == "number" then + rolDirObj = localRRPG.interpretarRolagem(tostring(rolDir)); + else + error("Cant concatenate rolls with the type " .. type(rolDir)); + end; + + local ret = _obj_invoke(self.handle, "Concatenar", rolDirObj.handle); + + if ret then + self:_readOps(); + end; + + return self; + end; + + function rolObj:rolarLocalmente() _obj_invoke(self.handle, "RolarLocalmente"); self:_readOps(); end; + function rolObj:loadFromBase64EncodedString(str) _obj_invoke(self.handle, "LoadFromBase64EncodedString", str); self:_readOps(); end; + + rolObj.props = propsRolagem; + objs.registerHandle(rolObj.handle, rolObj); + return rolObj; +end; + +function rrpg.interpretarRolagem(stringDaRolagem) + local rolObj = newRolagemObject(); + rolObj:interpretarString(stringDaRolagem); + return rolObj; +end; + +function rrpg.loadRolagemFromBase64EncodedString(encodedString) + local rolObj = newRolagemObject(); + rolObj:loadFromBase64EncodedString(encodedString); + return rolObj; +end + +function rrpg.contextObjectFromID(objectID) + return rrpgWrappers.contextObjectFromID(objectID); +end; + +function rrpg.objectFromID(objectID) + return localRRPG.contextObjectFromID(objectID); +end; + +function rrpg.getMesaFromNodeDataBase() +end; + +function rrpg.getMesaFromSheet(sheet) + return rrpg.getMesaFromNodeDataBase(sheet); +end; + +function rrpg.findMesa(codigoInterno) + local mesas = rrpg.getMesas(); + + for i = 1, #mesas, 1 do + local mesa = mesas[i]; + + if mesa.codigoInterno == codigoInterno then + return mesa; + end; + end; + + return nil; +end; + +function rrpg.getMesaDe(object) + if type(object) == "number" then + return rrpg.findMesa(object); + end; + + if (type(object) ~= "table") then + return nil; + end; + + local handle = rawget(object, "handle"); + local mesaObjectID; + + if handle == nil then + if ndb.isNodeObject(object) then + handle = ndb.getNodeHandle(object); + end; + end; + + if handle ~= nil then + mesaObjectID = _rrpg_tryGetMesaObjectIDRelatedToHandle(handle); + + if (mesaObjectID ~= nil) then + mesaObjectID = tonumber(mesaObjectID); + end; + + if mesaObjectID ~= nil then + return rrpg.objectFromID(mesaObjectID); + end; + end; + + return nil; +end; + +function rrpg.getBibliotecaItemDe(object) + if (type(object) ~= "table") then + return nil; + end; + + local handle = rawget(object, "handle"); + local bibObjectID; + + if handle == nil then + if ndb.isNodeObject(object) then + handle = ndb.getNodeHandle(object); + end; + end; + + if handle ~= nil then + bibObjectID = _rrpg_tryGetBibItemObjectIDRelatedToHandle(handle); + + if (bibObjectID ~= nil) then + bibObjectID = tonumber(bibObjectID); + end; + + if bibObjectID ~= nil then + return rrpg.objectFromID(bibObjectID); + end; + end; + + return nil; +end; + +function rrpg.getPersonagemDe(object) + local ctxObj = localRRPG.getBibliotecaItemDe(object); + + if (ctxObj ~= nil) and (ctxObj:isType("personagem")) then + return ctxObj; + else + return nil; + end; +end; + +function rrpg.getCurrentUser() + return _rrpg_getCurrentUser(); +end; + +function rrpg.ouvir(eventos) + if (eventos == nil) then + return; + end + + for k, v in pairs(eventos) do + if (type(v == "function")) then + local t = localRRPG.listeners[k]; + + if (t == nil) then + t = {}; + localRRPG.listeners[k] = t; + end; + + localRRPG.listeners.generator = localRRPG.listeners.generator + 1; + t[localRRPG.listeners.generator] = v; + + _rrpg_KnownEvent(k); + end + end; +end + +function rrpg.on(eventName, callbackFunction) + local tabela = {}; + tabela[eventName] = callbackFunction; + rrpg.ouvir(tabela); +end; + +function on(eventName, callbackFunction) + rrpg.on(eventName, callbackFunction); +end; + +function rrpg.dispatch(eventName, ...) + local t = localRRPG.listeners[eventName]; + + if (t == nil) then + return; + end; + + for k,v in pairs(t) do + v(...); + end; +end + +function rrpg.registrarDataType(dt) + if type(dt) == 'table' then + if ((dt.dataType ~= nil) and (dt.dataType ~= "")) then + localRRPG.dataTypes[dt.dataType] = dt; + _rrpg_DataTypes_Registrar(dt); + end; + end; +end; + +function rrpg.registrarForm(frm) + if type(frm) == 'table' then + if (frm.name ~= nil) then + localRRPG.forms[frm.name] = frm; + _rrpg_Forms_RegisterForm(frm); + end; + end; +end; + +function rrpg.registrarSpecialForm(frm) + if (type(frm) == 'table') and (frm.name ~= nil) then + _rrpg_Forms_RegistrarSpecial(frm); + end; +end; + +local __registeredToolButtons = nil; + +function rrpg.registerChatToolButton(params) + if type(params) ~= "table" then + error("registerChatToolButton: params must be a table"); + end; + + local regClass = objs.objectFromHandle(_obj_newObject("TRRPGLuaRegisteredChatToolButton")); + objs.registerHandle(regClass.handle); + + regClass.eves = {}; + regClass.eves["onCallback"] = ""; + + + if params.hint ~= nil then + _obj_setProp(regClass.handle, "Hint", params.hint); + end; + + _obj_setProp(regClass.handle, "IconURL", params.icon); + + local p = tonumber(params.priority); + + if p ~= nil then + _obj_setProp(regClass.handle, "Priority", math.floor(p)); + end; + + local group = tostring(params.group) or ""; + + if group ~= "" then + _obj_setProp(regClass.handle, "Group", tostring(params.group) or ""); + + p = tonumber(params.groupPriority); + + if p ~= nil then + _obj_setProp(regClass.handle, "GroupPriority", math.floor(p)); + end; + end; + + + if params.callback ~= nil then + regClass.onCallback = params.callback; + end; + + _obj_invoke(regClass.handle, "Activate"); + + if __registeredToolButtons == nil then + __registeredToolButtons = {}; + end; + + __registeredToolButtons[regClass.handle] = regClass; -- strong reference + return regClass.handle; +end; + +function rrpg.unregisterChatToolButton(toolButtonId) + if __registeredToolButtons ~= nil then + local regClass = __registeredToolButtons[toolButtonId]; + + if regClass ~= nil then + __registeredToolButtons[toolButtonId] = nil; + _obj_invoke(regClass.handle, "Deactivate"); + end; + end; +end; + +function rrpg.asyncOpenUserNDB(name, options) + if not Async.haveNativeBackendSupport() or not System.checkAPIVersion(87, 3) then + return Async.Promise.withError("No API Support"); + end; + + return rrpgWrappers.__serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_rrpg_Session_asyncOpenUserNDB(name, options)); + end); +end; + +function rrpg.parseTalemark(text, talemarkOptions) + if System.checkAPIVersion(87, 4) then + return _obj_invokeEx(localRRPG.handle, 'ParseTalemark', text, talemarkOptions); + else + return {type="root"}; + end; +end; + +rrpg.messaging = require("rrpgEventMessages.lua"); + +rrpg.props["mesas"] = {getter="getMesas", tipo="table"}; + +-- Alias functions +rrpg.listen = rrpg.messaging.listen; +rrpg.listenOnce = rrpg.messaging.listenOnce; +rrpg.unlisten = rrpg.messaging.unlisten; +rrpg.groupOnceListeners = rrpg.messaging.groupOnceListeners; +rrpg.Messaging = rrpg.messaging; +rrpg.parseRoll = rrpg.interpretarRolagem; +rrpg.findRoom = rrpg.findMesa; +rrpg.getRoomOf = rrpg.getMesaDe; +rrpg.getRooms = rrpg.getMesas; +rrpg.getLibraryItemOf = rrpg.getBibliotecaItemDe; +rrpg.getCharacterOf = rrpg.getPersonagemDe; + +-- Alias properties +rrpg.props["rooms"] = rrpg.props["mesas"]; + +RRPG = rrpg; + + +-- Exported API to the Firecast Executable + +function __rrpg_loadRolagemFromBase64EncodedString(encodedString) + return rrpg.loadRolagemFromBase64EncodedString(encodedString); +end; + +require("rrpgEventMessagesAdapters.lua"); +return rrpg; \ No newline at end of file diff --git a/sdk/rrpgDialogs.lua b/sdk/rrpgDialogs.lua new file mode 100644 index 00000000..9ea447c5 --- /dev/null +++ b/sdk/rrpgDialogs.lua @@ -0,0 +1,519 @@ +local objs = require("rrpgObjs.lua"); +local Async = require("async.lua"); + +local lDialogs = objs.objectFromHandle(_obj_newObject("TLuaDialogsServices")); + +local function newDialogObject(className) + return objs.objectFromHandle(_obj_newObject(className)); +end; + +lDialogs.DT_INFORMATION = "information"; +lDialogs.DT_ERROR = "error"; +lDialogs.DT_WARNING = "warning"; +lDialogs.DT_CONFIRMATION = "confirmation"; + +lDialogs.DB_YES = "yes"; +lDialogs.DB_NO = "no"; +lDialogs.DB_OK = "ok"; +lDialogs.DB_CANCEL = "cancel"; +lDialogs.DB_ABORT = "abort"; +lDialogs.DB_ALL = "all"; +lDialogs.DB_RETRY = "retry"; +lDialogs.DB_IGNORE = "ignore"; +lDialogs.DB_CLOSE = "close"; + +function lDialogs.newMessageDialog() + local dlg = newDialogObject('messageDialog'); + + function dlg:show(message, dialogType, dialogButtons, funcCallback) + _obj_setProp(dlg.handle, "DialogType", dialogType); + _obj_setProp(dlg.handle, "DialogButtons", dialogButtons); + + if funcCallback ~= nil then + dlg:addEventListener('OnResult', funcCallback); + end; + + _obj_invoke(dlg.handle, 'Executar', tostring(message)); + end; + + return dlg; +end; + +local runningMessageDialogs = {}; + +function lDialogs.showMessageDlg(message, dialogType, dialogButtons, funcCallback) + local dlg = lDialogs.newMessageDialog(); + runningMessageDialogs[dlg] = true; -- apenas manter uma referência forte ate o fim do dialogo + + dlg:show(message, dialogType, dialogButtons, + function (...) + runningMessageDialogs[dlg] = nil; + dlg = nil + + if type(funcCallback) == "function" then + funcCallback(...); + end; + end); +end; + +function lDialogs.confirmYesNo(question, callback) + lDialogs.showMessageDlg(question, lDialogs.DT_CONFIRMATION, {lDialogs.DB_YES, lDialogs.DB_NO}, + function(modalResult) + if type(callback) == "function" then + if modalResult == lDialogs.DB_YES then + callback(true); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.confirmOkCancel(question, callback) + lDialogs.showMessageDlg(question, lDialogs.DT_CONFIRMATION, {lDialogs.DB_OK, lDialogs.DB_CANCEL}, + function(modalResult) + if type(callback) == "function" then + if modalResult == lDialogs.DB_OK then + callback(true); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.showMessage(msg, callback) + lDialogs.showMessageDlg(msg, lDialogs.DT_INFORMATION, {lDialogs.DB_OK}, + function(modalResult) + if type(callback) == "function" then + callback(); + end; + end); +end; + +function lDialogs.showErrorMessage(msg, callback) + lDialogs.showMessageDlg(msg, lDialogs.DT_ERROR, {lDialogs.DB_OK}, + function(modalResult) + if type(callback) == "function" then + callback(); + end; + end); +end; + +function lDialogs.alert(msg, callback) + lDialogs.showMessageDlg(msg, lDialogs.DT_WARNING, {lDialogs.DB_OK}, + function(modalResult) + if type(callback) == "function" then + callback(); + end; + end); +end; + +function lDialogs.newInputQueryDialog() + local dlg = objs.objectFromHandle(_obj_newObject("TLuaInputQueryDialog")); + + function dlg:show(caption, prompt, initialValue, confirmCallback, cancelCallback, allowEmptyString) + if (confirmCallback ~= nil) then + dlg:addEventListener("OnConfirm", confirmCallback); + end; + + if (cancelCallback ~= nil) then + dlg:addEventListener("OnCancel", cancelCallback); + end; + + _obj_invoke(dlg.handle, "Executar", caption or "", prompt or "", initialValue or "", allowEmptyString == true); + end; + + objs.registerHandle(dlg.handle, dlg); + return dlg; +end; + +local runningQueryDialogs = {}; + +function lDialogs.inputQuery(caption, prompt, initialValue, confirmCallback, cancelCallback, allowEmptyString) + local dlg = lDialogs.newInputQueryDialog(); + runningQueryDialogs[dlg] = true; -- apenas manter uma referência forte até o fim do input query + + dlg:show(caption, prompt, initialValue, + function(...) + runningQueryDialogs[dlg] = nil; + dlg = nil; + + if confirmCallback ~= nil then + confirmCallback(...); + end; + end, + + function (...) + runningQueryDialogs[dlg] = nil; + dlg = nil; + + if cancelCallback ~= nil then + cancelCallback(...); + end; + end, allowEmptyString); +end; + +function alert(msg, callback) + lDialogs.alert(msg, callback); +end; + +function showMessage(msg, callback) + lDialogs.showMessage(msg, callback); +end; + +local runningFileQuerys = {}; + +function _newFileQueryObject() + local obj = objs.objectFromHandle(_obj_newObject('TLuaFileQueryDialog')); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["onResult"] = "data"; + obj.eves["onCancel"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +function lDialogs.openFile(prompt, accept, multiple, callback, cancelCallback) + local query = _newFileQueryObject(); + + query.onResult = function(files) + runningFileQuerys[query] = nil; + local utils = require("utils.lua"); + + for i = 1, #files, 1 do + files[i].stream = utils.streamFromHandle(files[i].streamHandle); + files[i].stream.position = 0; + files[i].streamHandle = nil; + end; + + if callback ~= nil then + callback(files or {}); + end; + end; + + query.onCancel = function() + runningFileQuerys[query] = nil; + + if cancelCallback ~= nil then + cancelCallback(); + end; + end; + + _obj_setProp(query.handle, "Accept", tostring(accept or "") or ""); + _obj_setProp(query.handle, "Multiple", not (not multiple)); + _obj_setProp(query.handle, "Prompt", tostring(prompt or "") or ""); + + runningFileQuerys[query] = true; + _obj_invoke(query.handle, "Execute"); +end; + +function lDialogs.asyncOpenFile(prompt, accept, multiple) + local promise, resolution = Async.Promise.pending(); + + lDialogs.openFile(prompt, accept, multiple, + function(data) + resolution:setSuccess(data); + end, + + function() + resolution:setUserAborted(); + end); + + return promise; +end; + +local function _newFileSaveObject() + local obj = objs.objectFromHandle(_obj_newObject('TLuaFileSaveDialog')); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["OnCallback"] = ""; + obj.eves["OnCancelCallback"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +local runningFileSaveDialogs = {}; + +function lDialogs.saveFile(prompt, stream, suggestedFileName, mimeType, callback, cancelCallback) + if (type(stream) ~= "table") or (stream.handle == nil) then + error("Dialogs.saveFile - 'stream' parameter is not a valid object"); + end; + + local query = _newFileSaveObject(); + rawset(query, "__tempStream", stream); -- keep reference while running the save dialog + + query.OnCallback = function() + runningFileSaveDialogs[query] = nil; + + if callback ~= nil then + callback(); + end; + end; + + query.OnCancelCallback = function() + runningFileSaveDialogs[query] = nil; + + if cancelCallback ~= nil then + cancelCallback(); + end; + end; + + _obj_setProp(query.handle, "Prompt", tostring(prompt or "") or ""); + _obj_setProp(query.handle, "SuggestedFileName", tostring(suggestedFileName or "") or ""); + _obj_setProp(query.handle, "MimeType", tostring(mimeType or "") or ""); + + _obj_invokeEx(query.handle, "SetStream", stream.handle); + + runningFileSaveDialogs[query] = true; + _obj_invoke(query.handle, "Execute"); +end + +function lDialogs.o(prompt, multiple, callback, cancelCallback) + return lDialogs.openFile(prompt, "image/*", multiple, callback, cancelCallback); +end; + +local function _newSelectImageURLObject() + local obj = objs.objectFromHandle(_obj_newObject('TLuaSelectImageURLQuery')); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["OnCallback"] = ""; + obj.eves["OnCancelCallback"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +local runningSelectImageURLDialogs = {}; + +function lDialogs.selectImageURL(defaultURL, callback, cancelCallback) + local query = _newSelectImageURLObject(); + + query.OnCallback = function() + runningSelectImageURLDialogs[query] = nil; + + if callback ~= nil then + callback(_obj_getProp(query.handle, "SelectedURL")); + end; + end; + + query.OnCancelCallback = function() + runningSelectImageURLDialogs[query] = nil; + + if cancelCallback ~= nil then + cancelCallback(); + end; + end; + + _obj_setProp(query.handle, "DefaultURL", tostring(defaultURL or "") or ""); + + runningSelectImageURLDialogs[query] = true; + _obj_invoke(query.handle, "Execute"); +end + +local function _newChoiceDialogPopup(className) + local GUI = require("gui.lua"); + local obj = GUI.controlFromHandle(_obj_newObject(className or 'TLuaChoiceDialogPopup')); + + if obj.eves == nil then + obj.eves = {}; + end; + + function obj:addSelectionOption(option) + _obj_invoke(obj.handle, "AddSelectionOption", tostring(option) or ""); + end; + + function obj:setDefaultIndex(defaultIndex) + _obj_setProp(obj.handle, "DefaultIndex", defaultIndex); + end; + + function obj:setTitle(title) + _obj_setProp(obj.handle, "DialogTitle", tostring(title) or ""); + end; + + function obj:buildPanel() + _obj_invoke(obj.handle, "BuildPanel"); + end; + + function obj:executeAsync() + _obj_invoke(obj.handle, "ExecuteAsync"); + end; + + function obj:acquireFocus() + _obj_invoke(obj.handle, "AcquireFocus"); + end; + + function obj:getSelectedIndex() + return _obj_getProp(obj.handle, "LuaSelectedIndex"); + end; + + obj.eves["onChoiceSelected"] = ""; + obj.eves["onChoiceCanceled"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +local function _newMultipleChoiceDialogPopup() + local obj = _newChoiceDialogPopup("TLuaMultipleChoiceDialogPopup"); + + function obj:getSelectedIndexes() + return _obj_invokeEx(obj.handle, "ReturnLuaArrayOfSelected"); + end; + + return obj; +end; + +local function _executeChoicePanel(panel, callback) + local GUI = require("gui.lua"); + require("utils.lua"); + + local frm = GUI.newPopupForm(); + frm.drawContainer = true; + frm.cancelable = false; + frm.resizable = true; + local haveNotified = false; + + local cancelProc = function() + frm:close(); + + if not haveNotified then + haveNotified = true; + + setTimeout( + function() + callback(false); + end, 1); + end; + end; + + frm.onCancelRequest = cancelProc; + panel.onChoiceCanceled = cancelProc; + frm.onHide = cancelProc; + + panel.onChoiceSelected = + function() + local mustNotify = not haveNotified; + haveNotified = true; + + frm:close(); + + if mustNotify then + setTimeout(function() + callback(true); + end, 1); + end; + end; + + panel.parent = frm; + panel.align = "client"; + panel.visible = true; + frm.width = 300; + frm.height = 300; + frm.theme = "dark"; + panel:executeAsync(); + frm:show(); + panel:acquireFocus(); +end; + +function lDialogs.choose(prompt, options, callback, defaultIndex, shortCircuit) + if (type(options) ~= "table") or (#options < 1) then + if callback ~= nil then + callback(false); + end; + + return; + end; + + require("gui.lua"); + local choosePanel = _newChoiceDialogPopup(); + + if type(options) == "table" then + for i = 1, #options, 1 do + choosePanel:addSelectionOption(options[i]); + end; + + if shortCircuit and (#options == 1) then + setTimeout( + function() + if callback ~= nil then + callback(true, 1, options[1]); + end; + end, 1); + + return; + end; + end; + + if defaultIndex ~= nil then + choosePanel:setDefaultIndex(defaultIndex - 1); + end; + + choosePanel:setTitle(prompt or ""); + choosePanel:buildPanel(); + + _executeChoicePanel(choosePanel, + function (confirmed) + if callback ~= nil then + if confirmed then + local idx = choosePanel:getSelectedIndex() + 1; + callback(true, idx, options[idx]); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.chooseMultiple(prompt, options, callback) + require("gui.lua"); + local choosePanel = _newMultipleChoiceDialogPopup(); + + if type(options) == "table" then + for i = 1, #options, 1 do + choosePanel:addSelectionOption(options[i]); + end; + end; + + choosePanel:setTitle(prompt or ""); + choosePanel:buildPanel(); + + _executeChoicePanel(choosePanel, + function (confirmed) + if callback ~= nil then + if confirmed then + local indexes = choosePanel:getSelectedIndexes(); + local values = {}; + + for i = 1, #indexes, 1 do + indexes[i] = indexes[i] + 1; + values[i] = options[indexes[i]]; + end; + + callback(true, indexes, values); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.asyncSelectTalemarkColor(initialColor) + local promiseHandle = _obj_invokeEx(lDialogs.handle, "AsyncSelectTalemarkColor", initialColor); + return Async.Promise.wrap(promiseHandle); +end; + +dialogs = lDialogs; +Dialogs = dialogs; +return dialogs; \ No newline at end of file diff --git a/sdk/rrpgEventMessages.lua b/sdk/rrpgEventMessages.lua new file mode 100644 index 00000000..d32bb018 --- /dev/null +++ b/sdk/rrpgEventMessages.lua @@ -0,0 +1,236 @@ +local rrpgObjs = require("rrpgObjs.lua"); +local messaging = {}; + +local CANCEL_RECEIVER = false; +messaging.CANCEL = CANCEL_RECEIVER; + +local _messageAdapters = {}; + +function messaging.createReceiver(messageName, callback, filters) + if (type(callback) ~= "function") or (type(messageName) ~= "string") or (messageName == "") then + return nil; + end; + + if type(filters) ~= "table" then + filters = nil; + end; + + local obj = rrpgObjs.objectFromHandle(_obj_newObject("TRRPGEventMessageReceiver")); + rrpgObjs.registerHandle(obj.handle, obj); + + local msgAdapter = _messageAdapters[string.upper(messageName)]; + + if (msgAdapter ~= nil) and (msgAdapter.prepareFilters ~= nil) and (filters ~= nil) then + msgAdapter.prepareFilters(filters); + end; + + if filters ~= nil then + for k, v in pairs(filters) do + _obj_invokeEx(obj.handle, "AddFilter", k, v); + end; + end; + + _obj_setProp(obj.handle, "EventName", messageName); + + obj.__callbackEventListenerId = obj:addEventListener("OnMessage", + function (message) + if callback ~= nil then + if (msgAdapter ~= nil) and (msgAdapter.prepareMessage ~= nil) then + msgAdapter.prepareMessage(message); + end; + + local retorno = callback(message); + + if retorno == CANCEL_RECEIVER then + messaging.disableReceiver(obj); + end; + + local response = message.response; + + if (response ~= nil) and (type(response) == "table") then + if (msgAdapter ~= nil) and (msgAdapter.prepareResponse ~= nil) then + msgAdapter.prepareResponse(response); + end; + + _obj_invokeEx(obj.handle, "AddResponse", response); + end; + end; + end); + + function obj:disable() + callback = nil; + local evtId = obj.__callbackEventListenerId; + + if evtId ~= nil then + _obj_setProp(obj.handle, "EventName", ""); + obj:removeEventListener(evtId); + obj.__callbackEventListenerId = nil; + end; + end; + + return obj; +end; + +messaging.newReceiver = messaging.createReceiver; + +function messaging.disableReceiver(receiverObj) + if (type(receiverObj) == "table") and (receiverObj.disable ~= nil) then + receiverObj:disable(); + end; +end; + +local __settedListeners = {}; +local __listenersGeneratorId = 1; +local __listenersByName = {}; + +function messaging.listen(messageName, callback, filters) + if (type(callback) ~= "function") or (type(messageName) ~= "string") or (messageName == "") then + return nil; + end; + + __listenersGeneratorId = __listenersGeneratorId + 1; + local esteListenerId = __listenersGeneratorId; + + local obj = messaging.createReceiver(messageName, + function(message) + local retorno; + + if callback ~= nil then + retorno = callback(message); + else + retorno = nil; + end; + + if retorno == CANCEL_RECEIVER then + messaging.unlisten(esteListenerId); + callback = nil; + end; + + return retorno; + end, filters); + + if obj == nil then + return nil; + end; + + __settedListeners[esteListenerId] = obj; + + local preparedMessageName = _util_genCollateWinPtBrString(messageName); + local lbn = __listenersByName[preparedMessageName]; + + if lbn == nil then + lbn = {}; + __listenersByName[preparedMessageName] = lbn; + end; + + obj.preparedMessageName = preparedMessageName; + lbn[esteListenerId] = obj; + return esteListenerId; +end; + +function messaging.unlisten(listenerId) + if listenerId == nil then + return; + end; + + local listenerObj = __settedListeners[listenerId]; + + if listenerObj ~= nil then + __settedListeners[listenerId] = nil; + + local lbn = __listenersByName[listenerObj.preparedMessageName]; + + if lbn ~= nil then + lbn[listenerId] = nil; + + if next(lbn, nil) == nil then -- Tabela vazia + __listenersByName[listenerObj.preparedMessageName] = nil; + end; + end; + + if listenerObj.disable ~= nil then + listenerObj:disable(); + end; + end; +end; + +function messaging.listenOnce(messageName, callback, filters) + local listenerId = messaging.listen(messageName, + function(message) + callback(message); + return CANCEL_RECEIVER; + end, filters); + + return listenerId; +end; + +function messaging.groupOnceListeners(...) + local parametros = table.pack(...); + local listenersObjs = {}; + local listenersId = {}; + + for i = 1, #parametros, 1 do + local obj = __settedListeners[parametros[i]]; + + if (obj ~= nil) then + listenersId[#listenersId + 1] = parametros[i]; + listenersObjs[#listenersObjs + 1] = obj; + end; + end; + + if #listenersObjs == 0 then + return; + end; + + local eventListenersId = {}; + + for i = 1, #listenersObjs, 1 do + local obj = listenersObjs[i]; + eventListenersId[#eventListenersId + 1] = obj:addEventListener('OnAfterMessage', + function() + -- um dos listeners disparou, vamos cancelar os outros. + + for j = 1, #listenersObjs, 1 do + local otherObj = listenersObjs[j]; + otherObj:removeEventListener(eventListenersId[j]); + messaging.unlisten(listenersId[j]); + otherObj:disable(); + end; + end); + end; +end; + +function messaging.addMessageAdapter(messageName, adapter) + _messageAdapters[string.upper(messageName)] = adapter; +end; + +function messaging.dispatchLocalMessage(messageName, message) + local lbn = __listenersByName[_util_genCollateWinPtBrString(messageName)]; + + if lbn == nil then + return; + end; + + if type(message) ~= "table" then + local nm = {}; + nm.data = message; + message = nm; + end; + + local copyOfLbn = {}; + + -- Copiar, pois lbn pode mudar ao longo do processo + for k, v in pairs(lbn) do + copyOfLbn[k] = v; + end; + + for k, v in pairs(copyOfLbn) do + _obj_invokeEx(v.handle, "TryDispatchLocalMessage", message); + end +end; + +function __export__dispatchLocalMessage(messageName, message) + return messaging.dispatchLocalMessage(messageName, message); +end; + +return messaging; \ No newline at end of file diff --git a/sdk/rrpgEventMessagesAdapters.lua b/sdk/rrpgEventMessagesAdapters.lua new file mode 100644 index 00000000..50331dbb --- /dev/null +++ b/sdk/rrpgEventMessagesAdapters.lua @@ -0,0 +1,308 @@ +local messaging = require("rrpgEventMessages.lua"); +local rrpgWrappers = require("rrpgWrappers.lua"); + +-- Não faça require em rrpg.lua + +local _basicChatCommandAdapter = {prepareFilters = + function(filters) + + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + + if filters.chat ~= nil then + filters.chatObjectID = filters.chat.objectID; + filters.chat = nil; + else + filters.chatObjectID = nil; + end; + + if filters.player ~= nil then + filters.jogadorObjectID = filters.player.objectID; + filters.player = nil; + filters.jogador = nil; + else + if filters.jogador ~= nil then + filters.jogadorObjectID = filters.jogador.objectID; + filters.jogador = nil; + else + filters.jogadorObjectID = nil; + end; + end; + end, + + prepareMessage = + function(message) + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + + message.chat = rrpgWrappers.contextObjectFromID(message.chatObjectID); + + message.jogador = rrpgWrappers.contextObjectFromID(message.jogadorObjectID); + message.player = message.jogador; + end, + }; + +local _basicChatMessageAdapter = {prepareFilters = + function(filters) + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + + if filters.chat ~= nil then + filters.chatObjectID = filters.chat.objectID; + filters.chat = nil; + else + filters.chatObjectID = nil; + end; + + if filters.player ~= nil then + filters.jogadorObjectID = filters.player.objectID; + filters.player = nil; + filters.jogador = nil; + else + if filters.jogador ~= nil then + filters.jogadorObjectID = filters.jogador.objectID; + filters.jogador = nil; + else + filters.jogadorObjectID = nil; + end; + end; + + if filters.pvtPlayer ~= nil then + filters.jogadorPVTObjectID = filters.pvtPlayer.objectID; + filters.pvtPlayer = nil; + filters.jogadorPVT = nil; + else + if filters.jogadorPVT ~= nil then + filters.jogadorPVTObjectID = filters.jogadorPVT.objectID; + filters.jogadorPVT = nil; + else + filters.jogadorPVTObjectID = nil; + end; + end; + + filters.rolagem = nil; + filters.roll = nil; + end, + + prepareMessage = + function(message) + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + + message.chat = rrpgWrappers.contextObjectFromID(message.chatObjectID); + + message.jogador = rrpgWrappers.contextObjectFromID(message.jogadorObjectID); + message.player = message.jogador; + + message.jogadorPVT = rrpgWrappers.contextObjectFromID(message.jogadorPVTObjectID); + message.pvtPlayer = message.jogadorPVT; + + if message.rolagem64 ~= nil then + message.rolagem = rrpg.loadRolagemFromBase64EncodedString(message.rolagem64); + message.roll = message.rolagem; + message.rolagem64 = nil; + end; + end, + }; + +local __listChatCommandsAdapter = { + prepareFilters = function(filters) + _basicChatMessageAdapter.prepareFilters(filters); + end, + + prepareMessage = + function(message) + _basicChatMessageAdapter.prepareMessage(message); + end, + + prepareResponse = function(response) + local r = {}; + + for k, v in pairs(response) do + if type(v) == "table" then + r[k] = v; + end; + + response[k] = nil; + end; + + local id = _rrpg_generateUniqueStrID(); + local qt = 0; + + for k, v in pairs(r) do + qt = qt + 1; + local str = ""; + local comando = v.command or v.comando; + local tComando = type(comando); + local comandoIdx = 1; + + if tComando == "string" then + str = str .. "comando" .. comandoIdx .. "=" .. _util_encodeStringToHexUTF8(comando) .. "&"; + --comandoIdx = comandoIdx + 1; + elseif tComando == "table" then + for i = 1, #comando, 1 do + str = str .. "comando" .. comandoIdx .. "=" .. _util_encodeStringToHexUTF8(comando[i]) .. "&"; + comandoIdx = comandoIdx + 1; + end; + end; + + str = str .. "descricao=" .. _util_encodeStringToHexUTF8(v.description or v.descricao); + response[id .. qt] = str; + end; + end; +}; + +local _mesaJoinPartAdapter = {prepareFilters = + function(filters) + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + + if filters.player ~= nil then + filters.jogadorObjectID = filters.player.objectID; + filters.player = nil; + filters.jogador = nil; + else + if filters.jogador ~= nil then + filters.jogadorObjectID = filters.jogador.objectID; + filters.jogador = nil; + else + filters.jogadorObjectID = nil; + end; + end; + + if filters.me ~= nil then + filters.eu = filters.me; + filters.me = nil; + end; + + if filters.isKick ~= nil then + filters.ehKick = filters.isKick; + filters.isKick = nil; + end; + + if filters.text ~= nil then + filters.mensagem = filters.text; + filters.text = nil; + end; + + if filters.responsible ~= nil then + filters.responsavelObjectID = filters.responsible.objectID; + filters.responsible = nil; + filters.responsavel = nil; + else + if filters.responsavel ~= nil then + filters.responsavelObjectID = filters.responsavel.objectID; + filters.responsavel = nil; + end; + end; + end, + + prepareMessage = + function(message) + message.me = message.eu; + message.isKick = message.ehKick; + message.text = message.mensagem; + + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + + message.jogador = rrpgWrappers.contextObjectFromID(message.jogadorObjectID); + message.player = message.jogador; + + if message.responsavelObjectID ~= nil then + message.responsavel = rrpgWrappers.contextObjectFromID(message.responsavelObjectID); + message.responsible = message.responsavel; + end; + end, + }; + +local _mesaMsgAdapter = {prepareFilters = + function(filters) + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + end, + + prepareMessage = + function(message) + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + end, + }; + +messaging.addMessageAdapter("ChatMessage", _basicChatMessageAdapter); +messaging.addMessageAdapter("HandleChatTextInput", _basicChatMessageAdapter); +messaging.addMessageAdapter("HandleChatCommand", _basicChatCommandAdapter); +messaging.addMessageAdapter("ListChatCommands", __listChatCommandsAdapter); +messaging.addMessageAdapter("MesaJoined", _mesaJoinPartAdapter); +messaging.addMessageAdapter("MesaParted", _mesaJoinPartAdapter); +messaging.addMessageAdapter("TablesDockClosedByUser", _mesaMsgAdapter); +messaging.addMessageAdapter("TablesDockPosChanged", _mesaMsgAdapter); + +-- Mensagens do Scene 3 + +local _SceneWrappers = nil; + +local _sceneMsgAdapter = {prepareFilters = + function(filters) + if filters.scene ~= nil then + filters.sceneObjectID = filters.scene.objectID; + filters.scene = nil; + else + filters.sceneObjectID = nil; + end; + end, + + prepareMessage = + function(message) + if _SceneWrappers == nil then + _SceneWrappers = require("sceneWrappers.dlua"); + end; + + message.scene = _SceneWrappers.objectFromID(message.sceneObjectID); + end, + }; + + +messaging.addMessageAdapter("SC3SceneLoaded", _sceneMsgAdapter); +messaging.addMessageAdapter("SC3SceneUnloaded", _sceneMsgAdapter); + \ No newline at end of file diff --git a/sdk/rrpgEvents.lua b/sdk/rrpgEvents.lua new file mode 100644 index 00000000..209c0115 --- /dev/null +++ b/sdk/rrpgEvents.lua @@ -0,0 +1,133 @@ +local ndb = require("ndb.lua"); +local objs = require("rrpgObjs.lua"); + + + +function _eve_MESA_PVT_ReceberMensagem(mesaID, senderID, msg) + rrpg.dispatch("MESA_PVT_ReceberMensagem", rrpg.objectFromID(mesaID), rrpg.objectFromID(senderID), msg); +end + + +--[[ Coisas relacionadas ao Sistema de Forms ]]-- + +local _LuaForms = {}; + +--[ Lista de forms que não estao sendo utilizados, e podem ser reusados (antes que o garbage colector faca sua parte) ]-- +local _CachedFreeForms = {}; + +function _eve_Forms_CriarForm(formName) + local dtObj = rrpg.forms[formName]; + + if dtObj ~= nil then + local frm = dtObj.newEditor(); + rawset(frm, "__formName", formName); + + _LuaForms[frm.handle] = frm; + return frm.handle; + else + return nil; + end; +end; + +function eve_Forms_ExisteFormName(formName) + return rrpg.forms[formName] ~= nil; +end; + +function _eve_Forms_DestruirForm(formHandle) + local frm = _LuaForms[formHandle]; + + if frm ~= nil then + _LuaForms[formHandle] = nil; + frm:destroy(); + end; +end; + +function _eve_Forms_AssignNodeDatabase(formHandle, nodeHandle) + local nodeDataBase = ndb.openNodeFacade(nodeHandle); + local formObj = _LuaForms[formHandle]; + + if (formObj ~= nil) then + if formObj.setNodeDatabase ~= nil then + formObj:setNodeDatabase(nodeDataBase); + end; + end; +end; + +local _tmrDestroyCachedForms = objs.newTimer(45000); +_tmrDestroyCachedForms:setEnabled(false); + +function _eve_Forms_Cached_CriarForm(formName) + local cache = _CachedFreeForms[formName]; + + if type(cache) == "table" then + local objetoEncontrado = nil; + + for k, v in pairs(cache) do + if (type(k) == "table") and (v ~= nil) then + objetoEncontrado = k; + break; + end; + end; + + if objetoEncontrado ~= nil then + _LuaForms[objetoEncontrado.handle] = objetoEncontrado; + cache[objetoEncontrado] = nil; + return objetoEncontrado.handle; + end; + end; + + -- se chegou até aqui, é porque nao conseguiu usar algum do cache + return _eve_Forms_CriarForm(formName); +end; + +function _eve_Forms_Cached_DestruirForm(formHandle) + local formObject = _LuaForms[formHandle]; + + if formObject ~= nil then + local formName = rawget(formObject, "__formName"); + + if formName ~= nil then + local cache = _CachedFreeForms[formName]; + + if cache == nil then + cache = {}; + _CachedFreeForms[formName] = cache; + end; + + cache[formObject] = true; -- adicionar ao cache + _LuaForms[formObject.handle] = nil; + + if formObject.setNodeDatabase ~= nil then + formObject:setNodeDatabase(nil); + end; + + formObject:setParent(nil); + + _tmrDestroyCachedForms:setEnabled(true); -- ativar o timer de coleta de cache + return; + end; + end; + + -- se chegou até aqui, é porque nao conseguiu colocar o form no cache + return _eve_Forms_DestruirForm(formHandle); +end; + +function timedCheckAndDestroyCachedForms() + _tmrDestroyCachedForms:setEnabled(false); + + local oldCachedFreeForms = _CachedFreeForms; + _CachedFreeForms = {}; + + for formName, cache in pairs(oldCachedFreeForms) do + + if cache ~= nil then + for formObj, v in pairs(cache) do + if (formObj ~= nil) and (formObj.destroy ~= nil) then + formObj:destroy(); + end; + end; + end; + end; +end; + +_tmrDestroyCachedForms:addEventListener("onTimer", timedCheckAndDestroyCachedForms); \ No newline at end of file diff --git a/sdk/rrpgGUI.lua b/sdk/rrpgGUI.lua new file mode 100644 index 00000000..5d1855bf --- /dev/null +++ b/sdk/rrpgGUI.lua @@ -0,0 +1,2060 @@ +local objs = require("rrpgObjs.lua"); +local ndb = require("ndb.lua"); +local System = require("system.lua"); +local Async = require("async.lua"); +local Utils = require("utils.lua"); + +local __delayedGridLib = nil; + +gui = objs.objectFromHandle(_obj_newObject("TLuaGUIServices")); +GUI = gui; + +gui.DEFAULT_FORM_CACHE_TIMEOUT = 60000; + +local guiLoaders = {}; +local guiClasses = {}; + +gui.guiLoaders = guiLoaders; +gui.guiClasses = guiClasses; + +local function registerTag(class, tagName) + assert(guiClasses[tagName] == nil, tagName); + assert(rawget(class, "tagName") == nil, tagName); + + guiLoaders[tagName] = class.fromHandle; + guiClasses[tagName] = class; + + rawset(class, "tagName", tagName); + + rawset(class, "new", + function() + return class.fromHandle(_obj_newObject(tagName)); + end); + + local constructorName = "new" .. tagName:gsub("^%l", string.upper); + + gui[constructorName] = + function() + return class.new(); + end; +end; + +--[[ Objeto Control ]]-- + +gui.Control = objs.HierarchyObject.inherit(); + +function gui.Control:initialize() + if self.props == nil then + self.props = {}; + end; + + if self.eves == nil then + self.eves = {}; + end; + + self:setParent(self:getParent()); +end; + +function gui.Control:setFocus() _obj_invoke(self.handle, "SetFocus"); end; +function gui.Control:beginUpdate() _obj_invoke(self.handle, "BeginUpdate"); end; +function gui.Control:endUpdate() _obj_invoke(self.handle, "EndUpdate"); end; +function gui.Control:needRepaint() _obj_invoke(self.handle, "Repaint"); end; + +function gui.Control:getVisible() return _obj_getProp(self.handle, "Visible"); end; + +function gui.Control:setVisible(visible) + _obj_setProp(self.handle, "Visible", visible == true); + + if visible then + local grid = self:tryGetGrid(); + + if grid ~= nil then + grid:invalidate(); + end; + end; +end; + +function gui.Control:getAlign() return _obj_getProp(self.handle, "Align"); end; +function gui.Control:setAlign(align) _obj_setProp(self.handle, "Align", align); end; + +function gui.Control:getEnabled()return _obj_getProp(self.handle, "Enabled"); end; +function gui.Control:setEnabled(enabled) _obj_setProp(self.handle, "Enabled", enabled == true) end; + +function gui.Control:getLeft() return _obj_getProp(self.handle, "Position.X"); end; +function gui.Control:setLeft(left) _obj_setProp(self.handle, "Position.X", left) end; + +function gui.Control:getTop() return _obj_getProp(self.handle, "Position.Y"); end; +function gui.Control:setTop(top) _obj_setProp(self.handle, "Position.Y", top) end; + +function gui.Control:getBottom() return self:getTop() + self:getHeight(); end; +function gui.Control:setBottom(bottom) self:setTop(bottom - self:getHeight()); end; + +function gui.Control:getRight() return self:getLeft() + self:getWidth(); end; +function gui.Control:setRight(right) self:setLeft(right - self:getWidth()); end; + +function gui.Control:getWidth() return _obj_getProp(self.handle, "Width"); end; +function gui.Control:setWidth(width) _obj_setProp(self.handle, "Width", width) end; + +function gui.Control:getHeight() return _gui_getHeight(self.handle); end; +function gui.Control:setHeight(height) _gui_setHeight(self.handle, height) end; + +function gui.Control:getHitTest() return _obj_getProp(self.handle, "HitTest"); end; +function gui.Control:setHitTest(hittest) _obj_setProp(self.handle, "HitTest", hittest == true) end; + +function gui.Control:getTabOrder() return _obj_getProp(self.handle, "TabOrder"); end; +function gui.Control:setTabOrder(tabOrder) _obj_setProp(self.handle, "TabOrder", tabOrder); end; + +function gui.Control:getOpacity() return _obj_getProp(self.handle, "Opacity"); end; +function gui.Control:setOpacity(opacity) _obj_setProp(self.handle, "Opacity", opacity); end; + +function gui.Control:getMargins() return _obj_getProp(self.handle, "Margins"); end; +function gui.Control:setMargins(margins) _gui_setMargins(self.handle, margins); end; + +function gui.Control:getPadding() return _obj_getProp(self.handle, "Padding"); end; +function gui.Control:setPadding(padding) _gui_setPadding(self.handle, padding); end; + +function gui.Control:getAnchors() return _obj_getProp(self.handle, "Anchors"); end; +function gui.Control:setAnchors(anchors) _obj_setProp(self.handle, "Anchors", anchors); end; + +function gui.Control:getCanFocus() return _obj_getProp(self.handle, "CanFocus"); end; +function gui.Control:setCanFocus(canFocus) _obj_setProp(self.handle, "CanFocus", canFocus); end; + +function gui.Control:getRotationAngle() return _obj_getProp(self.handle, "RotationAngle"); end; +function gui.Control:setRotationAngle(angle) _obj_setProp(self.handle, "RotationAngle", angle); end; + +function gui.Control:getRotationCenterX() return _obj_getProp(self.handle, "RotationCenter.X"); end; +function gui.Control:setRotationCenterX(x) _obj_setProp(self.handle, "RotationCenter.X", x); end; + +function gui.Control:getRotationCenterY() return _obj_getProp(self.handle, "RotationCenter.Y"); end; +function gui.Control:setRotationCenterY(y) _obj_setProp(self.handle, "RotationCenter.Y", y); end; + +function gui.Control:getScaleX() return _obj_getProp(self.handle, "Scale.X"); end; +function gui.Control:setScaleX(sX) _obj_setProp(self.handle, "Scale.X", sX); end; + +function gui.Control:getScaleY() return _obj_getProp(self.handle, "Scale.Y"); end; +function gui.Control:setScaleY(sY) _obj_setProp(self.handle, "Scale.Y", sY); end; + +function gui.Control:getScale() return self:getScaleX(); end; +function gui.Control:setScale(ss) self:beginUpdate(); self:setScaleX(ss); self:setScaleY(ss); self:endUpdate(); end; + +function gui.Control:isChildFocused() return _obj_getProp(self.handle, "IsChildFocused"); end; +function gui.Control:isFocused() return _obj_getProp(self.handle, "IsFocused"); end; +function gui.Control:isMouseOver() return _obj_getProp(self.handle, "IsMouseOver"); end; +function gui.Control:isVisible() return self:getVisible(); end; + +function gui.Control:getCursor() return _obj_getProp(self.handle, "MouseCursor"); end; +function gui.Control:setCursor(v) _obj_setProp(self.handle, "MouseCursor", v); end; + +function gui.Control:getHint() return _obj_getProp(self.handle, "Hint"); end; +function gui.Control:setHint(v) _gui_setHint(self.handle, v); end; + +function gui.Control:getEffect() return _obj_getProp(self.handle, "CompEffect"); end; +function gui.Control:setEffect(effect) _obj_setProp(self.handle, "CompEffect", effect); end; + +function gui.Control:getEffectTriggers() return _obj_getProp(self.handle, "CompEffectTriggers"); end; +function gui.Control:setEffectTriggers(triggers) _obj_setProp(self.handle, "CompEffectTriggers", triggers); end; + +function gui.Control:getEffectParam() return _obj_getProp(self.handle, "CompEffectParam"); end; +function gui.Control:setEffectParam(param) _obj_setProp(self.handle, "CompEffectParam", param); end; + +function gui.Control:getEffectParam2() return _obj_getProp(self.handle, "CompEffectParam2"); end; +function gui.Control:setEffectParam2(param) _obj_setProp(self.handle, "CompEffectParam2", param); end; + +function gui.Control:getEffectParam3() return _obj_getProp(self.handle, "CompEffectParam3"); end; +function gui.Control:setEffectParam3(param) _obj_setProp(self.handle, "CompEffectParam3", param); end; + +function gui.Control:getEffectParam4() return _obj_getProp(self.handle, "CompEffectParam4"); end; +function gui.Control:setEffectParam4(param) _obj_setProp(self.handle, "CompEffectParam4", param); end; + +function gui.Control:findControlByName(controlName) return gui.findControlByName(controlName, self); end; + +function gui.Control:getGrid() + local cachedGrid = rawget(self, "__cachedGrid"); + + if cachedGrid == nil then + if __delayedGridLib == nil then + __delayedGridLib = require("rrpgGUI_grid.dlua"); + assert(__delayedGridLib ~= nil); + end; + + cachedGrid = __delayedGridLib.new(self); + rawset(self, "__cachedGrid", cachedGrid); + end; + + return cachedGrid; +end; + +function gui.Control:tryGetGrid() + return rawget(self, "__cachedGrid"); +end; + +function gui.Control:__objindex(key) + if type(key) == "string" then + if key == "g" then + return true, self.grid.role; + end; + + local gridPropName = string.match(key, "^g%-(.+)$"); + + if gridPropName ~= nil then + return true, self.grid[gridPropName]; + end; + end; + + return false; +end; + +function gui.Control:__objnewindex(key, value) + if type(key) == "string" then + if key == "g" then + self.grid.role = value; + return true; + end; + + local gridPropName = string.match(key, "^g%-(.+)$"); + + if gridPropName ~= nil then + self.grid[gridPropName] = value; + return true; + end; + end; + + return false; +end; + +gui.Control.props["visible"] = {setter = "setVisible", getter = "getVisible", tipo = "bool"}; +gui.Control.props["align"] = {setter = "setAlign", getter = "getAlign", tipo = "enum", + values = {"none", "top", "left", "right", + "bottom", "client", "contents", "scale"}} + +gui.Control.props["enabled"] = {setter = "setEnabled", getter = "getEnabled", tipo = "bool"}; +gui.Control.props["left"] = {setter = "setLeft", getter = "getLeft", tipo = "double"}; +gui.Control.props["top"] = {setter = "setTop", getter = "getTop", tipo = "double"}; +gui.Control.props["right"] = {setter = "setRight", getter = "getRight", tipo = "double"}; +gui.Control.props["bottom"] = {setter = "setBottom", getter = "getBottom", tipo = "double"}; +gui.Control.props["width"] = {setter = "setWidth", getter = "getWidth", tipo = "double"}; +gui.Control.props["height"] = {setter = "setHeight", getter = "getHeight", tipo = "double"}; +gui.Control.props["hitTest"] = {setter = "setHitTest", getter = "getHitTest", tipo = "bool"}; +gui.Control.props["tabOrder"] = {setter = "setTabOrder", getter = "getTabOrder", tipo = "int"}; +gui.Control.props["opacity"] = {setter = "setOpacity", getter = "getOpacity", tipo = "double"}; +gui.Control.props["margins"] = {setter = "setMargins", getter = "getMargins", tipo = "bounds"}; +gui.Control.props["padding"] = {setter = "setPadding", getter = "getPadding", tipo = "bounds"}; +gui.Control.props["anchors"] = {setter = "setAnchors", getter = "getAnchors", tipo = "set", + values = {"left", "top", "right", "bottom"}}; + +gui.Control.props["canFocus"] = {setter = "setCanFocus", getter = "getCanFocus", tipo="bool"}; +gui.Control.props["rotationAngle"] = {setter = "setRotationAngle", getter = "getRotationAngle", tipo="double"}; +gui.Control.props["rotationCenterX"] = {setter = "setRotationCenterX", getter = "getRotationCenterX", tipo="double"}; +gui.Control.props["rotationCenterY"] = {setter = "setRotationCenterY", getter = "getRotationCenterY", tipo="double"}; +gui.Control.props["scaleX"] = {setter = "setScaleX", getter = "getScaleX", tipo="double"}; +gui.Control.props["scaleY"] = {setter = "setScaleY", getter = "getScaleY", tipo="double"}; +gui.Control.props["scale"] = {setter = "setScale", getter = "getScale", tipo="double"}; +gui.Control.props["parent"] = {setter = "setParent", getter = "getParent", tipo="table"}; + +gui.Control.props["cursor"] = {setter = "setCursor", getter = "getCursor", tipo="enum", + values={'default', 'arrow', 'handPoint', 'hourGlass', + 'IBeam', 'size', 'sizeNESW', 'sizeNS', + 'sizeNWSE', 'sizeWE', 'upArrow', + 'drag', 'noDrop', 'hSplit', 'vSplit', + 'multiDrag', 'sqlWait', 'no', 'appStart', + 'help', 'cross'}}; + +gui.Control.props["hint"] = {setter = "setHint", getter = "getHint", tipo="string"}; +gui.Control.props["grid"] = {getter = "getGrid", tipo="table"}; + +gui.Control.props["cacheMode"] = {readProp = "CacheMode", writeProp = "CacheMode", tipo = "enum", + values = {"none", "time"}}; + +gui.Control.eves["onResize"] = ""; +gui.Control.eves["onClick"] = "event"; +gui.Control.eves["onDblClick"] = "event"; +gui.Control.eves["onMouseDown"] = "event"; +gui.Control.eves["onMouseMove"] = "event"; +gui.Control.eves["onMouseUp"] = "event"; +gui.Control.eves["onMouseEnter"] = ""; +gui.Control.eves["onMouseLeave"] = ""; +gui.Control.eves["onEnter"] = ""; +gui.Control.eves["onExit"] = ""; +gui.Control.eves["onKeyDown"] = "event"; +gui.Control.eves["onKeyUp"] = "event"; +gui.Control.eves["onMenu"] = 'x, y, event'; +gui.Control.eves["onStartDrag"] = 'drag, x, y, event'; +gui.Control.eves["onStartDrop"] = 'drop, x, y, drag, event'; + +local function controlFromHandle(handle) + return gui.Control.fromHandle(handle); +end + +gui.controlFromHandle = controlFromHandle; + +--[[ Objeto Layout ]]-- + +gui.Layout = gui.Control.inherit(); +registerTag(gui.Layout, 'layout'); + +function gui.Layout:getFrameStyle() return _obj_getProp(self.handle, "FrameStyle"); end; +function gui.Layout:setFrameStyle(frameStyle) _obj_setProp(self.handle, "FrameStyle", frameStyle) end; + +function gui.Layout:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.Layout:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +gui.Layout.props["frameStyle"] = {setter = "setFrameStyle", getter = "getFrameStyle", tipo = "url"}; +gui.Layout.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; + + +--[[ Objeto Row ]]-- + +gui.Row = gui.Layout.inherit(); +registerTag(gui.Row, 'row'); + +--[[ Objeto Col ]]-- + +gui.Col = gui.Layout.inherit(); +registerTag(gui.Col, 'col'); + +--[[ Objeto Container ]]-- + +gui.Container = gui.Layout.inherit(); +registerTag(gui.Container, 'container'); + +--[[ Objeto Form Layout ]]-- + +local function __atualizarLockPopupWithTopStack(lockPopup) + local topStack = lockPopup.__topStackStatus; + + if topStack ~= nil then + lockPopup.__label.text = topStack.msg; + lockPopup.__label.visible = topStack.msg ~= ""; + end; +end; + +local function __lockFormWithActivity(form, msg) + local thePopup = rawget(form, "__lockWithActivityPopup"); + + if thePopup == nil then + -- criar o popup de lock + thePopup = gui.newPopup(); + thePopup.width = 280; + thePopup.height = 50; + thePopup.cancelable = false; + thePopup.drawContainer = false; + thePopup.autoScopeNode = false; + + thePopup.__indicator = gui.newActivityIndicator(); + thePopup.__indicator.align = "client"; + thePopup.__indicator.parent = thePopup; + + thePopup.__label = gui.newLabel(); + thePopup.__label.vertTextAlign = "leading"; + thePopup.__label.horzTextAlign = "center"; + thePopup.__label.autoSize = true; + thePopup.__label.wordWrap = true; + thePopup.__label.align = "bottom"; + thePopup.__label.parent = thePopup; + thePopup.__label.fontSize = 15; + + thePopup.parent = form; + rawset(form, "__lockWithActivityPopup", thePopup); + end; + + local stackStatus = {}; + stackStatus.msg = msg or ""; + stackStatus.anterior = thePopup.__topStackStatus; + thePopup.__topStackStatus = stackStatus; + + __atualizarLockPopupWithTopStack(thePopup); + + if not stackStatus.anterior then + -- Primeira chamada + thePopup.__indicator.enabled = true; + thePopup:show("center", form); + end; +end; + +local function __reallyCloseLockPopup(form, lockPopup) + lockPopup.__indicator.enabled = false; + lockPopup:close(); + rawset(form, "__lockWithActivityPopup", nil); -- Permitir o garbage collector coletar + + setTimeout(function() + lockPopup.parent = nil; + lockPopup.__label.parent = nil; + lockPopup.__indicator.parent = nil; + end, 3000); +end; + +local function __unlockFormWithActivity(form) + local thePopup = rawget(form, "__lockWithActivityPopup"); + + if thePopup == nil then + return true; + end; + + local topStack = thePopup.__topStackStatus; + + if topStack ~= nil then + topStack = topStack.anterior; + thePopup.__topStackStatus = topStack; + end; + + if topStack ~= nil then + __atualizarLockPopupWithTopStack(thePopup); + return false; + else + __reallyCloseLockPopup(form, thePopup); + return true; + end; +end; + +gui.Form = gui.Layout.inherit(); +registerTag(gui.Form, 'form'); + +function gui.Form:initialize() + rawset(self, "__isFormFlag", true); +end; + +function gui.Form:getWidth() return _obj_getProp(self.handle, "FormWidth"); end; +function gui.Form:setWidth(v) _obj_setProp(self.handle, "FormWidth", v); end; + +function gui.Form:getHeight() return _obj_getProp(self.handle, "FormHeight"); end; +function gui.Form:setHeight(v) _obj_setProp(self.handle, "FormHeight", v); end; + +function gui.Form:getLeft() return _obj_getProp(self.handle, "FormLeft"); end; +function gui.Form:setLeft(v) _obj_setProp(self.handle, "FormLeft", v); end; + +function gui.Form:getTop() return _obj_getProp(self.handle, "FormTop"); end; +function gui.Form:setTop(v) _obj_setProp(self.handle, "FormTop", v); end; + +function gui.Form:getTitle() return _obj_getProp(self.handle, "Title"); end; +function gui.Form:setTitle(title) _obj_setProp(self.handle, "Title", title) end; + +function gui.Form:getDescription() return _obj_getProp(self.handle, "Description"); end; +function gui.Form:setDescription(desc) _obj_setProp(self.handle, "Description", desc) end; + +function gui.Form:getDataType() return _obj_getProp(self.handle, "DataType"); end; +function gui.Form:setDataType(dataType) _obj_setProp(self.handle, "DataType", dataType) end; + +function gui.Form:getFormType() return _obj_getProp(self.handle, "FormType"); end; +function gui.Form:setFormType(formType) _obj_setProp(self.handle, "FormType", formType) end; + +function gui.Form:getTheme() return _obj_getProp(self.handle, "Theme"); end; +function gui.Form:setTheme(theme) _obj_setProp(self.handle, "Theme", theme) end; + +function gui.Form:getLockWhileNodeIsLoading() return _obj_getProp(self.handle, "LockWhileNodeIsLoading"); end; +function gui.Form:setLockWhileNodeIsLoading(v) _obj_setProp(self.handle, "LockWhileNodeIsLoading", v) end; + +function gui.Form:getMinWidth() return _obj_getProp(self.handle, "MinWidth"); end; +function gui.Form:setMinWidth(v) _obj_setProp(self.handle, "MinWidth", v) end; + +function gui.Form:getMaxWidth() return _obj_getProp(self.handle, "MaxWidth"); end; +function gui.Form:setMaxWidth(v) _obj_setProp(self.handle, "MaxWidth", v) end; + +function gui.Form:setNodeObject(nodeObject) + rawset(self, "nodeObject", nodeObject); + _gui_assignNodeObject(self.handle, ndb.getNodeHandle(nodeObject)); +end; + +function gui.Form:getNodeObject() return rawget(self, "nodeObject") end; +function gui.Form:getNode() return self:getNodeObject(); end; +function gui.Form:setNode(node) self:setNodeObject(node); end; +function gui.Form:getScopeNode() return self:getNodeObject(); end; +function gui.Form:setScopeNode(node) self:setNodeObject(node); end; + +function gui.Form:lockWithActivity(msg) return __lockFormWithActivity(self, msg); end; +function gui.Form:unlockWithActivity() return __unlockFormWithActivity(self); end; + +gui.Form.props["title"] = {setter = "setTitle", getter = "getTitle", tipo = "string"}; +gui.Form.props["description"] = {setter = "setDescription", getter = "getDescription", tipo = "string"}; +gui.Form.props["dataType"] = {setter = "setDataType", getter = "getDataType", tipo = "string"}; +gui.Form.props["formType"] = {setter = "setFormType", getter = "getDataType", tipo = "enum", + values = {"undefined", "sheetTemplate", "tablesDock"}}; +gui.Form.props["theme"] = {setter = "setTheme", getter = "getTheme", tipo = "enum", + values = {"default", "light", "dark", "firecast"}}; +gui.Form.props["lockWhileNodeIsLoading"] = {setter = "setLockWhileNodeIsLoading", getter = "getLockWhileNodeIsLoading", tipo = "bool"}; +gui.Form.props["scopeNode"] = {setter = "setScopeNode", getter = "getScopeNode", tipo = "table"}; +gui.Form.props["minWidth"] = {setter = "setMinWidth", getter = "getMinWidth", tipo = "double"}; +gui.Form.props["maxWidth"] = {setter = "setMaxWidth", getter = "getMaxWidth", tipo = "double"}; +gui.Form.props["isShowing"] = {readProp = "IsShowing", tipo = "bool"}; + +gui.Form.eves["onScopeNodeChanged"] = ""; +gui.Form.eves["onShow"] = ""; +gui.Form.eves["onHide"] = ""; +gui.Form.eves["onNodeReady"] = ""; +gui.Form.eves["onNodeUnready"] = ""; +gui.Form.eves["onNodeChanged"] = ""; + +--[[ Objeto Popup Form ]]-- + +gui.PopupForm = gui.Form.inherit(); +registerTag(gui.PopupForm, 'popupForm'); + +function gui.PopupForm:getDrawContainer() return _obj_getProp(self.handle, "DrawContainer"); end; +function gui.PopupForm:setDrawContainer(v) _obj_setProp(self.handle, "DrawContainer", v); end; + +function gui.PopupForm:getCancelable() return _obj_getProp(self.handle, "Cancelable"); end; +function gui.PopupForm:setCancelable(v) _obj_setProp(self.handle, "Cancelable", v); end; + +function gui.PopupForm:getPlacement() return _obj_getProp(self.handle, "Placement"); end; +function gui.PopupForm:setPlacement(v) _obj_setProp(self.handle, "Placement", v); end; + +function gui.PopupForm:getResizable() return _obj_getProp(self.handle, "Resizable"); end; +function gui.PopupForm:setResizable(v) _obj_setProp(self.handle, "Resizable", v); end; + +function gui.PopupForm:show() return gui.showPopup(self); end; +function gui.PopupForm:close() return gui.closePopup(self); end; + +gui.PopupForm.props["drawContainer"] = {setter = "setDrawContainer", getter = "getDrawContainer", tipo = "bool"}; +gui.PopupForm.props["cancelable"] = {setter = "setCancelable", getter = "getCancelable", tipo = "bool"}; +gui.PopupForm.props["resizable"] = {setter = "setResizable", getter = "getResizable", tipo = "bool"}; +gui.PopupForm.props["movable"] = {readProp = "Movable", writeProp = "Movable", tipo = "bool"}; + +gui.PopupForm.props["placement"] = {setter = "setPlacement", getter = "getPlacement", tipo = "enum", + values = {"center", "bottom", "top", "left", "right", + "topLeft", "topRight", "bottomLeft", "bottomRight", "mouse", "mouseCenter"}}; + +gui.PopupForm.eves["onCancelRequest"] = ""; + +--[[ Objeto Flow Part ]]-- + +gui.FlowPart = gui.Layout.inherit(); +registerTag(gui.FlowPart, 'flowPart'); + +function gui.FlowPart:getMinWidth() return _obj_getProp(self.handle, "MinWidth"); end; +function gui.FlowPart:setMinWidth(value) _obj_setProp(self.handle, "MinWidth", value) end; + +function gui.FlowPart:getMinScaledWidth() return _obj_getProp(self.handle, "MinScaledWidth"); end; +function gui.FlowPart:setMinScaledWidth(value) _obj_setProp(self.handle, "MinScaledWidth", value) end; + +function gui.FlowPart:getMaxWidth() return _obj_getProp(self.handle, "MaxWidth"); end; +function gui.FlowPart:setMaxWidth(value) _obj_setProp(self.handle, "MaxWidth", value) end; + +function gui.FlowPart:getMaxScaledWidth() return _obj_getProp(self.handle, "MaxScaledWidth"); end; +function gui.FlowPart:setMaxScaledWidth(value) _obj_setProp(self.handle, "MaxScaledWidth", value) end; + +function gui.FlowPart:getAvoidScale() return _obj_getProp(self.handle, "AvoidScale"); end; +function gui.FlowPart:setAvoidScale(value) _obj_setProp(self.handle, "AvoidScale", value) end; + +function gui.FlowPart:getVertAlign() return _obj_getProp(self.handle, "VerticalAlign"); end; +function gui.FlowPart:setVertAlign(value) _obj_setProp(self.handle, "VerticalAlign", value) end; + +function gui.FlowPart:getStepSizes() return _obj_getProp(self.handle, "StepSizes"); end; +function gui.FlowPart:setStepSizes(value) _obj_setProp(self.handle, "StepSizes", value) end; + +function gui.FlowPart:getAdjustHeightToLine() return _obj_getProp(self.handle, "AdjustHeightToLine"); end; +function gui.FlowPart:setAdjustHeightToLine(value) _obj_setProp(self.handle, "AdjustHeightToLine", value) end; + +gui.FlowPart.props["minWidth"] = {setter = "setMinWidth", getter = "getMinWidth", tipo = "double"}; +gui.FlowPart.props["minScaledWidth"] = {setter = "setMinScaledWidth", getter = "getMinScaledWidth", tipo = "double"}; +gui.FlowPart.props["maxWidth"] = {setter = "setMaxWidth", getter = "getMaxWidth", tipo = "double"}; +gui.FlowPart.props["maxScaledWidth"] = {setter = "setMaxScaledWidth", getter = "getMaxScaledWidth", tipo = "double"}; +gui.FlowPart.props["avoidScale"] = {setter = "setAvoidScale", getter = "getAvoidScale", tipo = "bool"}; + +gui.FlowPart.props["vertAlign"] = {setter = "setVertAlign", getter = "getVertAlign", tipo = "enum", + values={"leading", "center", "trailing"}}; + +gui.FlowPart.props["stepSizes"] = {setter = "setStepSizes", getter = "getStepSizes", tipo = "table"}; +gui.FlowPart.props["adjustHeightToLine"] = {setter = "setAdjustHeightToLine", getter = "getAdjustHeightToLine", tipo = "bool"}; + +--[[ Objeto Flow Layout ]]-- + +gui.FlowLayout = gui.FlowPart.inherit(); +registerTag(gui.FlowLayout, 'flowLayout'); + +function gui.FlowLayout:getAutoHeight() return _obj_getProp(self.handle, "AutoHeight"); end; +function gui.FlowLayout:setAutoHeight(value) _obj_setProp(self.handle, "AutoHeight", value) end; + +function gui.FlowLayout:getHorzAlign() return _obj_getProp(self.handle, "HorzAlign"); end; +function gui.FlowLayout:setHorzAlign(value) _obj_setProp(self.handle, "HorzAlign", value) end; + +function gui.FlowLayout:getMaxControlsPerLine() return _obj_getProp(self.handle, "MaxControlsPerLine"); end; +function gui.FlowLayout:setMaxControlsPerLine(value) _obj_setProp(self.handle, "MaxControlsPerLine", value) end; + +function gui.FlowLayout:getLineSpacing() return _obj_getProp(self.handle, "LineSpacing"); end; +function gui.FlowLayout:setLineSpacing(value) _obj_setProp(self.handle, "LineSpacing", value) end; + +function gui.FlowLayout:getOrientation() return _obj_getProp(self.handle, "Orientation"); end; +function gui.FlowLayout:setOrientation(value) _obj_setProp(self.handle, "Orientation", value) end; + +function gui.FlowLayout:getMaxColumns() return _obj_getProp(self.handle, "MaxColumns"); end; +function gui.FlowLayout:setMaxColumns(value) _obj_setProp(self.handle, "MaxColumns", value) end; + +function gui.FlowLayout:needRealign() _obj_invoke(self.handle, "NeedRealign"); end; + +gui.FlowLayout.props["autoHeight"] = {setter = "setAutoHeight", getter = "getAutoHeight", tipo = "bool"}; +gui.FlowLayout.props["horzAlign"] = {setter = "setHorzAlign", getter = "getHorzAlign", tipo = "enum", + values={"leading", "center", "trailing", "justify"}}; + +gui.FlowLayout.props["maxControlsPerLine"] = {setter = "setMaxControlsPerLine", getter = "getMaxControlsPerLine", tipo = "int"}; +gui.FlowLayout.props["lineSpacing"] = {setter = "setLineSpacing", getter = "getLineSpacing", tipo = "double"}; +gui.FlowLayout.props["orientation"] = {setter = "setOrientation", getter = "getOrientation", tipo = "enum", + values={"horizontal", "vertical"}}; +gui.FlowLayout.props["maxColumns"] = {setter = "setMaxColumns", getter = "getMaxColumns", tipo = "int"}; +gui.FlowLayout.props["contentWidth"] = {readProp = "ContentWidth", tipo = "double"}; +gui.FlowLayout.props["contentHeight"] = {readProp = "ContentHeight", tipo = "double"}; + +gui.FlowLayout.eves["onBeforeLayoutCalc"] = ""; +gui.FlowLayout.eves["onAfterLayoutCalc"] = ""; + +--[[ Objeto Flow Line Break ]]-- + +gui.FlowLineBreak = gui.Control.inherit(); +registerTag(gui.FlowLineBreak, 'flowLineBreak'); + +function gui.FlowLineBreak:getHorzAlign() return _obj_getProp(self.handle, "HorzAlign"); end; +function gui.FlowLineBreak:setHorzAlign(value) _obj_setProp(self.handle, "HorzAlign", value) end; + +function gui.FlowLineBreak:getLineSpacing() return _obj_getProp(self.handle, "LineSpacing"); end; +function gui.FlowLineBreak:setLineSpacing(value) _obj_setProp(self.handle, "LineSpacing", value) end; + +gui.FlowLineBreak.props["horzAlign"] = {setter = "setHorzAlign", getter = "getHorzAlign", tipo = "enum", + values={"leading", "center", "trailing", "justify"}}; + +gui.FlowLineBreak.props["lineSpacing"] = {setter = "setLineSpacing", getter = "getLineSpacing", tipo = "double"}; + +--[[ Text Controls]]-- + +local function _addFontPropertiesToObject(ctrl) + function ctrl:getFontColor() return _obj_getProp(self.handle, "FontColor"); end; + function ctrl:setFontColor(color) _gui_prepareForFontColorChange(self.handle); _obj_setProp(self.handle, "FontColor", color); end; + + function ctrl:getFontFamily() return _obj_getProp(self.handle, "Font.Family"); end; + function ctrl:setFontFamily(family) _gui_prepareForFontFamilyChange(self.handle); _obj_setProp(self.handle, "Font.Family", family); end; + + function ctrl:getFontSize() return _obj_getProp(self.handle, "Font.Size"); end; + function ctrl:setFontSize(fontSize) _gui_prepareForFontSizeChange(self.handle); _obj_setProp(self.handle, "Font.Size", fontSize); end; + + function ctrl:getFontStyle() return _obj_getProp(self.handle, "Font.Style"); end; + function ctrl:setFontStyle(fontStyle) _gui_prepareForFontStyleChange(self.handle); _obj_setProp(self.handle, "Font.Style", fontStyle); end; + + function ctrl:getFontHeight() return _gui_getFontHeight(self.handle); end; + + ctrl.props["fontColor"] = {setter = "setFontColor", getter = "getFontColor", tipo = "color"}; + ctrl.props["fontFamily"] = {setter = "setFontFamily", getter = "getFontFamily", tipo = "string"}; + ctrl.props["fontSize"] = {setter = "setFontSize", getter = "getFontSize", tipo = "double"}; + ctrl.props["fontStyle"] = {setter = "setFontStyle", getter = "getFontStyle", tipo = "set", + values = {"bold", "italic", "underline", "strikeout"}}; + + return ctrl; +end; + +local function _addTextStylePropsToObject(ctrl) + function ctrl:getHorzTextAlign() return _obj_getProp(self.handle, "TextAlign"); end; + function ctrl:setHorzTextAlign(textAlign) return _obj_setProp(self.handle, "TextAlign", textAlign); end; + + function ctrl:getVertTextAlign() return _obj_getProp(self.handle, "VertTextAlign"); end; + function ctrl:setVertTextAlign(textAlign) return _obj_setProp(self.handle, "VertTextAlign", textAlign); end; + + function ctrl:getWordWrap() return _obj_getProp(self.handle, "WordWrap"); end; + function ctrl:setWordWrap(wrap) return _obj_setProp(self.handle, "WordWrap", wrap == true); end; + + function ctrl:getTextTrimming() return _obj_getProp(self.handle, "Trimming"); end; + function ctrl:setTextTrimming(trimming) return _obj_setProp(self.handle, "Trimming", trimming); end; + + ctrl.props["horzTextAlign"] = {setter = "setHorzTextAlign", getter="getHorzTextAlign", tipo="enum", + values = {"center", "leading", "trailing"}}; + + ctrl.props["vertTextAlign"] = {setter = "setVertTextAlign", getter="getVertTextAlign", tipo="enum", + values = {"center", "leading", "trailing"}}; + + ctrl.props["wordWrap"] = {setter = "setWordWrap", getter="getWordWrap", tipo="bool"}; + + ctrl.props["textTrimming"] = {setter = "setTextTrimming", getter="getTextTrimming", tipo="enum", + values = {"none", "character", "word"}} + + return ctrl; +end; + +local function _addEditablePropsToObject(ctrl) + function ctrl:getReadOnly() return _obj_getProp(self.handle, "ReadOnly"); end; + function ctrl:setReadOnly(readonly) return _obj_setProp(self.handle, "ReadOnly", readonly); end; + + ctrl.props["readOnly"] = {setter="setReadOnly", getter="getReadOnly", tipo="bool"}; + ctrl.eves["onChange"] = ""; + + return ctrl; +end + +gui.TextControl = gui.Control.inherit(); +_addFontPropertiesToObject(gui.TextControl); +_addTextStylePropsToObject(gui.TextControl); + +function gui.TextControl:getText() return _obj_getProp(self.handle, "Text"); end; +function gui.TextControl:setText(text) return _obj_setProp(self.handle, "Text", text); end; + +function gui.TextControl:getStyledSettings() return _obj_getProp(self.handle, "StyledSettings"); end; +function gui.TextControl:setStyledSettings(settings) return _obj_setProp(self.handle, "StyledSettings", settings); end; + +gui.TextControl.props["text"] = {setter = "setText", getter = "getText", tipo = "string"}; +gui.TextControl.props["styledSettings"] = {setter = "setStyledSettings", getter = "getStyledSettings", tipo="set", + values = {"family", "size", "style", "fontcolor", "other"}}; + +--[[ Objeto Button ]]-- + +gui.Button = gui.TextControl.inherit(); +registerTag(gui.Button, 'button'); + +--[[ Objeto Label ]]-- + +gui.Label = gui.TextControl.inherit(); +registerTag(gui.Label, 'label'); + +function gui.Label:getAutoSize() return _obj_getProp(self.handle, "AutoSize"); end; +function gui.Label:setAutoSize(v) _obj_setProp(self.handle, "AutoSize", v); end; + +function gui.Label:getField() return _gui_getFieldName(self.handle); end; +function gui.Label:setField(v) _gui_setFieldName(self.handle, v); end; + +function gui.Label:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.Label:setFrameRegion(v) _obj_setProp(self.handle, "FrameRegion", v); end; + +gui.Label.props["autoSize"] = {setter = "setAutoSize", getter = "getAutoSize", tipo = "bool"}; +gui.Label.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.Label.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; +gui.Label.props["format"] = {writeProp = "StringFormat", readProp = "StringFormat", tipo = "string"}; +gui.Label.props["formatFloat"] = {writeProp = "StringFormatFloat", readProp = "StringFormatFloat", tipo = "string"}; + +--[[ Objeto CheckBox ]]-- + +gui.CheckBox = gui.TextControl.inherit(); +registerTag(gui.CheckBox, 'checkBox'); + +function gui.CheckBox:getChecked() return _obj_getProp(self.handle, "IsChecked"); end; +function gui.CheckBox:setChecked(v) return _obj_setProp(self.handle, "IsChecked", v); end; + +function gui.CheckBox:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.CheckBox:setField(v) return _obj_setProp(self.handle, "FieldName", v); end; + +gui.CheckBox.props["checked"] = {setter = "setChecked", getter = "getChecked", tipo = "bool"}; +gui.CheckBox.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; + +gui.CheckBox.eves["onChange"] = ""; + +--[[ Objeto RadioButton ]]-- + +gui.RadioButton = gui.TextControl.inherit(); +registerTag(gui.RadioButton, 'radioButton'); + +function gui.RadioButton:getChecked() return _obj_getProp(self.handle, "IsChecked"); end; +function gui.RadioButton:setChecked(v) return _obj_setProp(self.handle, "IsChecked", v); end; + +function gui.RadioButton:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.RadioButton:setField(v) return _obj_setProp(self.handle, "FieldName", v); end; + +function gui.RadioButton:getFieldValue() return _obj_getProp(self.handle, "FieldValue"); end; +function gui.RadioButton:setFieldValue(v) return _obj_setProp(self.handle, "FieldValue", v); end; + +function gui.RadioButton:getGroupName() return _obj_getProp(self.handle, "GroupName"); end; +function gui.RadioButton:setGroupName(v) return _obj_setProp(self.handle, "GroupName", v); end; + +gui.RadioButton.props["checked"] = {setter = "setChecked", getter = "getChecked", tipo = "bool"}; +gui.RadioButton.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.RadioButton.props["fieldValue"] = {setter = "setFieldValue", getter = "getFieldValue", tipo = "string"}; +gui.RadioButton.props["groupName"] = {setter = "setGroupName", getter = "getGroupName", tipo = "string"}; + +gui.RadioButton.eves["onChange"] = ""; + +--[[ Objeto ImageCheckBox ]]-- + +gui.ImageCheckBox = gui.Control.inherit(); +registerTag(gui.ImageCheckBox, 'imageCheckBox'); + +function gui.ImageCheckBox:getChecked() return _obj_getProp(self.handle, "IsChecked"); end; +function gui.ImageCheckBox:setChecked(v) _obj_setProp(self.handle, "IsChecked", v); end; + +function gui.ImageCheckBox:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.ImageCheckBox:setField(v) _obj_setProp(self.handle, "FieldName", v); end; + +function gui.ImageCheckBox:getImageChecked() return _obj_getProp(self.handle, "ImageChecked"); end; +function gui.ImageCheckBox:setImageChecked(v) _obj_setProp(self.handle, "ImageChecked", v); end; + +function gui.ImageCheckBox:getImageUnchecked() return _obj_getProp(self.handle, "ImageUnchecked"); end; +function gui.ImageCheckBox:setImageUnchecked(v) _obj_setProp(self.handle, "ImageUnchecked", v); end; + +function gui.ImageCheckBox:getOptimize() return _obj_getProp(self.handle, "Optimize"); end; +function gui.ImageCheckBox:setOptimize(opt) return _obj_setProp(self.handle, "Optimize", opt); end; + +function gui.ImageCheckBox:getAutoChange() return _obj_getProp(self.handle, "AutoChange"); end; +function gui.ImageCheckBox:setAutoChange(v) return _obj_setProp(self.handle, "AutoChange", v); end; + +gui.ImageCheckBox.props["checked"] = {setter = "setChecked", getter = "getChecked", tipo = "bool"}; +gui.ImageCheckBox.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.ImageCheckBox.props["imageChecked"] = {setter = "setImageChecked", getter = "getImageChecked", tipo = "url"}; +gui.ImageCheckBox.props["checkedImage"] = {setter = "setImageChecked", getter = "getImageChecked", tipo = "url"}; +gui.ImageCheckBox.props["imageUnchecked"] = {setter = "setImageUnchecked", getter = "getImageUnchecked", tipo = "url"}; +gui.ImageCheckBox.props["uncheckedImage"] = {setter = "setImageUnchecked", getter = "getImageUnchecked", tipo = "url"}; +gui.ImageCheckBox.props["optimize"] = {setter = "setOptimize", getter = "getOptimize", tipo = "bool"}; +gui.ImageCheckBox.props["autoChange"] = {setter = "setAutoChange", getter = "getAutoChange", tipo = "bool"}; + +gui.ImageCheckBox.eves["onChange"] = ""; + +--[[ Objeto Image ]]-- + +gui.Image = gui.Control.inherit(); +registerTag(gui.Image, 'image'); + +function gui.Image:getImageURL() return _obj_getProp(self.handle, "URLImagem"); end; +function gui.Image:setImageURL(url) return _obj_setProp(self.handle, "URLImagem", url); end; + +function gui.Image:getURL() return _obj_getProp(self.handle, "URLImagem"); end; +function gui.Image:setURL(url) return _obj_setProp(self.handle, "URLImagem", url); end; + +function gui.Image:getSRC() return _obj_getProp(self.handle, "URLImagem"); end; +function gui.Image:setSRC(src) return _obj_setProp(self.handle, "URLImagem", src); end; + +function gui.Image:getShowStyle() return _obj_getProp(self.handle, "ShowStyle"); end; +function gui.Image:setShowStyle(showStyle) return _obj_setProp(self.handle, "ShowStyle", showStyle); end; + +function gui.Image:getStyle() return _obj_getProp(self.handle, "ShowStyle"); end; +function gui.Image:setStyle(style) return _obj_setProp(self.handle, "ShowStyle", style); end; + +function gui.Image:getCenter() return _obj_getProp(self.handle, "Center"); end; +function gui.Image:setCenter(center) return _obj_setProp(self.handle, "Center", center); end; + +function gui.Image:getOptimizeQuality() return _obj_getProp(self.handle, "OtimizarDesenho"); end; +function gui.Image:setOptimizeQuality(opt) return _obj_setProp(self.handle, "OtimizarDesenho", opt); end; +function gui.Image:getOptimize() return _obj_getProp(self.handle, "OtimizarDesenho"); end; +function gui.Image:setOptimize(opt) return _obj_setProp(self.handle, "OtimizarDesenho", opt); end; + +function gui.Image:getShowProgress() return _obj_getProp(self.handle, "ExibirProgresso"); end; +function gui.Image:setShowProgress(showProgress) return _obj_setProp(self.handle, "ExibirProgresso", showProgress); end; + +function gui.Image:getURLWhileLoading() return _obj_getProp(self.handle, "NoImageURL"); end; +function gui.Image:setURLWhileLoading(url) return _obj_setProp(self.handle, "NoImageURL", url); end; + +function gui.Image:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.Image:setField(v) _obj_setProp(self.handle, "FieldName", v); end; + +function gui.Image:getEditable() return _obj_getProp(self.handle, "Editable"); end; +function gui.Image:setEditable(v) _obj_setProp(self.handle, "Editable", v); end; + +function gui.Image:getNaturalWidth() return _obj_getProp(self.handle, "NaturalWidth"); end; +function gui.Image:getNaturalHeight() return _obj_getProp(self.handle, "NaturalHeight"); end; + +gui.Image.props["imageURL"] = {setter = "setImageURL", getter="getImageURL", tipo="url"}; +gui.Image.props["url"] = {setter = "setURL", getter="getURL", tipo="url"}; +gui.Image.props["src"] = {setter = "setSRC", getter="getSRC", tipo="url"}; +gui.Image.props["URLWhileLoading"] = {setter = "setURLWhileLoading", getter="getURLWhileLoading", tipo="url"}; + +gui.Image.props["showStyle"] = {setter = "setShowStyle", getter="getShowStyle", tipo="enum", + values = {"proportional", "autoFit", "originalSize", "stretch"}}; +gui.Image.props["style"] = {setter = "setStyle", getter="getStyle", tipo="enum", + values = {"proportional", "autoFit", "originalSize", "stretch"}}; + +gui.Image.props["center"] = {setter = "setCenter", getter="getCenter", tipo="bool"}; +gui.Image.props["optimizeQuality"] = {setter = "setOptimizeQuality", getter="getOptimizeQuality", tipo="bool"}; +gui.Image.props["optimize"] = {setter = "setOptimize", getter="getOptimize", tipo="bool"}; +gui.Image.props["showProgress"] = {setter = "setShowProgress", getter="getShowProgress", tipo="bool"}; +gui.Image.props["field"] = {setter = "setField", getter="getField", tipo="string"}; +gui.Image.props["editable"] = {setter = "setEditable", getter="getEditable", tipo="bool"}; +gui.Image.props["naturalAnimated"] = {readProp="NaturalAnimated", tipo="bool"}; +gui.Image.props["naturalWidth"] = {getter="getNaturalWidth", tipo="double"}; +gui.Image.props["naturalHeight"] = {getter="getNaturalHeight", tipo="double"}; +gui.Image.props["animate"] = {readProp="Animate", writeProp="Animate", tipo="bool"}; + +gui.Image.eves["onPictureLoadedChange"] = ""; +gui.Image.eves["onLoad"] = ""; + +--[[ Objeto Edit ]]-- + +gui.Edit = gui.TextControl.inherit(); +registerTag(gui.Edit, 'edit'); + +_addEditablePropsToObject(gui.Edit); + +function gui.Edit:getTextPrompt() return _obj_getProp(self.handle, "TextPrompt"); end; +function gui.Edit:setTextPrompt(text) _obj_setProp(self.handle, "TextPrompt", text); end; + +function gui.Edit:getTransparent() _obj_getProp(self.handle, "Transparent"); end; +function gui.Edit:setTransparent(transparent) _obj_setProp(self.handle, "Transparent", transparent); end; + +function gui.Edit:getIsPasswordEdit() return _obj_getProp(self.handle, "Password"); end; +function gui.Edit:setIsPasswordEdit(isPasswordEdit) _obj_setProp(self.handle, "Password", isPasswordEdit); end; + +function gui.Edit:getKeyboardType() return _obj_getProp(self.handle, "KeyboardType"); end; +function gui.Edit:setKeyboardType(kbtype) _obj_setProp(self.handle, "KeyboardType", kbtype); end; + +function gui.Edit:getEnterKeyType() return _obj_getProp(self.handle, "ReturnKeyType"); end; +function gui.Edit:setEnterKeyType(enterType) _obj_setProp(self.handle, "ReturnKeyType", enterType); end; + +function gui.Edit:getField() return _gui_getFieldName(self.handle); end; +function gui.Edit:setField(field) _gui_setFieldName(self.handle, field); end; + +function gui.Edit:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.Edit:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +function gui.Edit:getType() return _obj_getProp(self.handle, "EditType"); end; +function gui.Edit:setType(v) _obj_setProp(self.handle, "EditType", v) end; + +function gui.Edit:getMin() return _obj_getProp(self.handle, "MinValue"); end; +function gui.Edit:setMin(v) _obj_setProp(self.handle, "MinValue", v) end; + +function gui.Edit:getMax() return _obj_getProp(self.handle, "MaxValue"); end; +function gui.Edit:setMax(v) _obj_setProp(self.handle, "MaxValue", v) end; + +function gui.Edit:getDecimalPlaces() return _obj_getProp(self.handle, "DecimalPlaces"); end; +function gui.Edit:setDecimalPlaces(v) _obj_setProp(self.handle, "DecimalPlaces", v) end; + +function gui.Edit:getAsNumber() return _obj_getProp(self.handle, "AsNumber"); end; +function gui.Edit:setAsNumber(v) _obj_setProp(self.handle, "AsNumber", v) end; + +gui.Edit.props["textPrompt"] = {setter="setTextPrompt", getter="getTextPrompt", tipo="string"}; +gui.Edit.props["transparent"] = {setter="setTransparent", getter="getTransparent", tipo="bool"}; +gui.Edit.props["isPasswordEdit"] = {setter="setIsPasswordEdit", getter="getIsPasswordEdit", tipo="bool"}; + +gui.Edit.props["keyboardType"] = {setter="setKeyboardType", getter="getKeyboardType", tipo="enum", + values = {"default", "numbersAndPunctuation", "numberPad", + "phonePad", "alphabet", "url", "email"}}; + +gui.Edit.props["enterKeyType"] = {setter="setEnterKeyType", getter="getEnterKeyType", tipo="enum", + values = {"default", "done", "go", "next", "search", "send"}}; + +gui.Edit.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.Edit.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; +gui.Edit.props["type"] = {setter = "setType", getter = "getType", tipo = "enum", values = {"text", "number", "float"}}; +gui.Edit.props["min"] = {setter = "setMin", getter = "getMin", tipo = "double"}; +gui.Edit.props["max"] = {setter = "setMax", getter = "getMax", tipo = "double"}; +gui.Edit.props["decimalPlaces"] = {setter = "setDecimalPlaces", getter = "getDecimalPlaces", tipo = "int"}; +gui.Edit.props["asNumber"] = {setter = "setAsNumber", getter = "getAsNumber", tipo = "double"}; + +gui.Edit.eves["onUserChange"] = ""; + +--[[ Objeto ComboBox ]]-- + +gui.ComboBox = gui.Control.inherit(); +registerTag(gui.ComboBox, 'comboBox'); + +_addFontPropertiesToObject(gui.ComboBox); +_addTextStylePropsToObject(gui.ComboBox); + +function gui.ComboBox:getTransparent() _obj_getProp(self.handle, "Transparent"); end; +function gui.ComboBox:setTransparent(transparent) _obj_setProp(self.handle, "Transparent", transparent); end; + +function gui.ComboBox:getField() return _gui_getFieldName(self.handle); end; +function gui.ComboBox:setField(field) _gui_setFieldName(self.handle, field); end; + +function gui.ComboBox:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.ComboBox:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +function gui.ComboBox:getText() return _obj_getProp(self.handle, "Text"); end; +function gui.ComboBox:setText(v) _obj_setProp(self.handle, "Text", v) end; + +function gui.ComboBox:getValue() return _obj_getProp(self.handle, "Value"); end; +function gui.ComboBox:setValue(v) _obj_setProp(self.handle, "Value", v) end; + +function gui.ComboBox:getItems() return _obj_getProp(self.handle, "ItemsI18N"); end; +function gui.ComboBox:setItems(v) _obj_setProp(self.handle, "ItemsI18N", v) end; + +function gui.ComboBox:getValues() return _obj_getProp(self.handle, "Values"); end; +function gui.ComboBox:setValues(v) _obj_setProp(self.handle, "Values", v) end; + +function gui.ComboBox:dropDown() _obj_invoke(self.handle, "InvokeDropDown"); end; + +gui.ComboBox.props["transparent"] = {setter="setTransparent", getter="getTransparent", tipo="bool"}; +gui.ComboBox.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.ComboBox.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; +gui.ComboBox.props["items"] = {setter = "setItems", getter = "getItems", tipo = "table"}; +gui.ComboBox.props["values"] = {setter = "setValues", getter = "getValues", tipo = "table"}; +gui.ComboBox.props["text"] = {setter = "setText", getter = "getText", tipo = "string"}; +gui.ComboBox.props["value"] = {setter = "setValue", getter = "getValue", tipo = "string"}; + +gui.ComboBox.eves["onChange"] = ""; + +--[[ Objeto ColorComboBox ]]-- + +gui.ColorComboBox = gui.Control.inherit(); +registerTag(gui.ColorComboBox, 'colorComboBox'); + +function gui.ColorComboBox:getColor() return _obj_getProp(self.handle, "Color"); end; +function gui.ColorComboBox:setColor(v) _obj_setProp(self.handle, "Color", v); end; + +function gui.ColorComboBox:getUseAlpha() return _obj_getProp(self.handle, "UseAlpha"); end; +function gui.ColorComboBox:setUseAlpha(v) _obj_setProp(self.handle, "UseAlpha", v); end; + +function gui.ColorComboBox:getField() return _gui_getFieldName(self.handle); end; +function gui.ColorComboBox:setField(field) _gui_setFieldName(self.handle, field); end; + +function gui.ColorComboBox:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.ColorComboBox:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +function gui.ColorComboBox:dropDown() _obj_invoke(self.handle, "InvokeDropDown"); end; + +gui.ColorComboBox.props["color"] = {setter="setColor", getter="getColor", tipo="color"}; +gui.ColorComboBox.props["useAlpha"] = {setter = "setUseAlpha", getter = "getUseAlpha", tipo = "bool"}; +gui.ColorComboBox.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.ColorComboBox.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; + +gui.ColorComboBox.eves["onChange"] = ""; +gui.ColorComboBox.eves["onUserChange"] = ""; + +--[[ Objeto TextEditor ]]-- + +gui.TextEditor = gui.TextControl.inherit(); +registerTag(gui.TextEditor, 'textEditor'); + +_addEditablePropsToObject(gui.TextEditor); + +function gui.TextEditor:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.TextEditor:setField(v) _obj_setProp(self.handle, "FieldName", v); end; + +function gui.TextEditor:getTransparent() return _obj_getProp(self.handle, "Transparent"); end; +function gui.TextEditor:setTransparent(v) _obj_setProp(self.handle, "Transparent", v); end; + +gui.TextEditor.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.TextEditor.props["transparent"] = {setter="setTransparent", getter="getTransparent", tipo="bool"}; + +--[[ Objeto TabControl ]]-- + +gui.TabControl = gui.Control.inherit(); +registerTag(gui.TabControl, 'tabControl'); + +function gui.TabControl:getTabIndex() return _obj_getProp(self.handle, "TabIndex"); end; +function gui.TabControl :setTabIndex(idx) _obj_setProp(self.handle, "TabIndex", idx); end; + +gui.TabControl .props["tabIndex"] = {setter="setTabIndex", getter="getTabIndex", tipo="int"}; + +--[[ Objeto Tab / TabItem ]]-- + +gui.TabItem = gui.Control.inherit(); +registerTag(gui.TabItem, 'tab'); + +function gui.TabItem:getText() return _obj_getProp(self.handle, "Title"); end; +function gui.TabItem:setText(text) _obj_setProp(self.handle, "Title", text); end; + +function gui.TabItem:getTitle() return _obj_getProp(self.handle, "Title"); end; +function gui.TabItem:setTitle(title) _obj_setProp(self.handle, "Title", title); end; +function gui.TabItem:activate() _obj_invoke(self.handle, "Activate"); end; + +gui.TabItem.props["text"] = {setter="setText", getter="getText", tipo="string"}; +gui.TabItem.props["title"] = {setter="setTitle", getter="getTitle", tipo="string"}; + +--[[ Objeto ScrollBox ]]-- + +gui.ScrollBox = gui.Control.inherit(); +registerTag(gui.ScrollBox, 'scrollBox'); + +--[[ Objeto Shape ]]-- + +gui.Shape = gui.Control.inherit(); + +function gui.Shape:getColor() return _obj_getProp(self.handle, "Fill.Color"); end; +function gui.Shape:setColor(color) _gui_shapeSetFillColor(self.handle, color); end; + +function gui.Shape:getStrokeColor() return _obj_getProp(self.handle, "Stroke.Color"); end; +function gui.Shape:setStrokeColor(color) _gui_shapeSetStrokeColor(self.handle, color); end; + +function gui.Shape:getStrokeSize() return _obj_getProp(self.handle, "Stroke.Thickness"); end; +function gui.Shape:setStrokeSize(size) _gui_shapeSetStrokeSize(self.handle, size); end; + +function gui.Shape:getStrokeCap() return _obj_getProp(self.handle, "Stroke.Cap"); end; +function gui.Shape:setStrokeCap(v) _gui_shapeSetStrokeCap(self.handle, v); end; + +function gui.Shape:getStrokeJoin() return _obj_getProp(self.handle, "Stroke.Join"); end; +function gui.Shape:setStrokeJoin(v) _gui_shapeSetStrokeCap(self.handle, v); end; + +function gui.Shape:getStrokeDash() return _obj_getProp(self.handle, "Stroke.Dash"); end; +function gui.Shape:setStrokeDash(v) _gui_shapeSetStrokeCap(self.handle, v); end; + +gui.Shape.props["color"] = {setter="setColor", getter="getColor", tipo="color"}; +gui.Shape.props["strokeColor"] = {setter="setStrokeColor", getter="getStrokeColor", tipo="color"}; +gui.Shape.props["strokeSize"] = {setter="setStrokeSize", getter="getStrokeSize", tipo="double"}; + +gui.Shape.props["strokeCap"] = {setter="setStrokeCap", getter="getStrokeCap", tipo="enum", + values={"flat", "round"}}; + +gui.Shape.props["strokeJoin"] = {setter="setStrokeJoin", getter="getStrokeJoin", tipo="enum", + values={"miter", "round", "bevel"}}; + +gui.Shape.props["strokeDash"] = {setter="setStrokeDash", getter="getStrokeDash", tipo="enum", + values={"solid", "dash", "dot", "dashDot", "dashDotDot"}}; + +--[[ Objeto Rectangle ]]-- + +gui.Rectangle = gui.Shape.inherit(); +registerTag(gui.Rectangle, 'rectangle'); + +function gui.Rectangle:getCorners() return _obj_getProp(self.handle, "Corners"); end; +function gui.Rectangle:setCorners(corners) _obj_setProp(self.handle, "Corners", corners); end; + +function gui.Rectangle:getCornerType() return _obj_getProp(self.handle, "CornerType"); end; +function gui.Rectangle:setCornerType(cornerType) _obj_setProp(self.handle, "CornerType", cornerType); end; + +function gui.Rectangle:getSides() return _obj_getProp(self.handle, "CornerType"); end; +function gui.Rectangle:setSides(sides) _obj_setProp(self.handle, "Sides", sides); end; + +function gui.Rectangle:getXradius() return _obj_getProp(self.handle, "XRadius"); end; +function gui.Rectangle:setXradius(xradius) _obj_setProp(self.handle, "XRadius", xradius); end; + +function gui.Rectangle:getYradius() return _obj_getProp(self.handle, "YRadius"); end; +function gui.Rectangle:setYradius(yradius) _obj_setProp(self.handle, "YRadius", yradius); end; + +gui.Rectangle.props["corners"] = {setter="setCorners", getter="getCorners", tipo="set", + values={"topLeft", "topRight", "bottomLeft", "bottomRight"}}; + +gui.Rectangle.props["cornerType"] = {setter="setCornerType", getter="getCornerType", tipo="enum", + values={"round", "bevel", "innerRound", "innerLine"}}; + +gui.Rectangle.props["sides"] = {setter="setSides", getter="getSides", tipo="set", + values={"top", "left", "bottom", "right"}}; + +gui.Rectangle.props["xradius"] = {setter="setXradius", getter="getXradius", tipo="double"}; +gui.Rectangle.props["yradius"] = {setter="setYradius", getter="getYradius", tipo="double"}; + +--[[ Objeto Path ]]-- + +gui.Path = gui.Shape.inherit(); +registerTag(gui.Path, 'path'); + +function gui.Path:getPathData() return _obj_getProp(self.handle, "PathData"); end; +function gui.Path:setPathData(v) _obj_setProp(self.handle, "PathData", v); end; + +function gui.Path:getMode() return _obj_getProp(self.handle, "WrapMode"); end; +function gui.Path:setMode(v) _obj_setProp(self.handle, "WrapMode", v); end; + +function gui.Path:getRoundToPixel() return _obj_getProp(self.handle, "RoundToPixels"); end; +function gui.Path:setRoundToPixel(v) _obj_setProp(self.handle, "RoundToPixels", v); end; + +gui.Path.props["data"] = {setter="setPathData", getter="getPathData", tipo="string"}; +gui.Path.props["pathData"] = gui.Path.props["data"] + +gui.Path.props["mode"] = {setter="setMode", getter="getMode", tipo="enum", + values={"original", "fit", "stretch", "tile"}}; + +gui.Path.props["wrapMode"] = gui.Path.props["mode"] +gui.Path.props["roundToPixel"] = {setter="setRoundToPixel", getter="getRoundToPixel", tipo="bool"}; + +--[[ Objeto HorzLine ]]-- + +gui.HorzLine = gui.Shape.inherit(); +registerTag(gui.HorzLine, 'horzLine'); + +--[[ Objeto Frame ]]-- + +gui.Frame = gui.Layout.inherit(); +registerTag(gui.Frame, 'frame'); + +function gui.Frame:getURL() return _obj_getProp(self.handle, "FrameURL"); end; +function gui.Frame:setURL(url) _obj_setProp(self.handle, "FrameURL", url); end; + +function gui.Frame:getFrameStyle() return _obj_getProp(self.handle, "FrameURL"); end; +function gui.Frame:setFrameStyle(frameStyle) _obj_setProp(self.handle, "FrameURL", frameStyle); end; + +function gui.Frame:getSrc() return _obj_getProp(self.handle, "FrameURL"); end; +function gui.Frame:setSrc(url) _obj_setProp(self.handle, "FrameURL", url); end; + +gui.Frame.props["url"] = {setter="setURL", getter="getURL", tipo="url"}; +gui.Frame.props["frameStyle"] = {setter="setFrameStyle", getter="getFrameStyle", tipo="url"}; +gui.Frame.props["src"] = {setter="setSrc", getter="getSrc", tipo="url"}; + + +--[[ Objeto DataLink ]]-- + +gui.DataLink = objs.HierarchyObject.inherit(); +registerTag(gui.DataLink, 'dataLink'); + +function gui.DataLink:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.DataLink:setField(v) return _obj_setProp(self.handle, "FieldName", v); end; + +function gui.DataLink:getFields() return _obj_getProp(self.handle, "Fields"); end; +function gui.DataLink:setFields(v) return _obj_setProp(self.handle, "Fields", v); end; + +function gui.DataLink:getDefaultValue() return _obj_getProp(self.handle, "DefaultValue"); end; +function gui.DataLink:setDefaultValue(v) return _obj_setProp(self.handle, "DefaultValue", v); end; + +function gui.DataLink:getDefaultValues() return _obj_getProp(self.handle, "DefaultValues"); end; +function gui.DataLink:setDefaultValues(v) return _obj_setProp(self.handle, "DefaultValues", v); end; + +function gui.DataLink:beginUpdate() end; +function gui.DataLink:endUpdate() end; + +gui.DataLink.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.DataLink.props["fields"] = {setter = "setFields", getter = "getFields", tipo = "table"}; +gui.DataLink.props["defaultValue"] = {setter = "setDefaultValue", getter = "getDefaultValue", tipo = "string"}; +gui.DataLink.props["defaultValues"] = {setter = "setDefaultValues", getter = "getDefaultValues", tipo = "table"}; + +gui.DataLink.eves["onChange"] = "field, oldValue, newValue"; +gui.DataLink.eves["onPersistedChange"] = "field, oldValue, newValue"; +gui.DataLink.eves["onUserChange"] = "field, oldValue, newValue"; +gui.DataLink.eves["onChildAdded"] = "node"; +gui.DataLink.eves["onChildRemoved"] = "node"; + +--[[ Objeto Record List ]]-- + +gui.RecordList = gui.Layout.inherit(); +registerTag(gui.RecordList, 'recordList'); + +function gui.RecordList:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.RecordList:setField(v) _obj_setProp(self.handle, "FieldName", v) end; + +function gui.RecordList:getItemHeight() return _obj_getProp(self.handle, "ItemHeight"); end; +function gui.RecordList:setItemHeight(v) _obj_setProp(self.handle, "ItemHeight", v) end; + +function gui.RecordList:getMinHeight() return _obj_getProp(self.handle, "MinHeight"); end; +function gui.RecordList:setMinHeight(v) _obj_setProp(self.handle, "MinHeight", v) end; + +function gui.RecordList:getMinQt() return _obj_getProp(self.handle, "MinQt"); end; +function gui.RecordList:setMinQt(v) _obj_setProp(self.handle, "MinQt", v) end; + +function gui.RecordList:getAutoHeight() return _obj_getProp(self.handle, "AutoHeight"); end; +function gui.RecordList:setAutoHeight(v) _obj_setProp(self.handle, "AutoHeight", v) end; + +function gui.RecordList:getTemplateForm() return _obj_getProp(self.handle, "TemplateForm"); end; +function gui.RecordList:setTemplateForm(v) _obj_setProp(self.handle, "TemplateForm", v); end; + +function gui.RecordList:getLayout() return _obj_getProp(self.handle, "RecordListLayout"); end; +function gui.RecordList:setLayout(v) _obj_setProp(self.handle, "RecordListLayout", v); end; + +function gui.RecordList:getSelectable() return _obj_getProp(self.handle, "SelectableList"); end; +function gui.RecordList:setSelectable(v) _obj_setProp(self.handle, "SelectableList", v); end; + +function gui.RecordList:append() return ndb.openNodeFacade(_obj_invokeEx(self.handle, "AppendItemEx")); end; + +function gui.RecordList:getSelectedNode() return ndb.openNodeFacade(_gui_recordListGetSelectedNodeHandle(self.handle)); end; +function gui.RecordList:setSelectedNode(node) _gui_recordListSetSelectedNodeHandle(self.handle, ndb.getNodeHandle(node)); end; + +function gui.RecordList:getSelectedForm() return objs.tryFindFromHandle(_gui_recordListGetSelectedFormHandle(self.handle)); end; + +function gui.RecordList:scrollToNode(node) _gui_recordListScrollToNodeHandle(self.handle, ndb.getNodeHandle(node)); end; +function gui.RecordList:sort() _obj_invoke(self.handle, "ReorganizarItens"); end; + +function gui.RecordList:getChildren() + local ret = {}; + local childCount = _obj_getProp(self.handle, "ChildFormCount"); + local child; + local childHandle; + local idxDest = 1; + + for i = 0, childCount - 1, 1 do + childHandle = _gui_rcl_getChild(self.handle, i); + + if (childHandle ~= nil) then + child = gui.fromHandle(childHandle); + + if (type(child) == "table") then + ret[idxDest] = child; + idxDest = idxDest + 1; + end + end; + end + + return ret; +end; + +gui.RecordList.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.RecordList.props["templateForm"] = {setter = "setTemplateForm", getter = "getTemplateForm", tipo = "string"}; +gui.RecordList.props["itemHeight"] = {setter = "setItemHeight", getter = "getItemHeight", tipo = "double"}; +gui.RecordList.props["minHeight"] = {setter = "setMinHeight", getter = "getMinHeight", tipo = "double"}; +gui.RecordList.props["autoHeight"] = {setter = "setAutoHeight", getter = "getAutoHeight", tipo = "bool"}; +gui.RecordList.props["minQt"] = {setter = "setMinQt", getter = "getMinQt", tipo = "int"}; +gui.RecordList.props["layout"] = {setter = "setLayout", getter = "getLayout", tipo = "enum", + values = {"vertical", "horizontal", "horizontalTiles", "verticalTiles"}}; +gui.RecordList.props["selectable"] = {setter = "setSelectable", getter = "getSelectable", tipo = "bool"}; + +gui.RecordList.props["selectedNode"] = {getter = "getSelectedNode", setter="setSelectedNode", tipo = "table"}; +gui.RecordList.props["selectedForm"] = {getter = "getSelectedForm", tipo = "table"}; + +gui.RecordList.eves["onSelect"] = ""; +gui.RecordList.eves["onBeginEnumeration"] = ""; +gui.RecordList.eves["onItemAdded"] = "node, form"; +gui.RecordList.eves["onItemRemoved"] = "node, form"; +gui.RecordList.eves["onEndEnumeration"] = ""; +gui.RecordList.eves["onCompare"] = "nodeA, nodeB"; + +--[[ Objeto GridRecordList ]]-- + +gui.GridRecordList = gui.Layout.inherit(); +registerTag(gui.GridRecordList, 'gridRecordList'); + +function gui.GridRecordList:append() return ndb.openNodeFacade(_obj_invokeEx(self.handle, "AppendItemEx")); end; +function gui.GridRecordList:reorganize() _obj_invoke(self.handle, "Reorganize"); end; +function gui.GridRecordList:getChildren() return _gui_getChildrenObj(self.handle); end; +function gui.GridRecordList:getSelectedNode() return _obj_invokeEx(self.handle, "GetSelectedNodeEx"); end; +function gui.GridRecordList:setSelectedNode(node) _obj_invokeEx(self.handle, "SetSelectedNodeEx", node); end; +function gui.GridRecordList:getSelectedForm() return _obj_invokeEx(self.handle, "GetSelectedFormEx"); end; +function gui.GridRecordList:scrollToNode(node) _obj_invokeEx(self.handle, "ScrollToNodeEx", node); end; + +gui.GridRecordList.props["field"] = {writeProp = "DataFieldName", readProp = "DataFieldName", tipo = "string"}; +gui.GridRecordList.props["templateForm"] = {writeProp = "TemplateForm", readProp = "TemplateForm", tipo = "string"}; +gui.GridRecordList.props["minQt"] = {writeProp = "MinQuantity", readProp = "MinQuantity", tipo = "int"}; +gui.GridRecordList.props["selectable"] = {writeProp = "IsSelectableList", readProp = "IsSelectableList", tipo = "bool"}; +gui.GridRecordList.props["selectedNode"] = {getter = "getSelectedNode", setter="setSelectedNode", tipo = "table"}; +gui.GridRecordList.props["paging"] = {writeProp = "IsPagingEnabled", readProp = "IsPagingEnabled", tipo = "bool"}; +gui.GridRecordList.props["pageSize"] = {writeProp = "PageSize", readProp = "PageSize", tipo = "int"}; +gui.GridRecordList.props["pageIndex"] = {writeProp = "PageIndex", readProp = "PageIndex", tipo = "int"}; +gui.GridRecordList.props["filterFields"] = {writeProp = "FilteringFields", readProp = "FilteringFields", tipo = "table"}; + +gui.GridRecordList.props["selectedForm"] = {getter = "getSelectedForm", tipo = "table"}; +gui.GridRecordList.props["pageCount"] = {readProp = "PageCount", tipo = "int"}; + +gui.GridRecordList.eves["onSelect"] = ""; +gui.GridRecordList.eves["onItemAdded"] = "node"; +gui.GridRecordList.eves["onItemRemoved"] = "node"; +gui.GridRecordList.eves["onItemFiltered"] = "node"; +gui.GridRecordList.eves["onItemUnfiltered"] = "node"; +gui.GridRecordList.eves["onItemShow"] = "node, form"; +gui.GridRecordList.eves["onItemHide"] = "node, form"; +gui.GridRecordList.eves["onCompare"] = "left, right"; +gui.GridRecordList.eves["onFilter"] = "node"; +gui.GridRecordList.eves["onGroupId"] = "node"; +gui.GridRecordList.eves["onGroupCompare"] = "left, right"; +gui.GridRecordList.eves["onGroupHeader"] = "id"; +gui.GridRecordList.eves["onGroupShow"] = "id, header"; +gui.GridRecordList.eves["onGroupHide"] = "id, header"; +gui.GridRecordList.eves["onEmptyState"] = ""; +gui.GridRecordList.eves["onPagingStateChange"] = ""; +gui.GridRecordList.eves["onBeginOrganization"] = ""; +gui.GridRecordList.eves["onEndOrganization"] = ""; + +--[[ Objeto GridRecordListPgCtrl ]]-- + +gui.GridRecordListPgNav = gui.Layout.inherit(); +registerTag(gui.GridRecordListPgNav, 'gridRecordListPgNav'); + +function gui.GridRecordListPgNav:setTarget(value) _obj_invokeEx(self.handle, 'SetGridRecordList', value); end; +function gui.GridRecordListPgNav:getTarget() return _obj_invokeEx(self.handle, 'GetGridRecordList'); end; + +gui.GridRecordListPgNav.props["target"] = {setter = "setTarget", getter = "getTarget", tipo = "obj", class=gui.GridRecordList}; + +--[[ Objeto DataScopeBox ]]-- + +gui.DataScopeBox = gui.Layout.inherit(); +registerTag(gui.DataScopeBox, 'dataScopeBox'); + +function gui.DataScopeBox:getNodeObject() return rawget(self, "__nodeObject"); end; + +function gui.DataScopeBox:setNodeObject(nodeObject) + rawset(self, "__nodeObject", nodeObject); + _gui_assignNodeObject(self.handle, ndb.getNodeHandle(nodeObject)); +end; + +gui.DataScopeBox.props["scopeNode"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.DataScopeBox.props["nodeObject"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.DataScopeBox.props["node"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; + +gui.DataScopeBox.eves["onNodeReady"] = ""; +gui.DataScopeBox.eves["onNodeUnready"] = ""; +gui.DataScopeBox.eves["onNodeChanged"] = ""; + +--[[ Objeto RichEdit ]]-- + +gui.RichEdit = gui.Control.inherit(); +registerTag(gui.RichEdit, 'richEdit'); + +function gui.RichEdit:getField() return _gui_getFieldName(self.handle); end; +function gui.RichEdit:setField(v) _gui_setFieldName(self.handle, v); end; + +function gui.RichEdit:beginEdit() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LBeginEdit") end; end; +function gui.RichEdit:endEdit() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEndEdit") end; end; + +function gui.RichEdit:selectAll() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LSelectAll") end; end; +function gui.RichEdit:unselect() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LUnselect") end; end; +function gui.RichEdit:getSelectionPosInChars() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionPosInChars"); else return 0, 0; end; end; +function gui.RichEdit:getSelectionPosInGlyphs() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionPosInGlyphs"); else return 0, 0; end; end; +function gui.RichEdit:getIsSelectionForward() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetIsSelectionForward"); else return true; end; end; +function gui.RichEdit:getSelectionText() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionText"); else return ""; end; end; +function gui.RichEdit:getSelectionURL() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionURL"); else return ""; end; end; +function gui.RichEdit:getSelectionFontColor() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontColor"); else return "Black"; end; end; +function gui.RichEdit:getSelectionFontBkgColor() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontBkgColor"); else return "White"; end; end; +function gui.RichEdit:getSelectionFontSize() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontSize"); else return 14; end; end; +function gui.RichEdit:getSelectionFontFamily() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontFamily"); else return "Roboto"; end; end; +function gui.RichEdit:getSelectionFontStyle() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontStyle"); else return {}; end; end; +function gui.RichEdit:getSelectionFloat() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFloat"); else return "none"; end; end; +function gui.RichEdit:getSelectionParaAlign() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionParaAlign"); else return "left"; end; end; + +function gui.RichEdit:gotoStart(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoStart", holdSelection); end; end; +function gui.RichEdit:gotoEnd(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoEnd", holdSelection); end; end; +function gui.RichEdit:gotoNext(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoNext", holdSelection); end; end; +function gui.RichEdit:gotoPrevious(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPrevious", holdSelection); end; end; +function gui.RichEdit:gotoStartOfLine(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoStartOfLine", holdSelection); end; end; +function gui.RichEdit:gotoEndOfLine(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoEndOfLine", holdSelection); end; end; +function gui.RichEdit:gotoNextWord(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoNextWord", holdSelection); end; end; +function gui.RichEdit:gotoPreviousWord(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPreviousWord", holdSelection); end; end; +function gui.RichEdit:gotoLineUp(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoLineUp", holdSelection); end; end; +function gui.RichEdit:gotoLineDown(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoLineDown", holdSelection); end; end; +function gui.RichEdit:gotoPageUp(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPageUp", holdSelection); end; end; +function gui.RichEdit:gotoPageDown(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPageDown", holdSelection); end; end; +function gui.RichEdit:gotoPositionInGlyphs(pos, holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPositionInGlyphs", pos, holdSelection); end; end; +function gui.RichEdit:gotoPositionInChars(pos, holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPositionInChars", pos, holdSelection); end; end; + +function gui.RichEdit:copySelectionToClipboard() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LCopySelectionToClipboard"); end; end; + +function gui.RichEdit:deleteSelection() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_DeleteSelection"); end; end; +function gui.RichEdit:insertText(text) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_InsertText", text); end; end; +function gui.RichEdit:insertTalemark(talemarkText, talemarkOptions, talemarkSheetStyle) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_InsertTalemark", talemarkText, talemarkOptions, talemarkSheetStyle); end; end; +function gui.RichEdit:insertImage(params) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_InsertImage", params); end; end; +function gui.RichEdit:breakLine() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_BreakLine"); end; end; +function gui.RichEdit:breakParagraph() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_BreakParagraph"); end; end; +function gui.RichEdit:indent(qty) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_Indent", qty); end; end; +function gui.RichEdit:pasteFromClipboard() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_PasteFromClipboard"); end; end; +function gui.RichEdit:cutSelectionToClipboard() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_CutSelectionToClipboard"); end; end; +function gui.RichEdit:setSelectionURL(url) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionURL", url); end; end; +function gui.RichEdit:setSelectionFontColor(color) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontColor", color); end; end; +function gui.RichEdit:setSelectionFontBkgColor(color) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontBkgColor", color); end; end; +function gui.RichEdit:setSelectionFontSize(size) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontSize", size); end; end; +function gui.RichEdit:setSelectionFontFamily(family) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontFamily", family); end; end; +function gui.RichEdit:setSelectionFontStyle(style) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontStyle", style); end; end; +function gui.RichEdit:setSelectionFloat(floatMode) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFloat", floatMode); end; end; +function gui.RichEdit:setSelectionParaAlign(paraAlign) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionParaAlign", paraAlign); end; end; + +function gui.RichEdit:getLengthInChars() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetLengthInChars"); else return 0; end; end; +function gui.RichEdit:getLengthInGlyphs() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetLengthInGlyphs"); else return 0; end; end; +function gui.RichEdit:getText() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetText"); else return ""; end; end; + +gui.RichEdit.props["animateImages"] = {readProp = "CanAnimateImages", writeProp = "CanAnimateImages", tipo = "bool"}; +gui.RichEdit.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.RichEdit.props["backgroundColor"] = {readProp = "BackgroundColor", writeProp = "BackgroundColor", tipo = "color"}; +gui.RichEdit.props["defaultFontColor"] = {readProp = "DefaultFontColor", writeProp = "DefaultFontColor", tipo = "color"}; +gui.RichEdit.props["defaultFontSize"] = {readProp = "DefaultFontSize", writeProp = "DefaultFontSize", tipo = "double"}; +gui.RichEdit.props["showToolbar"] = {readProp = "ShowToolbar", writeProp = "ShowToolbar", tipo = "bool"}; +gui.RichEdit.props["readOnly"] = {readProp = "ReadOnly", writeProp = "ReadOnly", tipo = "bool"}; +gui.RichEdit.props["hideSelection"] = {readProp = "HideSelectionNoFocus", writeProp = "HideSelectionNoFocus", tipo = "bool"}; + +--[[ Objeto Popup ]]-- + +gui.Popup = gui.Layout.inherit(); +registerTag(gui.Popup, 'popup'); + +function gui.Popup:getCancelable() return _obj_getProp(self.handle, "Cancelavel"); end; +function gui.Popup:setCancelable(v) _obj_setProp(self.handle, "Cancelavel", v) end; + +function gui.Popup:getBackOpacity() return _obj_getProp(self.handle, "BackOpacity"); end; +function gui.Popup:setBackOpacity(v) _obj_setProp(self.handle, "BackOpacity", v) end; + +function gui.Popup:getDrawContainer() return _obj_getProp(self.handle, "DesenharPopupContainer"); end; +function gui.Popup:setDrawContainer(v) _obj_setProp(self.handle, "DesenharPopupContainer", v) end; + +function gui.Popup:setNodeObject(nodeObject) + rawset(self, "nodeObject", nodeObject); + _gui_assignNodeObject(self.handle, ndb.getNodeHandle(nodeObject)); +end; + +function gui.Popup:getNodeObject() return rawget(self, "nodeObject") end; + +function gui.Popup:showPopupEx(placement, control) + if type(placement) ~= "string" then + placement = "center"; + end; + + _obj_setProp(self.handle, "Placement", placement); + + if (type(control) == "table") and (control.handle ~= nil) then + _obj_setProp(self.handle, "TargetControlHandle", control.handle); + else + _obj_setProp(self.handle, "TargetControlHandle", 0); + end; + + _obj_invoke(self.handle, "ExibirPopup"); +end; + +gui.Popup.show = gui.Popup.showPopupEx; +gui.Popup.showPopup = gui.Popup.showPopupEx; + +function gui.Popup:closePopup(cancelar, forcar) _obj_invoke(self.handle, "FecharPopup", cancelar == true, forcar == true); end; +function gui.Popup:close(cancelar, forcar) _obj_invoke(self.handle, "FecharPopup", cancelar == true, forcar == true); end; + +gui.Popup.props["cancelable"] = {setter = "setCancelable", getter = "getCancelable", tipo = "bool"}; +gui.Popup.props["backOpacity"] = {setter = "setBackOpacity", getter = "getBackOpacity", tipo = "double"}; +gui.Popup.props["drawContainer"] = {setter = "setDrawContainer", getter = "getDrawContainer", tipo = "bool"}; +gui.Popup.props["scopeNode"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.Popup.props["nodeObject"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.Popup.props["node"] = gui.Popup.props["nodeObject"]; +gui.Popup.props["scopeNode"] = gui.Popup.props["nodeObject"]; +gui.Popup.props["autoScopeNode"] = {writeProp = "AutoScopeNode", readProp = "AutoScopeNode", tipo = "bool"}; + +gui.Popup.eves["onClose"] = "canceled"; +gui.Popup.eves["onCanClose"] = "canceled"; +gui.Popup.eves["onCalculateSize"] = "dueToResize, width, height"; + +gui.Popup.eves["onNodeReady"] = ""; +gui.Popup.eves["onNodeUnready"] = ""; +gui.Popup.eves["onNodeChanged"] = ""; + +--[[ Objeto Progress Bar ]]-- + +gui.ProgressBar = gui.Control.inherit(); +registerTag(gui.ProgressBar, 'progressBar'); + +function gui.ProgressBar:getColor() return _obj_getProp(self.handle, "Color"); end; +function gui.ProgressBar:setColor(v) _obj_setProp(self.handle, "Color", v) end; + +function gui.ProgressBar:getPosition() return _obj_getProp(self.handle, "Value"); end; +function gui.ProgressBar:setPosition(v) _obj_setProp(self.handle, "Value", v) end; + +function gui.ProgressBar:getMin() return _obj_getProp(self.handle, "Min"); end; +function gui.ProgressBar:setMin(v) _obj_setProp(self.handle, "Min", v) end; + +function gui.ProgressBar:getMax() return _obj_getProp(self.handle, "Max"); end; +function gui.ProgressBar:setMax(v) _obj_setProp(self.handle, "Max", v) end; + +function gui.ProgressBar:getField() return _obj_getProp(self.handle, "Field"); end; +function gui.ProgressBar:setField(v) _obj_setProp(self.handle, "Field", v); end; + +function gui.ProgressBar:getFieldMin() return _obj_getProp(self.handle, "FieldMin"); end; +function gui.ProgressBar:setFieldMin(v) _obj_setProp(self.handle, "FieldMin", v); end; + +function gui.ProgressBar:getFieldMax() return _obj_getProp(self.handle, "FieldMax"); end; +function gui.ProgressBar:setFieldMax(v) _obj_setProp(self.handle, "FieldMax", v); end; + +function gui.ProgressBar:getMouseGlow() return _obj_getProp(self.handle, "MouseGlow"); end; +function gui.ProgressBar:setMouseGlow(v) _obj_setProp(self.handle, "MouseGlow", v); end; + +function gui.ProgressBar:getColorMode() return _obj_getProp(self.handle, "ColorMode"); end; +function gui.ProgressBar:setColorMode(v) _obj_setProp(self.handle, "ColorMode", v); end; + +gui.ProgressBar.props["color"] = {setter = "setColor", getter = "getColor", tipo = "color"}; +gui.ProgressBar.props["position"] = {setter = "setPosition", getter = "getPosition", tipo = "double"}; +gui.ProgressBar.props["value"] = {setter = "setPosition", getter = "getPosition", tipo = "double"}; +gui.ProgressBar.props["min"] = {setter = "setMin", getter = "getMin", tipo = "double"}; +gui.ProgressBar.props["max"] = {setter = "setMax", getter = "getMax", tipo = "double"}; +gui.ProgressBar.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.ProgressBar.props["fieldMin"] = {setter = "setFieldMin", getter = "getFieldMin", tipo = "string"}; +gui.ProgressBar.props["fieldMax"] = {setter = "setFieldMax", getter = "getFieldMax", tipo = "string"}; +gui.ProgressBar.props["mouseGlow"] = {setter = "setMouseGlow", getter = "getMouseGlow", tipo = "bool"}; +gui.ProgressBar.props["colorMode"] = {setter = "setColorMode", getter = "getColorMode", tipo = "enum", values={"default", "hl"}}; + +--[[ Objeto Timer ]]-- + +gui.Timer = objs.Timer; +registerTag(gui.Timer, 'timer'); + + +--[[ Objeto ActivityIndicator ]]-- + +gui.ActivityIndicator = gui.Control.inherit(); +registerTag(gui.ActivityIndicator, 'activityIndicator'); + +--[[ Objeto InertialMovement ]]-- + +gui.InertialMovement = objs.newClass() +registerTag(gui.InertialMovement, 'TInertialMovement'); + +gui.newInertialMovement = gui.InertialMovement.new; + +function gui.InertialMovement:setPos(x, y) _obj_invoke(self.handle, "SetPosition", x, y); end; +function gui.InertialMovement:getPos() return _obj_invokeEx(self.handle, "ExGetPosition"); end; +function gui.InertialMovement:setBounds(minX, minY, maxX, maxY) _obj_invoke(self.handle, "SetBounds", minX, minY, maxX, maxY); end; +function gui.InertialMovement:pointerDown(x, y) _obj_invoke(self.handle, "PointerDown", x, y); end; +function gui.InertialMovement:pointerMove(x, y) _obj_invoke(self.handle, "PointerMove", x, y); end; +function gui.InertialMovement:pointerUp(x, y) _obj_invoke(self.handle, "PointerUp", x, y); end; +function gui.InertialMovement:pointerLeave() _obj_invoke(self.handle, "PointerLeave"); end; +function gui.InertialMovement:pointerWheel(deltaX, deltaY) _obj_invoke(self.handle, "PointerWheel", deltaX, deltaY); end; + +gui.InertialMovement.props["active"] = {tipo = "boolean", readProp = "Active", writeProp="Active"}; +gui.InertialMovement.props["animated"] = {tipo = "boolean", readProp = "Animated", writeProp="Animated"}; +gui.InertialMovement.props["decelerationRate"] = {tipo = "double", readProp = "DecelerationRate", writeProp="DecelerationRate"}; + +gui.InertialMovement.eves["onChange"] = ""; + +--[[ Objeto Drag n Drop ]]-- + +local Serializer = nil; + +local __DragDropDataProps = {dataCount = {tipo = "int", readProp = "DataCount"}}; + +local __DragDropDataMethods = + { + addData = function(d, dataType, dataValue) + _obj_invokeEx(d.handle, "AddData", dataType, Serializer.packData(dataValue)); + end, + + getData = function(d, dataType) + return Serializer.unpackData(_obj_invokeEx(d.handle, "GetData", dataType)); + end + }; + +local __DragProps = {actionCount = {tipo = "int", readProp = "ActionCount"}}; + +local __DragMethods = + { + addAction = function(d, dataType, callback) + if type(callback) == "function" then + _gui_addDragAction(d.handle, dataType, callback); + end; + end + }; + +local __DragEvents = {}; + +local __DropProps = {actionCount = {tipo = "int", readProp = "ActionCount"}}; + +local __DropMethods = + { + addAction = function(d, dataType, callback) + if type(callback) == "function" then + _gui_addDropAction(d.handle, dataType, callback); + end; + end + }; + +local __DropEvents = {}; + +local function dragDropDataObjectFromHandle(handle) + if Serializer == nil then + Serializer = require("utils.serializer.dlua"); + end; + + local obj = objs.objectFromHandle(handle); + + if obj.props == nil then + obj.props = {}; + end; + + for k, v in pairs(__DragDropDataProps) do + obj.props[k] = v; + end; + + for k, v in pairs(__DragDropDataMethods) do + rawset(obj, k, v); + end; + + return obj; +end; + +local function dragObjectFromHandle(handle) + local obj = dragDropDataObjectFromHandle(handle); + + for k, v in pairs(__DragProps) do + obj.props[k] = v; + end; + + for k, v in pairs(__DragMethods) do + rawset(obj, k, v); + end; + + obj.eves = __DragEvents; + return obj; +end + +function gui.newDrag() + return gui.fromHandle(_obj_newObject("TDragObject")); +end; + +guiLoaders["TDragObject"] = dragObjectFromHandle; + +local function dropObjectFromHandle(handle) + local obj = dragDropDataObjectFromHandle(handle); + + for k, v in pairs(__DropProps) do + obj.props[k] = v; + end; + + for k, v in pairs(__DropMethods) do + rawset(obj, k, v); + end; + + obj.eves = __DropEvents; + return obj; +end + +function gui.newDrop() + return gui.fromHandle(_obj_newObject("TDropObject")); +end; + +guiLoaders["TDropObject"] = dropObjectFromHandle; + +function __export__guiInitDropObject(dropUserData) + local d = gui.newDrop(); + _gui_initDragDropDataObject(d.handle, dropUserData); + return d; +end; + +function __export__guiInitDragObject(dragUserData) + local d = gui.newDrag(); + _gui_initDragDropDataObject(d.handle, dragUserData); + return d; +end; + +--[[ API gui ]]-- + +function gui.fromHandle(handle) + if (handle == nil) then + return nil; + end + + local ctrl = objs.tryFindFromHandle(handle); + + if (ctrl ~= nil) then + return ctrl; + end; + + local className = _obj_getClassName(handle); + + if (className == nil) then + return nil; + end; + + local loader = guiLoaders[className]; + + if (loader ~= nil) then + ctrl = loader(handle); + else + ctrl = controlFromHandle(handle); + end + + objs.registerHandleIfNeeded(handle, ctrl); + return ctrl; +end; + +function gui.findControlByName(controlName, referenceControl) + local parentMost; + local p; + + if (type(referenceControl) ~= "table") or (referenceControl.handle == nil) then + return nil; + end; + + local child; + + child = referenceControl:findChildByName(controlName, true); + + if child ~= nil then + return child; + end; + + -- Else, vamos ir ate a RAIZ procurar a partir dela o objeto sem fazer analise recursiva + + parentMost = nil; + p = referenceControl; + + while p ~= nil do + if (type(p) == "table") and (p.findChildByName ~= nil) then + parentMost = p; + child = parentMost:findChildByName(controlName, false, true); -- não fazer analise recursiva neste ponto ainda + + if child ~= nil then + return child; + end; + end; + + p = p:getParent(); + end; + + if parentMost == nil then + return nil; + elseif parentMost.name == controlName then + return parentMost; + end; + + return parentMost:findChildByName(controlName, true); +end; + +findControlByName = gui.findControlByName; + +function gui.newForm(formName) + if (formName == nil) then + return gui.Form.new(); + end; + + if (type(formName) == "string" and (rrpg ~= nil)) then + local formFactory = rrpg.forms[formName]; + + if formFactory ~= nil then + local frm = formFactory.newEditor(); + assert(frm ~= nil); + + return frm; + else + error("Form name not found: '" .. formName .. "'"); + end; + end; + + return nil; +end; + +function gui.newPopupForm(formName) + if (formName == nil) then + return gui.fromHandle(_obj_newObject("popupForm")); + end; + + if (type(formName) == "string" and (rrpg ~= nil)) then + local formFactory = rrpg.forms[formName]; + + if (formFactory ~= nil) and (formFactory.formComponentName == "popupForm") then + local frm = formFactory.newEditor(); + assert(frm ~= nil); + + return frm; + else + error("PopupForm name not found: '" .. formName .. "'"); + end; + end; + + return nil; +end; + +local function formParameterToObjectForm(form) + local retorno = nil; + + if (type(form) == "string") then + retorno = gui.newForm(form); + elseif (type(form) == "table") then + local handle = rawget(form, "handle"); + + if (handle ~= nil) and (rawget(form, "__isFormFlag")) then + retorno = form; + end; + end; + + return retorno; +end; + +local _popupFormShowers = {}; +setmetatable(_popupFormShowers, {__mode="k"}); -- popupFormShowers possui chaves weak-reference + +function gui.showPopup(form, options) + if (form == nil) then + error("invalid parameter - form is nil"); + return false; + end; + + if type(options) ~= "table" then + options = {}; + end; + + options.placement = options.placement or "center"; + form = formParameterToObjectForm(form); + + if (form == nil) then + return false; + end; + + local popupShower = _popupFormShowers[form]; + + if popupShower == nil then + popupShower = rrpgObjs.componentFromHandle(_obj_newObject('TLuaFiremonkeyPopupShower')); + rrpgObjs.registerHandleIfNeeded(popupShower.handle, popupShower); + _popupFormShowers[form] = popupShower; + + local frmHandle = form.handle; + _obj_invoke(popupShower.handle, "SetFormHandle", frmHandle); + + popupShower:addEventListener("OnPopupClose", + function() + local frmRef = objs.tryFindFromHandle(frmHandle); + + if frmRef ~= nil then + _popupFormShowers[frmRef] = nil; + end; + end); + end; + + local closeListenerId = rawget(popupShower, "__closeListenerID"); + + if closeListenerId ~= nil then + popupShower:removeEventListener(closeListenerId); + rawset(popupShower, "__closeListenerID", nil); + end; + + if type(options.onClose) == "function" then + closeListenerId = popupShower:addEventListener("OnPopupClose", options.onClose); + rawset(popupShower, "__closeListenerID", closeListenerId); + end; + + _obj_setProp(popupShower.handle, "PopupPlacement", options.placement); + return _obj_invoke(popupShower.handle, "Show"); +end; + +function gui.closePopup(form) + if type(form) == "table" then + for k, v in pairs(_popupFormShowers) do + if k == form then + return _obj_invoke(v.handle, "Close"); + end; + end; + elseif type(form) == "string" then + local fechouAlgum = false; + + for k, v in pairs(_popupFormShowers) do + if (type(k) == "table") and (k.name == form) then + fechouAlgum = fechouAlgum or _obj_invoke(v.handle, "Close"); + end; + end; + + return fechouAlgum; + else + return false; + end; +end; + +function gui.openInBrowser(url) + if type(url) == "string" then + local achado = url:find("https?://"); + + if achado ~= 1 then + url = "http://" .. url; + end; + + return _gui_openInBrowser(url); + end; +end; + +function gui.asyncOpenFirecastURI(uri, params) + local promiseHandle = _obj_invokeEx(gui.handle, "AsyncOpenFirecastURI", uri, params); + return Async.Promise.wrap(promiseHandle); +end; + +function gui.toast(message) + return _gui_toast(message); +end; + +function gui.getShiftState() + return _gui_getShiftState(); +end; + +-- [ Form cache control ]-- + +local __frmCachedByTime = {cacheName = {}, countByName = {}, genCacheId = 1}; + +function __frmCachedByTime:tryAcquireByName(name) + if (type(name) ~= "string") or (name == "") then + return nil; + end; + + local formsWithSameName = self.cacheName[name]; + + if formsWithSameName ~= nil then + local form = nil; + + for k, v in pairs(formsWithSameName) do + if (type(k) == "table") and (v ~= nil) then + form = k; + break; + end; + end; + + if form ~= nil then + formsWithSameName[form] = nil; + self.countByName[name] = (self.countByName[name] or 0) - 1; + + if self.countByName[name] <= 0 then + self.cacheName[name] = nil; + self.countByName[name] = nil; + end; + + rawset(form, '__timeCacheId', nil); + + local timeoutId = rawget(form, '__timeCacheTimeoutId'); + + if timeoutId ~= nil then + Utils.clearTimeout(timeoutId); + rawset(form, '__timeCacheTimeoutId', nil); + end; + + return form; + else + return nil; + end; + else + return nil; + end; +end; + +function __frmCachedByTime:createTimeoutCallback(name, form, cacheId) + return function() + local currentCacheId = rawget(form, "__timeCacheId"); + local formsWithSameName = self.cacheName[name]; + + if (formsWithSameName ~= nil) and (currentCacheId == cacheId) then + -- Remove from cache to let GC collect the form + + rawset(form, '__timeCacheId', nil); + rawset(form, '__timeCacheTimeoutId', nil); + + formsWithSameName[form] = nil; + self.countByName[name] = (self.countByName[name] or 0) - 1; + + if self.countByName[name] <= 0 then + self.cacheName[name] = nil; + self.countByName[name] = nil; + end; + end; + end; +end; + +function __frmCachedByTime:releaseByName(name, form) + assert(form ~= nil); + + if (type(name) ~= "string") or (name == "") then + return; + end; + + if form.setNodeDatabase ~= nil then + form:setNodeDatabase(nil); + end; + + form:setParent(nil); + + local formsWithSameName = self.cacheName[name]; + + if formsWithSameName == nil then + formsWithSameName = {}; + self.cacheName[name] = formsWithSameName; + self.countByName[name] = 0; + end; + + formsWithSameName[form] = true; + self.countByName[name] = (self.countByName[name] or 0) + 1; + + self.genCacheId = self.genCacheId + 1; + + local cacheId = self.genCacheId; + rawset(form, '__timeCacheId', cacheId); + + local timeoutId = Utils.setTimeout(self:createTimeoutCallback(name, form, cacheId), gui.DEFAULT_FORM_CACHE_TIMEOUT); + rawset(form, '__timeCacheTimeoutId', timeoutId); +end; + +-- [[ Exported functions ]] -- + +function _export_gui_fromHandle(handle) + return gui.fromHandle(handle); +end; + +function _export_gui_acquireForm(formName) + if Firecast == nil then + require('rrpg.lua'); + end; + + assert(Firecast ~= nil); + local frmClass = Firecast.forms[formName]; + + if frmClass ~= nil then + local frm = nil; + + if frmClass.cacheMode == "time" then + frm = __frmCachedByTime:tryAcquireByName(formName); + end; + + if frm ~= nil then + return frm; + end; + + frm = frmClass.newEditor(); + assert(frm ~= nil); + + rawset(frm, "__cachedFrmClass", frmClass); + return frm; + else + return nil; + end; +end; + +function _export_gui_releaseForm(form) + if form == nil then + return; + end; + + local cachedFrmClass = rawget(form, "__cachedFrmClass"); + local cacheMode; + + if cachedFrmClass ~= nil then + cacheMode = cachedFrmClass.cacheMode; + else + cacheMode = nil; + end; + + if cacheMode == "time" then + __frmCachedByTime:releaseByName(cachedFrmClass.name, form); + end; +end; + +return gui; diff --git a/sdk/rrpgGUI_grid.dlua b/sdk/rrpgGUI_grid.dlua new file mode 100644 index 00000000..42ce9b30 --- /dev/null +++ b/sdk/rrpgGUI_grid.dlua @@ -0,0 +1,244 @@ +local Objs = require("rrpgObjs.lua"); + +local SCREEN_SIZES_ARRAY = {"xs", "sm", "md", "lg", "xl"}; +local VALID_SCREEN_SIZE_STR_DICT = {}; + +for i = 1, #SCREEN_SIZES_ARRAY, 1 do + VALID_SCREEN_SIZE_STR_DICT[SCREEN_SIZES_ARRAY[i]] = true; +end; + +-- Class Declaration + +local Grid = Objs.newClass(); + +function Grid.shouldUseScreenSizeStr(value) + return (value ~= nil) and (type(value) == "string") and VALID_SCREEN_SIZE_STR_DICT[value]; +end; + +function __registerScreenSizePropFor_specificScreenSize(screenSize, details, outerGetter, outerSetter) + local wrappedSetter = + function(instance, value) + return outerSetter(instance, screenSize, value); + end; + + local wrappedGetter = + function (instance) + return outerGetter(instance, screenSize); + end; + + local propDetais = {getter=wrappedGetter, setter=wrappedSetter, tipo=details.tipo, values=details.values}; + + if screenSize ~= nil then + if details.lfmName ~= nil then + Grid.props[details.lfmName .. "-" .. screenSize] = propDetais; + else + Grid.props[details.luaName .. "-" .. screenSize] = propDetais; + end; + else + if details.lfmName ~= nil then + Grid.props[details.lfmName] = propDetais; + else + Grid.props[details.luaName] = propDetais; + end; + end; +end; + +local function __registerScreenSizeProp(details) + local hostSetterMethodName = "Set" .. details.hostName; + local hostGetterMethodName = "Get" .. details.hostName; + local luaFirstLetterUpperCasePropName = details.luaName:gsub("^%l", string.upper); + + local setter = + function (instance, screenSizeOrValue, value) + if Grid.shouldUseScreenSizeStr(screenSizeOrValue) then + _obj_invokeEx(instance.handle, hostSetterMethodName, screenSizeOrValue, value); + elseif (screenSizeOrValue ~= nil) then + if value == nil then + _obj_invokeEx(instance.handle, hostSetterMethodName, nil, screenSizeOrValue); + else + error('Invalid ScreenSize: "' .. tostring(screenSizeOrValue) .. '"'); + end; + else + _obj_invokeEx(instance.handle, hostSetterMethodName, nil, value); + end; + + return instance; + end; + + local getter = + function (instance, screenSize) + if Grid.shouldUseScreenSizeStr(screenSize) then + return _obj_invokeEx(instance.handle, hostGetterMethodName, screenSize); + else + return _obj_invokeEx(instance.handle, hostGetterMethodName, nil); + end; + end; + + Grid["set" .. luaFirstLetterUpperCasePropName] = setter; + Grid["get" .. luaFirstLetterUpperCasePropName] = getter; + + __registerScreenSizePropFor_specificScreenSize(nil, details, getter, setter) + + for i = 1, #SCREEN_SIZES_ARRAY do + __registerScreenSizePropFor_specificScreenSize(SCREEN_SIZES_ARRAY[i], details, getter, setter); + end; +end; + +local function __registerNonScreenSizeProp(details) + local hostPropertyNamme = details.hostName; + local luaFirstLetterUpperCasePropName = details.luaName:gsub("^%l", string.upper); + local useDefaultValue = details.useDefaultValueOnSet; + local defaultValue = details.defaultValueOnSet; + + local setter = + function (instance, value) + if (value == nil) and useDefaultValue then + _obj_setProp(instance.handle, hostPropertyNamme, defaultValue); + else + _obj_setProp(instance.handle, hostPropertyNamme, value); + end; + + return instance; + end; + + local getter = + function (instance) + return _obj_getProp(instance.handle, hostPropertyNamme); + end; + + Grid["set" .. luaFirstLetterUpperCasePropName] = setter; + Grid["get" .. luaFirstLetterUpperCasePropName] = getter; + + local propDetais = {getter=getter, setter=setter, tipo=details.tipo, values=details.values}; + Grid.props[details.luaName] = propDetais; + + if details.lfmName ~= nil then + Grid.props[details.lfmName] = propDetais; + end; +end; + +local function __registerScreenSizeEvent_specificScreenSize(screenSize, details, setterWithScreenSizeArgument) + local eve = {arguments = details.arguments}; + + eve.setter = + function(instance, value) + setterWithScreenSizeArgument(instance, screenSize, value); + end; + + if screenSize == nil then + if details.lfmName ~= nil then + Grid.eves[details.lfmName] = eve; + else + Grid.eves[details.luaName] = eve; + end; + else + if details.lfmName ~= nil then + Grid.eves[details.lfmName .. "-" .. screenSize] = eve; + else + Grid.eves[details.luaName .. "-" .. screenSize] = eve; + end; + end; +end; + +local function __registerScreenSizeEvent(details) + local hostSetterMethodName = "Set" .. details.hostName; + + local setterWithScreenSizeArgument = + function(instance, screenSize, value) + _obj_invokeEx(instance.handle, hostSetterMethodName, screenSize, value); + return instance; + end; + + __registerScreenSizeEvent_specificScreenSize(nil, details, setterWithScreenSizeArgument) + + for i = 1, #SCREEN_SIZES_ARRAY do + __registerScreenSizeEvent_specificScreenSize(SCREEN_SIZES_ARRAY[i], details, setterWithScreenSizeArgument); + end; +end; + +function Grid:invalidate() + _obj_invokeEx(self.handle, "Invalidate"); + return self; +end; + +function Grid:reset() + _obj_invokeEx(self.handle, "Reset"); + return self; +end; + +function Grid:getTxtWidth() + return _obj_invokeEx(self.handle, "GetTxtWidth"); +end; + +local GRID_VERT_ALIGN_VALUES = {"top", "center", "middle", "bottom"}; +local GRID_HORZ_ALIGN_VALUES = {"start", "center", "end", "around", "between", "left", "right", "middle"}; +local GRID_CONTAINER_HORZ_ALIGN_VALUES = {"start", "center", "end", "left", "right", "middle"}; + +-- Grid Properties + +__registerNonScreenSizeProp({luaName="role", hostName="Role", tipo="enum", values={"none", "row", "col", "block", "container"}}); +__registerNonScreenSizeProp({luaName="root", hostName="Root", tipo="bool", useDefaultValueOnSet=true, defaultValueOnSet=true}); +__registerNonScreenSizeProp({luaName="screenSizeDet", lfmName="screen-size-det", hostName="ScreenSizeDeterminator", tipo="bool", useDefaultValueOnSet=true, defaultValueOnSet=true}); +__registerNonScreenSizeProp({luaName="autoHeight", lfmName="auto-height", hostName="AutoHeight", tipo="bool", useDefaultValueOnSet=true, defaultValueOnSet=true}); + +__registerScreenSizeProp({luaName="width", hostName="Width", tipo="int"}); +__registerScreenSizeProp({luaName="offset", lfmName="offset", hostName="Offset", tipo="int"}); +__registerScreenSizeProp({luaName="push", lfmName="push", hostName="Push", tipo="int"}); +__registerScreenSizeProp({luaName="pull", lfmName="pull", hostName="Pull", tipo="int"}); +__registerScreenSizeProp({luaName="cntVertAlign", lfmName="cnt-vert-align", hostName="CntVertAlign", tipo="enum", values=GRID_VERT_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="cntHorzAlign", lfmName="cnt-horz-align", hostName="CntHorzAlign", tipo="enum", values=GRID_HORZ_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="cntGutter", lfmName="cnt-gutter", hostName="CntGutter", tipo="double"}); +__registerScreenSizeProp({luaName="cntLineSpacing", lfmName="cnt-line-spacing", hostName="CntLineSpacing", tipo="double"}); +__registerScreenSizeProp({luaName="cntMinGridWidth", lfmName="cnt-min-grid-width", hostName="CntMinGridWidth", tipo="double"}); +__registerScreenSizeProp({luaName="cntMinGridWidthFt", lfmName="cnt-min-grid-width-ft", hostName="CntMinGridWidthFt", tipo="double"}); +__registerScreenSizeProp({luaName="invisibleReserved", lfmName="invisible-reserved", hostName="InvisibleReserved", tipo="bool"}); +__registerScreenSizeProp({luaName="vertAlign", lfmName="vert-align", hostName="SelfVertAlign", tipo="enum", values=GRID_VERT_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="gutter", lfmName="gutter", hostName="SelfGutter", tipo="double"}); +__registerScreenSizeProp({luaName="horzAlign", lfmName="horz-align", hostName="SelfHorzAlign", tipo="enum", values=GRID_CONTAINER_HORZ_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="breakLineBefore", lfmName="break-line-before", hostName="BreakLineBefore", tipo="bool"}); +__registerScreenSizeProp({luaName="breakLineAfter", lfmName="break-line-after", hostName="BreakLineAfter", tipo="bool"}); +__registerScreenSizeProp({luaName="order", lfmName="order", hostName="Order", tipo="int"}); +__registerScreenSizeProp({luaName="group", lfmName="group", hostName="Group", tipo="int"}); +__registerScreenSizeProp({luaName="marginLeft", lfmName="margin-left", hostName="MarginLeft", tipo="double"}); +__registerScreenSizeProp({luaName="marginTop", lfmName="margin-top", hostName="MarginTop", tipo="double"}); +__registerScreenSizeProp({luaName="marginRight", lfmName="margin-right", hostName="MarginRight", tipo="double"}); +__registerScreenSizeProp({luaName="marginBottom", lfmName="margin-bottom", hostName="MarginBottom", tipo="double"}); +__registerScreenSizeProp({luaName="paddingLeft", lfmName="padding-left", hostName="PaddingLeft", tipo="double"}); +__registerScreenSizeProp({luaName="paddingTop", lfmName="padding-top", hostName="PaddingTop", tipo="double"}); +__registerScreenSizeProp({luaName="paddingRight", lfmName="padding-right", hostName="PaddingRight", tipo="double"}); +__registerScreenSizeProp({luaName="paddingBottom", lfmName="padding-bottom", hostName="PaddingBottom", tipo="double"}); +__registerScreenSizeProp({luaName="dynWidthTxt", lfmName="dyn-width-txt", hostName="DynWidthTxt", tipo="bool"}); +__registerScreenSizeProp({luaName="dynHeightTxt", lfmName="dyn-height-txt", hostName="DynHeightTxt", tipo="bool"}); +__registerScreenSizeProp({luaName="postDynWidthTxt", lfmName="post-dyn-width-txt", hostName="PostDynWidthTxt", tipo="bool"}); +__registerScreenSizeProp({luaName="finalOffsetX", lfmName="final-offset-x", hostName="FinalOffsetX", tipo="double"}); +__registerScreenSizeProp({luaName="finalOffsetY", lfmName="final-offset-y", hostName="FinalOffsetY", tipo="double"}); +__registerScreenSizeProp({luaName="vertTile", lfmName="vert-tile", hostName="VertTile", tipo="bool"}); +__registerScreenSizeProp({luaName="vertTileWeight", lfmName="vert-tile-weight", hostName="VertTileWeight", tipo="double"}); +__registerScreenSizeProp({luaName="horzTile", lfmName="horz-tile", hostName="HorzTile", tipo="bool"}); +__registerScreenSizeProp({luaName="minHeight", lfmName="min-height", hostName="MinHeight", tipo="double"}); +__registerScreenSizeProp({luaName="maxHeight", lfmName="max-height", hostName="MaxHeight", tipo="double"}); +__registerScreenSizeProp({luaName="minWidth", lfmName="min-width", hostName="MinWidth", tipo="double"}); +__registerScreenSizeProp({luaName="maxWidth", lfmName="max-width", hostName="MaxWidth", tipo="double"}); + +__registerScreenSizeProp({luaName="dynWidthSingleLine", lfmName="dyn-width-single-line", hostName="DynWidthSingleLine", tipo="bool"}); +__registerScreenSizeProp({luaName="dynWidthEachLine", lfmName="dyn-width-each-line", hostName="DynWidthEachLine", tipo="bool"}); +__registerScreenSizeProp({luaName="dynWidthMatchHeight", lfmName="dyn-width-match-height", hostName="DynWidthMatchHeight", tipo="bool"}); + + +-- Grid Events +__registerScreenSizeEvent({luaName="onPrepare", lfmName="on-prepare", hostName="OnPrepare", arguments="screenSize"}); +__registerScreenSizeEvent({luaName="onAligned", lfmName="on-aligned", hostName="OnAligned", arguments="screenSize, changedBounds, childChangedBounds"}); +__registerScreenSizeEvent({luaName="onGetWidth", lfmName="on-get-width", hostName="OnGetWidth", arguments="screenSize, width"}); +__registerScreenSizeEvent({luaName="onGetHeight", lfmName="on-get-height", hostName="OnGetHeight", arguments="screenSize, height"}); +__registerScreenSizeEvent({luaName="onGetVertMargins", lfmName="on-get-vert-margins", hostName="OnGetVertMargins", arguments="screenSize, height, top, bottom"}); + +-- Instance + +function Grid.new(ctrl) + assert(ctrl ~= nil); + + local g = Grid.fromHandle(_obj_newObject("TLuaGridControl", ctrl.handle)); + return g; +end; + +return Grid; \ No newline at end of file diff --git a/sdk/rrpgLFM.lua b/sdk/rrpgLFM.lua new file mode 100644 index 00000000..1fc7525b --- /dev/null +++ b/sdk/rrpgLFM.lua @@ -0,0 +1,428 @@ +require("rrpgUtil.lua"); +require("rrpgGUI.lua"); + +local serpent = nil; +local lfmObjectsStrongRef = {}; + +function lfm_getObject(ctrlOrHandle) + if ctrlOrHandle == nil then + return nil; + elseif isNumber(ctrlOrHandle) then + return lfmObjectsStrongRef[ctrlOrHandle]; + else + return ctrlOrHandle; + end; +end; + +function lfm_newObjectHandle(className) + local obj = gui.fromHandle(_obj_newObject(className)); + lfmObjectsStrongRef[obj.handle] = obj; + return obj.handle; +end; + +function lfm_destroyObject(ctrlOrHandle) + local obj = lfm_getObject(ctrlOrHandle); + + if obj ~= nil then + lfmObjectsStrongRef[obj.handle] = nil; + obj:destroy(); + end +end + +function lfm_enumEvents(ctrlOrHandle) + local obj = lfm_getObject(ctrlOrHandle); + + local eves = {}; + local qt = 0; + local alreadyListedEves = {}; + + local function processEvent(eventName, eventData) + if not alreadyListedEves[eventName] then + alreadyListedEves[eventName] = true; + + local eveRec = {name = eventName}; + + if type(eventData) == "table" then + eveRec.parameters = eventData.arguments or ""; + else + eveRec.parameters = eventData or ""; + end; + + qt = qt + 1; + eves[qt] = eveRec; + end; + end; + + -- Instance Defined Events + local definedEves = obj.eves; + + if definedEves ~= nil then + for k, v in pairs(obj.eves) do + processEvent(k, v); + end; + end; + + -- Class Defined Events + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + definedEves = currentClass.eves; + + if definedEves ~= nil then + for k, v in pairs(definedEves) do + processEvent(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return eves; +end; + +local function __copyPropTable(propName, prop) + local tbl = {name = propName, tipo = prop.tipo, values = prop.values, getter = prop.getter, setter = prop.setter}; + + if (prop.tipo == "obj") and (type(prop.class) == "table") then + tbl.refClassTagName = prop.class.tagName; + end; + + return tbl; +end; + +function lfm_enumProps(ctrlOrHandle) + local obj = lfm_getObject(ctrlOrHandle); + + local props = {}; + local qt = 0; + local alreadyListedProps = {}; + + local function processProp(propName, prop) + if not alreadyListedProps[propName] then + alreadyListedProps[propName] = true; + qt = qt + 1; + props[qt] = __copyPropTable(propName, prop); + end; + end; + + -- Instance Defined Props + local definedProps = obj.props; + + if definedProps ~= nil then + for k, v in pairs(definedProps) do + processProp(k, v); + end; + end; + + -- Class Defined Props + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + definedProps = currentClass.props; + + if definedProps ~= nil then + for k, v in pairs(definedProps) do + processProp(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return props; +end; + +function lfm_enumGridPropsForCompiler() + local gridClass = require("rrpgGUI_grid.dlua"); + + local props = {}; + local qt = 0; + local alreadyListedProps = {}; + + local function processProp(propName, prop) + if not alreadyListedProps[propName] then + alreadyListedProps[propName] = true; + qt = qt + 1; + props[qt] = __copyPropTable(propName, prop); + end; + end; + + -- Class Defined Props + local currentClass = gridClass; + + while currentClass ~= nil do + definedProps = currentClass.props; + + if definedProps ~= nil then + for k, v in pairs(definedProps) do + processProp(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return props; +end; + +function lfm_enumGridEventsForCompiler() + local gridClass = require("rrpgGUI_grid.dlua"); + + local eves = {}; + local qt = 0; + local alreadyListedEves = {}; + + local function processEvent(eventName, eventData) + if not alreadyListedEves[eventName] then + alreadyListedEves[eventName] = true; + + local eveRec = {name = eventName}; + + if type(eventData) == "table" then + eveRec.parameters = eventData.arguments or ""; + else + eveRec.parameters = eventData or ""; + end; + + qt = qt + 1; + eves[qt] = eveRec; + end; + end; + + -- Class Defined Events + local currentClass = gridClass; + + while currentClass ~= nil do + definedEves = currentClass.eves; + + if definedEves ~= nil then + for k, v in pairs(definedEves) do + processEvent(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return eves; +end; + +local function _getStrOfSetTable(value) + local ret = ""; + local qt = 0; + + for k, v in pairs(value) do + if qt == 0 then + ret = tostring(v); + else + ret = ret .. " " .. tostring(v); + end; + + qt = qt + 1; + end; + + return ret; +end; + +function lfm_valueToStr(value, tipo, valuesOfTipo) + tipo = lowercase(tipo); + + if tipo == "bool" then + if value then + return "true"; + else + return "false"; + end; + elseif (tipo == "int") then + return tostring(round(value)); + elseif tipo == "double" then + return tostring(value); + elseif tipo == "enum" then + return tostring(value); + elseif (tipo == "string") or (tipo == "color") or (tipo == 'url') then + return value; + elseif tipo == "set" then + return _getStrOfSetTable(value, valuesOfTipo); + elseif (tipo == "bounds") or (tipo == "table") then + + if serpent == nil then + serpent = require("serpent.dlua"); + end; + + return serpent.line(value, {comment = false}); + else + return ""; + end; +end; + +function lfm_strToValue(value, tipo, valuesOfTipo) + tipo = lowercase(tipo); + + if tipo == "bool" then + return value == "true"; + elseif (tipo == "int") or (tipo =="double") then + return tonumber(value); + elseif (tipo == "string") or (tipo == "color") or (tipo == "url") then + return value; + elseif tipo == "enum" then + if isStrInTable(value, valuesOfTipo) then + return value; + else + return ""; + end; + elseif tipo == "set" then + + local objSet = {}; + + if type(value) == "string" then + for k, v in pairs(valuesOfTipo) do + if string.find(value, v) then + objSet[#objSet + 1] = v; + end; + end; + elseif type(value) == "table" then + objSet = value; + end; + + return objSet; + elseif (tipo == "bounds") or (tipo == "table") then + f, e = load("return " .. value); + if e then error(e) end + return f(); + else + return nil; + end; +end; + +local function simplificarTable(t) + local ret = {}; + + for k, v in pairs(t) do + if isNumber(k) or (k == v) then + ret[#ret + 1] = v; + else + ret[k]=v; + end; + end; + + return ret; +end + +function lfm_valueToStrToUser(value, tipo, valuesOfTipo) + tipo = lowercase(tipo); + + if tipo == "set" then + if serpent == nil then + serpent = require("serpent.dlua"); + end; + + return serpent.line(simplificarTable(value), {comment = false}); + else + return lfm_valueToStr(value, tipo, valuesOfTipo); + end; +end; + +function lfm_getPropAsString(ctrlOrHandle, propName) + local obj = lfm_getObject(ctrlOrHandle); + local props = obj.props; + + if props == nil then + return nil; + end; + + local prop = props[propName]; + + if prop == nil then + return nil; + end; + + local getter = obj[prop.getter]; + local v = getter(obj); + + return lfm_valueToStr(v, prop.tipo, prop.values); +end; + +function lfm_setPropAsString(ctrlOrHandle, propName, vAsStr) + local obj = lfm_getObject(ctrlOrHandle); + local prop; + + if obj.findPropDef ~= nil then + prop = obj:findPropDef(propName); + end; + + if prop == nil then + local props = obj.props; + + if props ~= nil then + prop = props[propName]; + end; + end; + + if prop == nil then + return nil; + end; + + v = lfm_strToValue(vAsStr, prop.tipo, prop.values); + obj[propName] = v; +end; + +function lfm_getPropAsStringToUser(ctrlOrHandle, propName) + local obj = lfm_getObject(ctrlOrHandle); + local props = obj.props; + + if props == nil then + return nil; + end; + + local prop = props[propName]; + + if prop == nil then + return nil; + end; + + local getter = obj[prop.getter]; + local v = getter(obj); + + return lfm_valueToStrToUser(v, prop.tipo, prop.values); +end; + + +function lfm_setParent(ctrlOrHandleFilho, ctrlOrHandlePai) + local objFilho = lfm_getObject(ctrlOrHandleFilho); + local objPai = lfm_getObject(ctrlOrHandlePai); + objFilho:setParent(objPai); +end; + +local function walkHierarchyAndGetTagClassName(class) + local currentClass = class; + + while type(currentClass) == "table" do + local tagName = rawget(currentClass, "tagName"); + + if type(tagName) == "string" then + return tagName; + end; + + currentClass = currentClass.super; + end; + + return nil; +end; + +function lfm_enumerarClasses() + local ret = {}; + + for k, v in pairs(gui.guiClasses) do + local tagName = rawget(v, "tagName"); + + assert(k == tagName, string.format('k = %s, tagName = %s', k, tagName)); + assert(ret[tagName] == nil, tagName); + + local c = {name = tagName, + parentClassName = walkHierarchyAndGetTagClassName(v.super)}; + + ret[tagName] = c; + end; + + return ret; +end; \ No newline at end of file diff --git a/sdk/rrpgObjs.lua b/sdk/rrpgObjs.lua new file mode 100644 index 00000000..463da9cc --- /dev/null +++ b/sdk/rrpgObjs.lua @@ -0,0 +1,775 @@ +local Async = require("async.lua"); + +objs = {} +local localObjs = objs; + +rrpgObjs = objs; + +local weakHandlerMetatable = { + __mode = "v" +} + +objs.weakMetatable = weakHandlerMetatable; + +local objHandlers = {}; +setmetatable(objHandlers, weakHandlerMetatable); + +objs.events = {}; + +objs.events.eveIdToObject = {}; +setmetatable(objs.events.eveIdToObject, {__mode="v"}); + +objs.events.eventsOfObjects = {}; +setmetatable(objs.events.eventsOfObjects, {__mode="k"}); + +objs.events.idGenerator = 1; + +function objs.addEventListener(object, eventName, funcCallback) + local objectHandle; + + if type(object) == 'table' then + objectHandle = object.handle; + else + objectHandle = nil; + end; + + if type(funcCallback) ~= "function" then + error("Ops, a function is needed to listen an event"); + end; + + if (funcCallback == nil) or (objectHandle == nil) then + return 0; + end; + + local eveItem = {}; + + eveItem.funcCallback = function(...) + return Async.execute(funcCallback, ...):unwrap(); + end + + local evesOfObject = localObjs.events.eventsOfObjects[object]; + + if evesOfObject == nil then + evesOfObject = {}; + localObjs.events.eventsOfObjects[object] = evesOfObject; + end; + + localObjs.events.idGenerator = localObjs.events.idGenerator + 1; + local esteEventId = localObjs.events.idGenerator; + + evesOfObject[esteEventId] = eveItem; + localObjs.events.eveIdToObject[esteEventId] = object; + + local eveDefFinder = object.findEventDef; + local eveDef; + + if eveDefFinder ~= nil then + eveDef = eveDefFinder(object, eventName); + else + eveDef = nil; + end; + + if (eveDef ~= nil) and (type(eveDef) == "table") and (type(eveDef.setter) == "function") then + eveItem.haveCustomSetter = true; + eveItem.setter = eveDef.setter; + eveDef.setter(object, eveItem.funcCallback); + else + _obj_listenEvent(objectHandle, eventName, esteEventId); + end; + + return esteEventId; +end; + +function objs.removeEventListenerById(eventId) + local obj = localObjs.events.eveIdToObject[eventId]; + + if obj == nil then + return; + end; + + localObjs.events.eveIdToObject[eventId] = nil; + + local evesOfObject = localObjs.events.eventsOfObjects[obj]; + + if evesOfObject == nil then + return; + end; + + local eventItem = evesOfObject[eventId]; + + if eventItem == nil then + return; + end; + + evesOfObject[eventId] = nil; + + if eventItem.haveCustomSetter then + eventItem.setter(obj, nil); + else + _obj_stopListeningEvent(obj.handle, eventId); + end; +end; + +--[[ Objeto TObject ]]-- + +objs.class = { + _isClass = true, + + initialize = function(obj) + end, + + addEventListener = function (obj, eventName, funcCallback) + return localObjs.addEventListener(obj, eventName, funcCallback); + end, + + removeEventListener = function (obj, eventListenerId) + return localObjs.removeEventListenerById(eventListenerId); + end, + + removeAllEventListeners = function(obj) + if (obj.handle == nil) then + return; + end; + + local eventsOfThis = localObjs.events.eventsOfObjects[obj]; + + if (eventsOfThis ~= nil) then + local eventsIds = {}; + local idx = 1; + + for k, v in pairs(eventsOfThis) do + eventsIds[idx] = k; + idx = idx + 1; + end; + + for i = 1, idx - 1, 1 do + localObjs.removeEventListenerById(eventsIds[i]); + end; + + localObjs.events.eventsOfObjects[obj] = nil; + end; + end, + + destroy = function(obj) + if not obj._calledDestroy then + obj._calledDestroy = true; + + if obj.handle ~= nil then + if (obj.removeAllEventListeners ~= nil) then + obj:removeAllEventListeners(); + end; + + if objHandlers[obj.handle] == obj then + objHandlers[obj.handle] = nil; + end; + + _obj_destruir(obj.handle); + obj.handle = nil; + end; + end; + end, + + getClassName = function(obj) + if obj.handle ~= nil then + return _obj_getClassName(obj.handle); + else + return ""; + end; + end, + + findPropDef = function(obj, propName) + -- Instance property + local props = rawget(obj, "props"); + + if props ~= nil then + local propKey = props[propName]; + + if propKey ~= nil then + return propKey; + end; + end; + + -- Class property + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + props = rawget(currentClass, "props"); + + if props ~= nil then + local propKey = props[propName]; + + if propKey ~= nil then + return propKey; + end; + end; + + currentClass = rawget(currentClass, "super"); + end; + + return nil; + end, + + findEventDef = function(obj, eventName) + -- Instance event + local eves = rawget(obj, "eves"); + + if eves ~= nil then + local eveKey = eves[eventName]; + + if eveKey ~= nil then + return eveKey; + end; + end; + + -- Class event + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + eves = rawget(currentClass, "eves"); + + if eves ~= nil then + local eveKey = eves[eventName]; + + if eveKey ~= nil then + return eveKey; + end; + end; + + currentClass = rawget(currentClass, "super"); + end; + + return nil; + end +}; + +objs.class.listen = objs.class.addEventListener; +objs.class.unlisten = objs.class.removeEventListener; + +local function __readPropertyValue(instance, propKey) + local fgetter; + + if type(propKey.getter) == "function" then + fgetter = propKey.getter; + else + fgetter = instance[propKey.getter]; + end; + + if fgetter ~= nil then + return fgetter(instance); + elseif propKey.readProp ~= nil then + return _obj_getProp(rawget(instance, 'handle'), propKey.readProp); + end; +end; + +local function __tryIndexObjWithDefinition(definition, instance, key) + -- Raw Value + local v = rawget(definition, key); + + if (v ~= nil) then + return true, v; + end; + + -- Property + local props = rawget(definition, "props"); + + if props ~= nil then + local propKey = props[key]; + + if propKey ~= nil then + return true, __readPropertyValue(instance, propKey); + end; + end; + + -- Event + local eves = rawget(definition, "eves"); + + if eves ~= nil then + local eveKey = eves[key]; + + if eveKey ~= nil then + -- Existe um evento com este nome.. Vamos retornar o evento principal associado, se existir. + local mainEves = rawget(instance, "__mainEves"); + + if mainEves ~= nil then + return true, mainEves[key]; + end; + end; + end; + + -- Custom object __objindex method + local objIndexMethod = rawget(definition, "__objindex"); + + if (objIndexMethod ~= nil) and (type(objIndexMethod) == "function") then + return objIndexMethod(instance, key); + else + return false; + end; +end; + +local function __tryNewIndexObjWithDefinition(definition, instance, key, value) + -- Tentar setar uma propriedade + local fsetter = nil; + local props = rawget(definition, "props"); + + if props ~= nil then + local propKey = props[key]; + + if propKey ~= nil then + if type(propKey.setter) == "function" then + fsetter = propKey.setter; + else + fsetter = instance[propKey.setter]; + end; + + if (fsetter == nil) and (propKey.writeProp ~= nil) then + _obj_setProp(rawget(instance, 'handle'), propKey.writeProp, value); + return true; + end; + end; + end; + + if fsetter ~= nil then + fsetter(instance, value); + return true; + end; + + -- Tentar setar um evento + local eves = rawget(definition, "eves"); + + if eves ~= nil then + local eveKey = eves[key]; + + if eveKey ~= nil then + -- Existe um evento com este nome.. Vamos setar o evento principal associado, se existir. + local mainEves = rawget(instance, "__mainEves"); + + if (mainEves == nil) then + mainEves = {}; + rawset(instance, "__mainEves", mainEves) + end; + + local oldListenerId = mainEves["id_" .. key]; + + if oldListenerId ~= nil then + objs.removeEventListenerById(oldListenerId); + mainEves["id_" .. key] = nil; + end; + + mainEves[key] = value; + + if value ~= nil then + mainEves[key] = value; + mainEves["id_" .. key] = objs.addEventListener(instance, key, value); + end; + + return true; + end; + end; + + -- Custom object __objnewindex method + local objNewIndexMethod = rawget(definition, "__objnewindex"); + + if (objNewIndexMethod ~= nil) and (type(objNewIndexMethod) == "function") then + return objNewIndexMethod(instance, key, value); + else + -- Could not newindex object with supplied definition + return false; + end; +end; + +local objectMetaTable = { + --[[ Comparação padrão entre objetos ]]-- + __eq = function(op1, op2) + if op1.handle ~= nil then + if op2.handle ~= nil then + return op1.handle == op2.handle; + else + return false; + end; + else + if op2.handle ~= nil then + return false; + else + return op1 == op2; + end; + end; + end, + + --[[ getter padrão de propriedades dos objetos. Chamado quando tentar gettar uma propriedade que não existe ]]-- + + __index = function(table, key) + local r, v; + + r, v = __tryIndexObjWithDefinition(table, table, key); + + if r then + return v; + end; + + -- Verificar classes + local currentClass = rawget(table, "class"); + + while currentClass ~= nil do + r, v = __tryIndexObjWithDefinition(currentClass, table, key); + + if r then + return v; + end; + + currentClass = rawget(currentClass, "super"); + end; + + -- Se chegou até aqui, é porque não localizou nenhum valor especial + return nil; + end, + + --[[ setter padrão de propriedades dos objetos. Chamado quando tentou settar uma propriedade que não existe ]]-- + + __newindex = function(table, key, value) + local r; + r = __tryNewIndexObjWithDefinition(table, table, key, value); + + if r then + return; + end; + + -- Verificar classes + local currentClass = rawget(table, "class"); + + while currentClass ~= nil do + r = __tryNewIndexObjWithDefinition(currentClass, table, key, value); + + if r then + return; + end; + + currentClass = rawget(currentClass, "super"); + end; + + -- Se chegou até aqui, é porque não conseguiu fazer nenhuma atribuição especial. + -- Vamos fazer uma atribuição padrão + rawset(table, key, value); + end, + + __gc = function(obj) + if obj.destroy ~= nil then + obj:destroy(); + end; + + if obj.handle ~= nil then + _obj_destruir(obj.handle); + obj.handle = nil; + end; + end +}; + +local classMetatable = { + __index = function(classTable, key) + if (key == "eves") or (key == "props") then + return rawget(classTable, key); + end; + + local currentClass = classTable; + + while currentClass ~= nil do + local v = rawget(currentClass, key); + + if v ~= nil then + return v; + end; + + currentClass = rawget(currentClass, "super"); + end; + + -- Se chegou até aqui, é porque não localizou nenhum valor especial + return nil; + end, + + __newindex = function(classTable, key, value) + rawset(classTable, key, value); + end; +}; + +function objs.objectFromHandle(handle) + local obj = {handle=handle, + class=objs.class}; + + setmetatable(obj, objectMetaTable); + objs.registerHandleIfNeeded(handle, obj); + return obj; +end + +function objs.newPureLuaObject() + return objs.objectFromHandle(nil); +end; + +function objs.__recursiveRunInitialize(obj, class) + local superClass = class.super; + + if superClass ~= nil then + objs.__recursiveRunInitialize(obj, superClass); + end; + + local initialize = rawget(class, "initialize"); + + if initialize ~= nil then + initialize(obj); + end; +end; + +function objs.__createSubclass(superClass) + assert(superClass ~= nil); + local class = {super = superClass, props = {}, eves = {}, _isClass = true}; + + class.new = function() + local obj = {class=class}; + setmetatable(obj, objectMetaTable); + objs.__recursiveRunInitialize(obj, class); + return obj; + end; + + class.fromHandle = function(handle) + local obj = {handle=handle, class=class}; + setmetatable(obj, objectMetaTable); + objs.registerHandleIfNeeded(handle, obj); + objs.__recursiveRunInitialize(obj, class); + return obj; + end; + + class.inherit = function() return objs.__createSubclass(class); end; + setmetatable(class, classMetatable); + return class; +end; + +function objs.newClass() + return objs.__createSubclass(objs.class); +end; + +objs.inherit = objs.newClass; + +-- ## Component Class + +objs.Component = objs.newClass(); + +function objs.Component:initialize() + rawset(self, "props", {}); + rawset(self, "eves", {}); +end; + +function objs.Component:getName() return _obj_getProp(self.handle, "Name"); end; +function objs.Component:setName(name) _obj_setProp(self.handle, "Name", name); end; + +objs.Component.props["name"] = {setter = "setName", getter = "getName", tipo = "string"}; + +function objs.componentFromHandle(handle) + local obj = objs.Component.fromHandle(handle); + return obj; +end; + +-- ## HierarchyObject Class + +objs.HierarchyObject = objs.Component.inherit(); + +function objs.HierarchyObject:initialize() + rawset(self, "_children", {}); +end; + +function objs.HierarchyObject.getChildren(instance) + local ret = {}; + local idxDest = 1; + + for k, v in pairs(instance._children) do + ret[idxDest] = v; + idxDest = idxDest + 1; + end; + + return ret; +end; + +function objs.HierarchyObject.findChildByName(instance, childName, recursive, superficialSearch) + recursive = recursive or true; + local child; + + child = instance[childName]; + + if type(child) == "table" and (child.handle ~= nil) and (child.getName ~= nil) and (child:getName() == childName) then + return child; + end; + + if superficialSearch then + return nil; + end; + + local childs = instance:getChildren(); + + for i = 1, #childs, 1 do + child = childs[i]; + + if child.getName ~= nil then + + if child:getName() == childName then + return child; + end; + end; + end; + + if recursive then + local retChild; + + for i = 1, #childs, 1 do + child = childs[i]; + retChild = child:findChildByName(childName, recursive); + + if retChild ~= nil then + return retChild; + end; + end; + end; + + return nil; +end; + +function objs.HierarchyObject.getParent(instance) + return GUI.fromHandle(_gui_getParent(instance.handle)) +end; + +function objs.HierarchyObject.setParent(instance, parent) + if (instance._parent == parent) then + return; + end; + + if (instance._parent ~= nil) then + instance._parent._children[instance.handle] = nil; + end + + instance._parent = parent; + + if (instance._parent ~= nil) then + _gui_setParent(instance.handle, parent.handle); + instance._parent._children[instance.handle] = instance; + else + _gui_setParent(instance.handle, nil); + end; +end; + +objs.HierarchyObject.__oldDestroyHierarchyObject = objs.HierarchyObject.destroy; + +function objs.HierarchyObject.destroy(instance) + instance:removeAllEventListeners(); + + if instance._children ~= nil then + for k, v in pairs(instance._children) do + if v ~= nil then + v:setParent(nil); + end; + end; + + instance._children = {}; + end; + + if (instance._parent ~= nil) then + + if (instance._parent._children ~= nil) and (instance.handle ~= nil) then + instance._parent._children[instance.handle] = nil; + end; + + instance._parent = nil; + end; + + objs.HierarchyObject.__oldDestroyHierarchyObject(instance); +end; + +function objs.hierarchyObjectFromHandle(handle) + local obj = objs.HierarchyObject.fromHandle(handle); + return obj; +end; + +-- ## Timer Class + +objs.Timer = objs.HierarchyObject.inherit(); + +function objs.Timer:getInterval() return _obj_getProp(self.handle, "Interval") end; +function objs.Timer:setInterval(v) _obj_setProp(self.handle, "Interval", v) end; +function objs.Timer:getEnabled() return _obj_getProp(self.handle, "Enabled") end; +function objs.Timer:setEnabled(v) _obj_setProp(self.handle, "Enabled", v) end; +function objs.Timer:beginUpdate() end; +function objs.Timer:endUpdate() end; + +objs.Timer.props["interval"] = {setter = "setInterval", getter = "getInterval", tipo = "int"}; +objs.Timer.props["enabled"] = {setter = "setEnabled", getter = "getEnabled", tipo = "bool"}; + +objs.Timer.eves["onTimer"] = ""; + +function objs.__timerFromHandle(handle) + local timer = objs.Timer.fromHandle(handle); + return timer; +end; + +function objs.newTimer(interval, callback) + local timer = objs.__timerFromHandle(_obj_newObject("timer")); + + interval = tonumber(interval); + + if (type(interval) ~= "number") or (interval < 1) then + interval = 1; + end; + + timer:setInterval(interval); + + if type(callback) == "function" then + timer:addEventListener("onTimer", callback); + end; + + timer:setEnabled(true); + return timer; +end; + +function objs.beginObjectsLoading() + _obj_beginObjectsLoading(); +end; + +function objs.endObjectsLoading() + _obj_endObjectsLoading(); +end; + +function objs.tryFindFromHandle(handle) + return objHandlers[handle]; +end; + +function objs.registerHandle(handle, object) + objHandlers[handle] = object; +end; + +function objs.registerHandleIfNeeded(handle, object) + if objHandlers[handle] == nil then + objHandlers[handle] = object; + end; +end + +function _rrpgObjs_events_receiver(eventId, ...) + local obj = localObjs.events.eveIdToObject[eventId]; + + if obj == nil then + return; + end; + + local evesOfObject = localObjs.events.eventsOfObjects[obj]; + + if evesOfObject == nil then + return; + end; + + local eventItem = evesOfObject[eventId]; + + if eventItem == nil then + return; + end; + + return eventItem.funcCallback(...); +end; + +function __EXPORT__objs_tryFindFromHandle(handle) + return objs.tryFindFromHandle(handle); +end; + +return localObjs; \ No newline at end of file diff --git a/sdk/rrpgRequests.lua b/sdk/rrpgRequests.lua new file mode 100644 index 00000000..d01ba98a --- /dev/null +++ b/sdk/rrpgRequests.lua @@ -0,0 +1,83 @@ +local rrpg = require("rrpg.lua"); +local rrpgObjs = require("rrpgObjs.lua"); +require("rrpgUtil"); +local messaging = rrpg.messaging; + +local requests = rrpgObjs.objectFromHandle(_obj_newObject("TRRPGLuaRequests")); +rrpgObjs.registerHandle(requests.handle, requests); + +local sessionLostMessage = "A conexão com o servidor foi perdida"; + +local function execCallback(callbackFunction, ...) + if type(callbackFunction) == "function" then + setTimeout( + function(...) + callbackFunction(...); + end, 50, ...); + end; +end; + +function requests.criarItensNaBiblioteca(mesa, itens, successCallback, failureCallback) + local pacote = itens; + + if mesa == nil then + error("Parâmetro mesa não informado"); + end; + + if #itens == 0 then + execCallback(failureCallback, "Não foi especificado itens para a criação"); + return; + end; + + for i = 1, #itens, 1 do + local it = itens[i]; + + if (type(it.itemPai) == "table") then + it.itemPai = it.itemPai.codigoInterno; + end; + + if type(it.dono) == "table" then + it.dono = it.dono.codigoInterno; + end; + end; + + if type(mesa) == "table" then + mesa = mesa.codigoInterno; + end; + + local r, r2 = _obj_invokeEx(requests.handle, "ExCriarItensNaBiblioteca", mesa, pacote); + + if r then + local l1 = messaging.listenOnce("ServerResponse_CriarItemBiblioteca", + function(msg) + if msg.r then + execCallback(successCallback); + else + execCallback(failureCallback, msg.msg); + end; + end, {requestId=r2}); + + local l2 = messaging.listenOnce("SessionLost", + function() + execCallback(failureCallback, sessionLostMessage); + end); + + messaging.groupOnceListeners(l1, l2); + else + execCallback(failureCallback, r2); + end; +end; + +function requests.criarPersonagem(itemPai, nome, dataType, visivelATodos, dono, successCallback, failureCallback) + + if itemPai == nil then + error("Parâmetro itemPai não informado"); + end; + + local itens = {{tipoItem="personagem", itemPai=itemPai, nome=nome, sistema=dataType, dono=dono, visivel=visivelATodos}}; + return requests.criarItensNaBiblioteca(itemPai.mesa, itens, successCallback, failureCallback); +end; + +rrpg.requests = requests; +rrpg.Requests = requests; +return requests; \ No newline at end of file diff --git a/sdk/rrpgSharedObjects.lua b/sdk/rrpgSharedObjects.lua new file mode 100644 index 00000000..f6f6b1d0 --- /dev/null +++ b/sdk/rrpgSharedObjects.lua @@ -0,0 +1,149 @@ +local SharedObjects = {}; +local registeredUnpackers = {}; + +local __SHAREDOBJ_PREFIX = "##RRPGshObj("; +local __SHAREDOBJ_SUFIX = ")##"; +local __MATCH_SHARED_OBJ = "##RRPGshObj%((.+)%)##" +local __MATCH_SHARED_OBJ_NOCAPTURE = "##RRPGshObj%([^%(%)#]+%)##" + +local __SHAREDARRAYOBJ_PREFIX = "@@RRPGshObjArray("; +local __SHAREDARRAYOBJ_SUFIX = ")@@"; +local __SHAREDARRAYOBJ_SEP = ","; +local __MATCH_SHARED_ARRAYOBJ = "@@RRPGshObjArray%((.+)%)@@" + +local function sidToString(sid) + if type(sid) == "table" then + if sid.extra ~= nil then + return _internet_HTTPEncode(sid.objectType) .. "\\" .. + _internet_HTTPEncode(sid.objectID) .. "\\" .. + _internet_HTTPEncode(sid.extra); + else + return _internet_HTTPEncode(sid.objectType) .. "\\" .. + _internet_HTTPEncode(sid.objectID); + end; + else + return ""; + end; +end; + +local __strToSidOrder = {"objectType", "objectID", "extra"} + +local function stringToSid(str) + local sid = {}; + + if str ~= nil and type(str) == "string" then + local ordem = 1; + + for t in string.gmatch(str, "[^\\]+") do + local k = __strToSidOrder[ordem]; + + if k ~= nil then + sid[k] = _internet_HTTPDecode(t); + end; + + ordem = ordem + 1; + end; + end; + + sid.objectType = sid.objectType or ""; + sid.objectID = sid.objectID or ""; + return sid; +end; + +function SharedObjects.tryPack(tabela) + if type(tabela) ~= "table" then + return false; + end; + + local h = rawget(tabela, "handle"); + + if h ~= nil then + local so = nil; + local fnGetShareObjectID = rawget(tabela, "getShareID"); + + if (fnGetShareObjectID ~= nil) and (type(fnGetShareObjectID) == "function") then + local sid = fnGetShareObjectID(tabela); + so = __SHAREDOBJ_PREFIX .. sidToString(sid) .. __SHAREDOBJ_SUFIX; + end; + + return true, so; + else + local qtNaTabela = #tabela; + + if qtNaTabela > 0 then + -- Pode ser um array.... + local bStr = __SHAREDARRAYOBJ_PREFIX; + local qtPacked = 0; + + for i = 1, #tabela, 1 do + local xR, xStr = SharedObjects.tryPack(tabela[i]); + + if xR then + if qtPacked > 0 then + bStr = bStr .. __SHAREDARRAYOBJ_SEP; + end; + + bStr = bStr .. xStr; + qtPacked = qtPacked + 1; + end; + end; + + if qtPacked > 0 then + return true, bStr .. __SHAREDARRAYOBJ_SUFIX; + else + return false; + end + else + return false; + end + end; +end; + +function SharedObjects.tryUnpack(str) + if str == nil then + return false; + end; + + local arrayContent = string.match(str, __MATCH_SHARED_ARRAYOBJ); + + if arrayContent ~= nil then + -- Um array de objetos + local tabela = {}; + + for sObj in string.gmatch(arrayContent, __MATCH_SHARED_OBJ_NOCAPTURE) do + local xR, xObj = SharedObjects.tryUnpack(sObj); + + if xR then + tabela[#tabela + 1] = xObj; + end; + end; + + if #tabela > 0 then + return true, tabela; + else + return false; + end; + else + local strSid = string.match(str, __MATCH_SHARED_OBJ); + + if strSid ~= nil then + local sid = stringToSid(strSid); + local unpacker = registeredUnpackers[sid.objectType]; + + if unpacker ~= nil then + local so = unpacker(sid); + return true, so; + else + return false; + end; + else + return false; + end; + end; +end; + +function SharedObjects.registerUnpacker(objectType, unpackerCallback) + registeredUnpackers[objectType] = unpackerCallback; +end; + +return SharedObjects; \ No newline at end of file diff --git a/sdk/rrpgUtil.lua b/sdk/rrpgUtil.lua new file mode 100644 index 00000000..225c3835 --- /dev/null +++ b/sdk/rrpgUtil.lua @@ -0,0 +1,485 @@ +local rrpgObjs = require("rrpgObjs.lua"); +utils = {}; +Utils = utils; + +function lowercase(s) + return string.lower(s); +end; + +function uppercase(s) + return string.upper(s); +end; + +function isNumber(v) + return type(v) == "number"; +end; + +function isnumber(v) + return type(v) == "number"; +end; + +function floor(v) + return math.floor(v); +end; + +function round(v) + return floor(v + 0.5); +end; + +function utils.tryFinally(tryCallback, finallyCallback) + return _util_tryFinally(tryCallback, finallyCallback); +end; + +tryFinally = utils.tryFinally; + +function isStrInTable(s, table) + for k, v in ipairs(table) do + if (k == s) or (v == s) then + return true; + end; + end; + + return false; +end; + +function removerAcentos(str) + return utils.removerAcentos(str); +end; + + +function strToTable(str) + return totable(str); +end; + +function tableToStr(tabela, pretty) + local serpent = require("serpent.dlua"); + + if pretty then + return serpent.block(tabela, {comment=false}); + else + return serpent.line(tabela, {comment=false}); + end; +end; + +utils.tableToStr = tableToStr; +utils.strToTable = strToTable; + +function utils.removerAcentos(str) + return _util_removerAcentos(str); +end; + +function utils.removerFmtChat(str, removerSmileys) + if removerSmileys == nil then + removerSmileys = false; + end; + + return _util_removerTagsDeFormatacaoDeChat(str, not (not removerSmileys)); +end; + +function utils.compareStringPtBr(strLeft, strRight) + return _util_compareStringsPtBr(strLeft, strRight); +end; + +function utils.sortPtBrArray(array) + table.sort(array, function(l, r) return utils.compareStringPtBr(l, r) < 0; end); +end; + +local __settedTimers = {}; +local __timersGeneratorId = 1; + +local function __unsetupTemporizador(timerId, temporizador) + if temporizador == nil then + temporizador = __settedTimers[timerId]; + end; + + __settedTimers[timerId] = nil; + + if (temporizador ~= nil) and (temporizador.timer ~= nil) then + local timer = temporizador.timer; + timer.enabled = false; + temporizador.callback = nil; + temporizador.parametros = nil; + temporizador.timer = nil; -- liberar para o garbage collector + end; +end; + +local function __setupTemporizador(callback, interval, isInterval, ...) + if (type(callback) ~= "function") or (type(interval) ~= "number") then + return nil; + end; + + if interval < 1 then + interval = 1; + end; + + __timersGeneratorId = __timersGeneratorId + 1; + + local temporizador = {}; + local timer = rrpgObjs.newTimer(); + local timerId = __timersGeneratorId; + + + temporizador.id = timerId; + temporizador.timer = timer; + temporizador.interval = interval; + temporizador.isInterval = isInterval; + temporizador.callback = callback; + temporizador.parametros = table.pack(...); + + temporizador.onTimerEventListenerId = timer:addEventListener("onTimer", + function () + local callbackFunction = temporizador.callback; + local parametros = temporizador.parametros; + + if not temporizador.isInterval then + __unsetupTemporizador(timerId, temporizador); + end; + + local ret; + + if callbackFunction ~= nil then + if parametros ~= nil then + ret = callbackFunction(table.unpack(parametros)); + else + ret = callbackFunction(); + end; + else + ret = false; + end; + + if temporizador.isInterval and (ret == false) then + __unsetupTemporizador(timerId, temporizador); + end; + end); + + __settedTimers[timerId] = temporizador; + timer.interval = interval; + timer.enabled = true; + return timerId; +end; + +function utils.setTimeout(callback, interval, ...) + interval = tonumber(interval); + + if (interval == nil) or (interval <= 0) then + callback(...); + return nil; + else + return __setupTemporizador(callback, interval, false, ...); + end; +end; + +function utils.setInterval(callback, interval, ...) + return __setupTemporizador(callback, interval, true, ...); +end; + +function utils.clearInterval(intervalId) + return __unsetupTemporizador(intervalId); +end; + +function utils.clearTimeout(timeoutId) + return __unsetupTemporizador(timeoutId); +end; + +function setTimeout(callback, interval, ...) + return utils.setTimeout(callback, interval, ...); +end; + +function setInterval(callback, interval, ...) + return utils.setInterval(callback, interval, ...); +end; + +function clearInterval(intervalId) + return utils.clearInterval(intervalId); +end; + +function clearTimeout(timeoutId) + return utils.clearTimeout(timeoutId); +end; + +function utils.binaryEncode(destArray, format, value, startIndex) + if type(destArray) ~= "table" then + return; + end; + + if type(startIndex) ~= "number" then + startIndex = 1; + end; + + return _util_binaryEncode(destArray, format, value, startIndex); +end; + +function utils.binaryDecode(sourceArray, format, startIndex, length) + if type(sourceArray) ~= "table" then + return nil; + end; + + if type(startIndex) ~= "number" then + startIndex = 1; + end; + + if type(length) ~= "number" then + length = #sourceArray - startIndex + 1; + end; + + return _util_binaryDecode(sourceArray, format, startIndex, length); +end; + +function utils.getBinarySize(format) + return _util_getBinarySize(format); +end; + +local __streamProps = nil; + +function utils.streamFromHandle(handle) + local stream = rrpgObjs.tryFindFromHandle(handle); + + if stream ~= nil then + return stream; + end; + + stream = rrpgObjs.objectFromHandle(handle); + + function stream:getSize() return _obj_getProp(self.handle, "Size"); end; + function stream:setSize(v) _obj_setProp(self.handle, "Size", v); end; + + function stream:getPosition() return _obj_getProp(self.handle, "Position"); end; + function stream:setPosition(v) _obj_setProp(self.handle, "Position", v); end; + + function stream:read(destArray, qtBytes) return _obj_invokeEx(self.handle, "ReadBytes", destArray, qtBytes); end; + function stream:write(sourceArray, qtBytes) return _obj_invokeEx(self.handle, "WriteBytes", sourceArray, qtBytes); end; + + function stream:getRemainingBytes() + local r = self.size - self.position; + + if r < 0 then + return 0; + else + return r; + end; + end; + + function stream:close() _obj_invoke(self.handle, "Close"); end; + + function stream:writeBinary(format, ...) + local qt = select("#", ...); + local qtBytesEscrito = 0; + local binario = {}; + + for i = 1, qt, 1 do + local v = select(i, ...); + local qtBytesEste = utils.binaryEncode(binario, format, v); + local qtEscritoNeste = self:write(binario, qtBytesEste); + qtBytesEscrito = qtBytesEscrito + qtEscritoNeste; + + if qtEscritoNeste < qtBytesEste then + return qtBytesEscrito; + end; + end; + + return qtBytesEscrito; + end; + + function stream:readBinary(format, qt) + local qtBytesPorItem = utils.getBinarySize(format); + local qtBytesALer; + + if type(qt) ~= "number" then + qt = 1; + end; + + if qt <= 0 then + return; + end; + + if qtBytesPorItem < 0 then + -- tamanho variável. + qtBytesALer = self.remainingBytes; + else + qtBytesALer = qt * qtBytesPorItem; + end; + + local bts = {}; + local bytesLido = self:read(bts, qtBytesALer); + + if (qt == 1) or (qtBytesPorItem <= 0) then + return utils.binaryDecode(bts, format, 1, bytesLido); + else + local retornos = {}; + local currentIndex = 1; + + for i = 1, qt, 1 do + local retValue, bytesUsados = utils.binaryDecode(bts, format, currentIndex, qtBytesPorItem); + retornos[i] = retValue; + currentIndex = currentIndex + bytesUsados; + end; + + return table.unpack(retornos); + end; + end; + + function stream:readAsBase64(qtBytes) + if qtBytes == nil then + qtBytes = self.remainingBytes; + else + qtBytes = tonumber(qtBytes); + + if qtBytes < 0 then + qtBytes = 0; + elseif qtBytes > self.remainingBytes then + qtBytes = self.remainingBytes; + end; + end; + + return _obj_invoke(self.handle, "ReadAsBase64", qtBytes); + end; + + function stream:writeBase64(str) + if str == nil or str == "" then + return 0; + end; + + return _obj_invoke(self.handle, "WriteBase64", tostring(str)); + end; + + function stream:copyFrom(sourceStream, qtBytes) + qtBytes = tonumber(qtBytes); + + if (type(sourceStream) ~= "table") or (sourceStream.handle == nil) or (qtBytes == nil) or (qtBytes <= 0) then + return 0; + end; + + return _obj_invokeEx(self.handle, "CopyFrom", sourceStream.handle, qtBytes); + end; + + function stream:share() return _obj_invoke(self.handle, "ShareStream"); end; + + function stream:getMD5() return _obj_invoke(self.handle, "CalculateMD5"); end; + function stream:getSHA1() return _obj_invoke(self.handle, "CalculateSHA1"); end; + + if __streamProps == nil then + __streamProps = stream.props or {}; + __streamProps["size"] = {setter = "setSize", getter = "getSize", tipo = "int"}; + __streamProps["position"] = {setter = "setPosition", getter = "getPosition", tipo = "int"}; + __streamProps["remainingBytes"] = {getter = "getRemainingBytes", tipo = "int"}; + __streamProps["md5"] = {getter = "getMD5", tipo = "string"}; + __streamProps["sha1"] = {getter = "getSHA1", tipo = "string"}; + end; + + stream.props = __streamProps; + + rrpgObjs.registerHandle(handle, stream); + return stream; +end; + +string.upper = function(str) + return _util_upperCase(str); +end; + +string.lower = function(str) + return _util_lowerCase(str); +end; + +function utils.zlibCompress(sourceStream, destStream, level, qtBytesInSource) + if level ~= "none" and level ~= "fastest" and level ~= "default" and level ~= "max" then + level = "default"; + end; + + if qtBytesInSource == nil then + qtBytesInSource = sourceStream.remainingBytes; + else + qtBytesInSource = tonumber(qtBytesInSource); + + if qtBytesInSource < 0 then + qtBytesInSource = 0; + elseif qtBytesInSource > sourceStream.remainingBytes then + qtBytesInSource = sourceStream.remainingBytes; + end; + end; + + return _util_zlibCompress(sourceStream.handle, destStream.handle, level, qtBytesInSource); +end; + +function utils.zlibDecompress(sourceStream, destStream) + return _util_zlibDecompress(sourceStream.handle, destStream.handle); +end; + +function utils.zlibCompressAsync(sourceStream, destStream, level, qtBytesInSource, onFinish, onError) + if level ~= "none" and level ~= "fastest" and level ~= "default" and level ~= "max" then + level = "default"; + end; + + if qtBytesInSource == nil then + qtBytesInSource = sourceStream.remainingBytes; + else + qtBytesInSource = tonumber(qtBytesInSource); + + if qtBytesInSource < 0 then + qtBytesInSource = 0; + elseif qtBytesInSource > sourceStream.remainingBytes then + qtBytesInSource = sourceStream.remainingBytes; + end; + end; + + local compressObject = require("rrpgUtil_async.dlua").newAsyncZLibObject(); + compressObject:zlibCompressAsync(sourceStream, destStream, level, qtBytesInSource, onFinish, onError); +end; + +function utils.zlibDecompressAsync(sourceStream, destStream, onFinish, onError) + local compressObject = require("rrpgUtil_async.dlua").newAsyncZLibObject(); + compressObject:zlibDecompressAsync(sourceStream, destStream, onFinish, onError); +end; + +function utils.newMemoryStream() + return utils.streamFromHandle(_util_newMemoryStream()); +end; + +function utils.newTempFileStream() + return utils.streamFromHandle(_util_newTempFileStream()); +end; + +function utils.openSharedStream(sharedId) + return utils.streamFromHandle(_util_openSharedStream(sharedId)); +end; + +function utils.generateUniqueString() + return _rrpg_generateUniqueStrID(); +end; + +function utils.cloneTable(t, deep) + if t == nil then + return nil; + end; + + local r = {}; + + for i = 1, #t do + local v = t[i]; + + if (deep) and (type(v) == "table") then + r[i] = utils.cloneTable(v); + else + r[i] = v; + end; + end; + + for k, v in pairs(t) do + if r[k] == nil then + if (deep) and (type(v) == "table") then + r[k] = utils.cloneTable(v); + else + r[k] = v; + end; + end; + end; + + return r; +end; + +utils.colorToRGBA = _gui_colorToRGBA; +utils.RGBAToColor = _gui_RGBAToColor; + +colorToRGBA = utils.colorToRGBA; +RGBAToColor = utils.RGBAToColor; + +return utils; \ No newline at end of file diff --git a/sdk/rrpgUtil_async.dlua b/sdk/rrpgUtil_async.dlua new file mode 100644 index 00000000..cc51a94d --- /dev/null +++ b/sdk/rrpgUtil_async.dlua @@ -0,0 +1,78 @@ +local objs = require("rrpgObjs.lua"); +local async = {}; + +local __asyncsWorking = {}; + +function async.newAsyncZLibObject() + local obj = objs.objectFromHandle(_obj_newObject("asyncZLibObject")); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["onFinish"] = ""; + obj.eves["onError"] = ""; + + function obj:undoReferenceToStreams() + rawset(obj, "__sourceStream", nil); + rawset(obj, "__destStream", nil); + end; + + function obj:setWorking() + __asyncsWorking[obj] = true; + end; + + function obj:setNotWorking() + obj:undoReferenceToStreams(); + __asyncsWorking[obj] = nil; + end; + + function obj:zlibCompressAsync(sourceStream, destStream, level, qtBytesInSource, onFinish, onError) + rawset(obj, "__sourceStream", sourceStream); + rawset(obj, "__destStream", destStream); + + obj.onFinish = function (...) + if onFinish ~= nil then + onFinish(...); + obj:setNotWorking(); + end; + end; + + obj.onError = function (...) + if onError ~= nil then + onError(...); + obj:setNotWorking(); + end; + end; + + obj:setWorking(); + _obj_invokeEx(obj.handle, "ZLibCompressAsync", sourceStream.handle, destStream.handle, level, qtBytesInSource); + end; + + function obj:zlibDecompressAsync(sourceStream, destStream, onFinish, onError) + rawset(obj, "__sourceStream", sourceStream); + rawset(obj, "__destStream", destStream); + + obj.onFinish = function () + if onFinish ~= nil then + onFinish(); + obj:setNotWorking(); + end; + end; + + obj.onError = function (errorMsg) + if onError ~= nil then + onError(errorMsg); + obj:setNotWorking(); + end; + end; + + obj:setWorking(); + _obj_invokeEx(obj.handle, "ZLibDecompressAsync", sourceStream.handle, destStream.handle); + end; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +return async; \ No newline at end of file diff --git a/sdk/rrpgWrappers.lua b/sdk/rrpgWrappers.lua new file mode 100644 index 00000000..b4b39038 --- /dev/null +++ b/sdk/rrpgWrappers.lua @@ -0,0 +1,1185 @@ +local objs = require("rrpgObjs.lua"); +local SharedObjects = require("rrpgSharedObjects.lua"); +local rrpgWrappers = {}; +local localStrongRefContextoObjects = {}; +local Locale = require("locale.lua"); +local Async = require("async.lua"); +local Utils = require('utils.lua'); + +local SHARED_OBJECT_TYPE = "rrpgObject"; + +--[ Anti Flood System ]-- + +local function newTimedJobQueue(interval) + local o = {}; + o.interval = interval; + + o.timer = objs.newTimer(interval, + function() + + -- Pesquisar novo job + local achouJob = false; + local jobEncontrado = nil; + local idJobEncontrado = nil; + + while (not achouJob) and (o.ultimoJobExecutado < o.gerador) do + o.ultimoJobExecutado = o.ultimoJobExecutado + 1; + local jobObject = o.jobs[o.ultimoJobExecutado]; + + if jobObject ~= nil then + achouJob = true; + jobEncontrado = jobObject; + idJobEncontrado = o.ultimoJobExecutado; + end; + end; + + if achouJob and (jobEncontrado ~= nil) then + o.jobs[idJobEncontrado] = nil; + + if jobEncontrado.parameters ~= nil then + jobEncontrado.callback(table.unpack(jobEncontrado.parameters)); + else + jobEncontrado.callback(); + end; + else + o.readyForJob = true; + o.timer.enabled = false; + end; + + end); + + o.timer.enabled = false; + + function o:addJob(callback, ...) + if o.readyForJob then + o.readyForJob = false; + o.timer.enabled = true; + callback(...); + else + o.gerador = o.gerador + 1; + local idJob = o.gerador; + local jobObject = {}; + jobObject.callback = callback; + jobObject.parameters = table.pack(...); + o.jobs[idJob] = jobObject; + end; + end; + + function o:addAsyncJob(callback, ...) + local promise, resolution = Async.Promise.toResolve(); + assert((promise ~= nil) and (resolution ~= nil)); + + o:addJob( + function(...) + assert(resolution ~= nil); + + local function protectedCallback(...) + local ret = table.pack(pcall(callback, ...)); + + if ret[1] then + return table.unpack(ret, 2); + else + return Async.Promise.failed(ret[2]); + end; + end; + + Async.execute(protectedCallback, ...):thenResolve(resolution); + end, ...); + + return promise; + end; + + function o:clear() + o.timer.enabled = false; + o.gerador = 0; + o.ultimoJobExecutado = 0; + o.jobs = {}; + o.readyForJob = true; + end; + + o:clear(); + return o; +end; + +local __serverRequestQueue = newTimedJobQueue(250); +rrpgWrappers.__serverRequestQueue = __serverRequestQueue; + +local function initWrappedObjectFromHandle(handle) + local wObj = objs.objectFromHandle(handle); + + if (wObj.props == nil) then + wObj.props = {}; + end; + + function wObj:getObjectID() return _obj_getProp(self.handle, "ContextoObjectID"); end; + function wObj:getObjectType() return _obj_getProp(self.handle, "WrappedObjectType"); end; + function wObj:getIsObjectAlive() return _obj_getProp(self.handle, "IsObjectAlive"); end; + function wObj:isType(typeName) return _rrpg_IsWrapperOfType(self.handle, typeName); end; + + function wObj:getShareID() return {objectType=SHARED_OBJECT_TYPE, objectID=tostring(self:getObjectID())} end; + + wObj.props["objectType"] = {getter = "getObjectType", tipo = "string"}; + wObj.props["isObjectAlive"] = {getter = "getIsObjectAlive", tipo = "bool"}; + wObj.props["objectID"] = {getter = "getObjectID", tipo = "int"}; + return wObj; +end; + +--[ OBJETO MESA ]-- + +local function initMesaWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local mesa = wObj; + + function mesa:getActiveChat() + local objMesa = rrpgWrappers.objectFromID(_obj_getProp(self.handle, "ActiveChatObjectID")); + + if objMesa == nil then + return mesa:getChat(); + else + return objMesa; + end; + end; + + function mesa:getAudioPlayer() + local cachedPlayer = rawget(self, "__cachedAudioPlayer"); + + if cachedPlayer == nil then + local audioLib = require("audioCore.dlua"); + + if self.isObjectAlive then + local audioPlayerHandle = _obj_invokeEx(self.handle, 'CreateRoomAudioPlayer'); + + if audioPlayerHandle ~= nil then + cachedPlayer = audioLib._audioPlayerWrapperFromHandle(audioPlayerHandle); + else + cachedPlayer = audioLib._newNullAudioPlayerWrapper("Failed to initialize room audio player"); + end; + else + cachedPlayer = audioLib._newNullAudioPlayerWrapper("Not in room"); + end; + + assert(cachedPlayer ~= nil); + rawset(self, "__cachedAudioPlayer", cachedPlayer); + end; + + return cachedPlayer; + end; + + function mesa:getChat() + local objMesa = rrpgWrappers.objectFromID(_obj_getProp(self.handle, "ChatObjectID")); + + if objMesa == nil then + return rrpgWrappers.NullChatWrapper; -- ao invés de retornar NULL, vamos retorna um objeto que não faz nada. + else + return objMesa; + end; + end; + + function mesa:getJogadores() + local hs = _obj_getProp(self.handle, "JogadoresObjectIDs"); + local jogadores = {}; + local idx = 1; + + for p, v in pairs(hs) do + jogadores[idx] = rrpgWrappers.contextObjectFromID(v); + idx = idx + 1; + end + + return jogadores; + end + + function mesa:findBibliotecaItem(codigoInterno) return rrpgWrappers.objectFromID(_obj_invoke(self.handle, "TryFindBibliotecaItem", codigoInterno)); end; + + function mesa:findJogador(loginOuCodigoInterno) + if type(loginOuCodigoInterno) == "string" then + return rrpgWrappers.objectFromID(_obj_invoke(self.handle, "TryFindJogadorByLogin", loginOuCodigoInterno)); + elseif type(loginOuCodigoInterno) == "number" then + return rrpgWrappers.objectFromID(_obj_invoke(self.handle, "TryFindJogadorById", loginOuCodigoInterno)); + else + return nil; + end; + end; + + function mesa:getNome() return _obj_getProp(self.handle, "Nome"); end; + function mesa:getDescricao() return _obj_getProp(self.handle, "Descricao"); end; + function mesa:getMsgStatus() return _obj_getProp(self.handle, "MsgStatus"); end; + function mesa:getSite() return _obj_getProp(self.handle, "Site"); end; + function mesa:getLogotipo() return _obj_getProp(self.handle, "Logotipo"); end; + function mesa:getSistema() return _obj_getProp(self.handle, "Sistema"); end; + function mesa:getMsgBoasVindas() return _obj_getProp(self.handle, "MsgBoasVindas"); end; + function mesa:getCodigoInterno() return math.tointeger(_obj_getProp(self.handle, "CodigoInterno")); end; + function mesa:getIsRestrito18Anos() return _obj_getProp(self.handle, "IsRestrito18Anos"); end; + function mesa:getHaVagas() return _obj_getProp(self.handle, "HaVagas"); end; + function mesa:getIsModerada() return _obj_getProp(self.handle, "IsModerada"); end; + function mesa:getMeuJogador() return rrpgWrappers.contextObjectFromID(_obj_getProp(self.handle, "MeuJogadorObjectID")); end; + function mesa:getBiblioteca() return rrpgWrappers.contextObjectFromID(_obj_getProp(self.handle, "BibliotecaObjectID")); end; + function mesa:getPodeTablesDock() return _obj_getProp(self.handle, "PodeTablesDock"); end; + + function mesa:requestSetModerada(moderada) + moderada = Locale.autoEval(moderada); + __serverRequestQueue:addJob(function () _obj_invokeNoEval(self.handle, "RequestSetModerada", not (not moderada)); end); + end; + + function mesa:abrirNDBDeMesa(nome, callback, opcoes) + local ndbBib = require("ndb.lua"); + + if type(opcoes) ~= "table" then + opcoes = {}; + else + opcoes = Utils.cloneTable(opcoes, true); + end; + + opcoes.criar = not not opcoes.criar; + + local ndbHandle = _obj_invokeEx(self.handle, 'AbrirNDBDeMesa', tostring(nome) or "", opcoes.criar); + local ndbObj = nil; + local rootNode = nil; + + if ndbHandle ~= nil then + ndbObj = ndbBib.openNodeDatabaseFromHandle(ndbHandle); + end; + + if ndbObj ~= nil then + rootNode = ndbBib.getRoot(ndbObj); + end; + + if rootNode ~= nil then + local jaNotificou = false; + local jaNotificouEmCarregamento = false; + local listenerProvider = nil; + local listenerLoaded = nil; + + local function checkState() + if not jaNotificou then + local state = ndbBib.getState(rootNode); + + if state == "open" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, rootNode); + end; + elseif state == "closed" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, nil); + end; + else + if (not jaNotificouEmCarregamento) and (not jaNotificou) then + jaNotificouEmCarregamento = true; + + if opcoes.callbackDeCarga ~= nil then + opcoes.callbackDeCarga(rootNode); + end; + end; + end; + + if jaNotificou and (ndbObj ~= nil) then + ndbObj:removeEventListener(listenerProvider); + ndbObj:removeEventListener(listenerLoaded); + --ndbObj = nil; + end; + end; + end; + + listenerProvider = ndbObj:addEventListener("OnProviderStateChange", checkState); + listenerLoaded = ndbObj:addEventListener("OnLoaded", checkState); + + checkState(); + elseif callback ~= nil then + setTimeout(callback, 1, nil); + end; + end; + + function mesa:asyncOpenRoomNDB(name, options) + options = options or {}; + + local promise, resolution = Async.Promise.pending(); + + local adaptedOptions = {}; + adaptedOptions.criar = options.create; + + if options.skipLoad then + adaptedOptions.callbackDeCarga = + function(loadingNode) + resolution:setSuccess(loadingNode); + end; + end; + + self:abrirNDBDeMesa(name, + function(loadedNode) + if loadedNode ~= nil then + resolution:setSuccess(loadedNode); + else + resolution:setFailure("Could not load room nodedatabase"); + end; + end, + adaptedOptions); + + return promise; + end; + + function mesa:asyncOpenUserRoomNDB(name, options) + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncOpenUserRoomNDB", name, options)); + end); + end; + + function mesa:getFirecastURI() + return _obj_invokeEx(self.handle, "GetFirecastURI"); + end; + + function mesa:asyncOpenPVT(login, params) + local promiseHandle = _obj_invokeEx(self.handle, "AsyncOpenPVT", login, params); + return Async.Promise.wrap(promiseHandle); + end; + + function mesa:asyncCreateGroupPVT(logins, params) + local clonedLogins = Utils.cloneTable(logins); + local clonedParams = Utils.cloneTable(params); + + return __serverRequestQueue:addAsyncJob( + function () + local promiseHandle = _obj_invokeEx(self.handle, "AsyncCreateGroupPVT", clonedLogins, clonedParams); + return Async.Promise.wrap(promiseHandle); + end); + end; + + function mesa:getChats() + return _obj_invokeEx(self.handle, "GetChats"); + end; + + wObj.props["activeChat"] = {getter="getActiveChat", tipo="table"}; + wObj.props["audioPlayer"] = {getter="getAudioPlayer", tipo="table"}; + wObj.props["nome"] = {getter = "getNome", tipo = "string"}; + wObj.props["descricao"] = {getter = "getDescricao", tipo = "string"}; + wObj.props["msgStatus"] = {getter = "getMsgStatus", tipo = "string"}; + wObj.props["site"] = {getter = "getSite", tipo = "string"}; + wObj.props["logotipo"] = {getter = "getLogotipo", tipo = "string"}; + wObj.props["sistema"] = {getter = "getSistema", tipo = "string"}; + wObj.props["msgBoasVindas"] = {getter = "getMsgBoasVindas", tipo = "string"}; + wObj.props["codigoInterno"] = {getter = "getCodigoInterno", tipo = "int"}; + wObj.props["firecastURI"] = {getter = "getFirecastURI", tipo = "string"}; + wObj.props["isRestrito18Anos"] = {getter = "getIsRestrito18Anos", tipo = "bool"}; + wObj.props["haVagas"] = {getter = "getHaVagas", tipo = "bool"}; + wObj.props["isModerada"] = {getter = "getIsModerada", tipo = "bool"}; + wObj.props["podeTablesDock"] = {getter = "getPodeTablesDock", tipo = "bool"}; + wObj.props["jogadores"] = {getter = "getJogadores", tipo = "table"}; + wObj.props["meuJogador"] = {getter = "getMeuJogador", tipo = "table"}; + wObj.props["biblioteca"] = {getter = "getBiblioteca", tipo = "table"}; + wObj.props["chat"] = {getter="getChat", tipo="table"}; + + wObj.props["library"] = wObj.props["biblioteca"]; + wObj.props["me"] = wObj.props["meuJogador"]; + + return wObj; +end; + +--[ OBJETO JOGADOR ]-- + +local function initJogadorWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local jogador = wObj; + + function jogador:getMesa() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "MesaID")); end; + function jogador:getNick() return _obj_getProp(self.handle, "Nick"); end; + function jogador:getLogin() return _obj_getProp(self.handle, "Login"); end; + function jogador:getAvatar() return _obj_getProp(self.handle, "Avatar"); end; + function jogador:getCapa() return _obj_getProp(self.handle, "Capa"); end; + function jogador:getIsGold() return _obj_getProp(self.handle, "IsGold"); end; + function jogador:getIsGoldPlus() return _obj_getProp(self.handle, "IsGoldPlus"); end; + function jogador:getIsRuby() return _obj_getProp(self.handle, "IsRuby"); end; + function jogador:getIsAusente() return _obj_getProp(self.handle, "IsAusente"); end; + function jogador:getIsCnxDormente() return _obj_getProp(self.handle, "IsCnxDormente"); end; + function jogador:getIsSessaoMobile() return _obj_getProp(self.handle, "IsSessaoMobile"); end; + function jogador:getIsJuggernaut() return _obj_getProp(self.handle, "IsJuggernaut"); end; + function jogador:getIsMestre() return _obj_getProp(self.handle, "IsMestre"); end; + function jogador:getIsJogador() return _obj_getProp(self.handle, "IsJogador"); end; + function jogador:getIsEspectador() return _obj_getProp(self.handle, "IsEspectador"); end; + function jogador:getIsMudo() return _obj_getProp(self.handle, "IsMudo"); end; + function jogador:getIsCego() return _obj_getProp(self.handle, "IsCego"); end; + function jogador:getHaveVoice() return _obj_getProp(self.handle, "HaveVoice"); end; + function jogador:getCodigoInterno() return _obj_getProp(self.handle, "CodigoInterno"); end; + + function jogador:__innerRequestSetMode(modo, ativar) + modo, ativar = Locale.autoEval(modo, ativar); + + __serverRequestQueue:addJob(function() + _obj_invokeNoEval(self.handle, "RequestSetMode", modo, not (not ativar)); + end); + end; + + function jogador:requestSetCego(cego) self:__innerRequestSetMode("cego", cego); end; + function jogador:requestSetMudo(mudo) self:__innerRequestSetMode("mudo", mudo); end; + function jogador:requestSetVoz(voz) self:__innerRequestSetMode("voz", voz); end; + function jogador:requestSetJogador(isJogador) self:__innerRequestSetMode("jogador", isJogador); end; + function jogador:requestKick() __serverRequestQueue:addJob(function() _obj_invoke(self.handle, "RequestKick", ""); end); end; + function jogador:getBarValue(index) return _obj_invokeEx(self.handle, "LuaGetBarValue", index); end; + + function jogador:requestSetBarValue(index, currentValue, maxValue) + index, currentValue, maxValue = Locale.autoEval(index, currentValue, maxValue); + + __serverRequestQueue:addJob( + function() + _obj_invokeExNoEval(self.handle, "LuaRequestSetBarValue", index, currentValue, maxValue); + end); + end; + + function jogador:getEditableLine(index) return _obj_invokeEx(self.handle, "LuaGetEditableLine", index); end; + function jogador:requestSetEditableLine(index, text) index, text = Locale.autoEval(index, text); __serverRequestQueue:addJob(function() _obj_invokeExNoEval(self.handle, "LuaRequestSetEditableLine", index, text); end); end; + + wObj.props["mesa"] = {getter = "getMesa", tipo = "table"}; + wObj.props["nick"] = {getter = "getNick", tipo = "string"}; + wObj.props["login"] = {getter = "getLogin", tipo = "string"}; + wObj.props["avatar"] = {getter = "getAvatar", tipo = "string"}; + wObj.props["isGold"] = {getter = "getIsGold", tipo = "bool"}; + wObj.props["isGoldPlus"] = {getter = "getIsGoldPlus", tipo = "bool"}; + wObj.props["isRuby"] = {getter = "getIsRuby", tipo = "bool"}; + wObj.props["isAusente"] = {getter = "getIsAusente", tipo = "bool"}; + wObj.props["isCnxDormente"] = {getter = "getIsCnxDormente", tipo = "bool"}; + wObj.props["isSessaoMobile"] = {getter = "getIsSessaoMobile", tipo = "bool"}; + wObj.props["isJuggernaut"] = {getter = "getIsJuggernaut", tipo = "bool"}; + wObj.props["isMestre"] = {getter = "getIsMestre", tipo = "bool"}; + wObj.props["isJogador"] = {getter = "getIsJogador", tipo = "bool"}; + wObj.props["isEspectador"] = {getter = "getIsEspectador", tipo = "bool"}; + wObj.props["isMudo"] = {getter = "getIsMudo", tipo = "bool"}; + wObj.props["isCego"] = {getter = "getIsCego", tipo = "bool"}; + wObj.props["haveVoice"] = {getter = "getHaveVoice", tipo = "bool"}; + wObj.props["haveVoz"] = {getter = "getHaveVoice", tipo = "bool"}; + wObj.props["codigoInterno"] = {getter = "getCodigoInterno", tipo = "int"}; + wObj.props["personagemPrincipal"] = {readProp="PersonagemPrincipal", tipo = "int"}; + wObj.props["id"] = {readProp="ID", tipo = "int"}; + + return wObj; +end; + +--[ OBJETO BIBLIOTECA ITEM ]-- + +local function initBibliotecaItemWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local bibItem = wObj; + + function bibItem:getFilhos() + local hs = _obj_getProp(self.handle, "FilhosObjectIDs"); + local filhos = {}; + local idx = 1; + + for p, v in pairs(hs) do + filhos[idx] = rrpgWrappers.objectFromID(v); + idx = idx + 1; + end + + return filhos; + end; + + function bibItem:__asyncCreateBibItem(bibItemType, params) + assert(type(params) == "table"); + + local innerPromise = __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncCreateBibItemObjectID", bibItemType, params)); + end); + + return Async.Promise.toHandle(innerPromise, + function (newObjectID) + local newObj = rrpgWrappers.contextObjectFromID(newObjectID); + + if newObj ~= nil then + return newObj; + else + error("Could not find the new created library item"); + end; + end); + end; + + function bibItem:asyncCreateChar(charParams) + if type(charParams) ~= "table" then + error("charParams must be a table"); + end; + + if charParams.name == nil then + error("Required field: charParams.name"); + end; + + if charParams.name == nil then + error("Required field: charParams.dataType"); + end; + + return bibItem:__asyncCreateBibItem('character', charParams); + end; + + function bibItem:asyncCreateDir(dirParams) + if type(dirParams) ~= "table" then + error("dirParams must be a table"); + end; + + if dirParams.name == nil then + error("Required field: dirParams.name"); + end; + + return bibItem:__asyncCreateBibItem('directory', dirParams); + end; + + function bibItem:asyncCreateScene3(gridParams) + if type(gridParams) ~= "table" then + error("gridParams must be a table"); + end; + + if gridParams.name == nil then + error("Required field: gridParams.name"); + end; + + return bibItem:__asyncCreateBibItem('scene3', gridParams); + end; + + function bibItem:asyncDelete() + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(bibItem.handle, "AsyncDelete")); + end); + end; + + function bibItem:asyncMoveTo(newParent) + if type(newParent) ~= 'table' then + error('Parameter "newParent" must be an object'); + end; + + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(bibItem.handle, "AsyncMoveTo", newParent.objectID)); + end); + end; + + function bibItem:asyncUpdate(changes) + if type(changes) ~= 'table' then + error('Parameter "changes" must be a table'); + end; + + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(bibItem.handle, "AsyncUpdate", changes)); + end); + end; + + function bibItem:getFirecastURI() + return _obj_invokeEx(self.handle, "GetFirecastURI"); + end; + + function bibItem:getMesa() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "MesaObjectID")); end; + function bibItem:getNome() return _obj_getProp(self.handle, "Nome"); end; + function bibItem:getPai() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "ItemMaeObjectID")); end; + function bibItem:getDono() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "JogadorOwnerObjectID")); end; + function bibItem:getLoginDono() return _obj_getProp(self.handle, "LoginDono"); end; + function bibItem:getCriador() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "JogadorCriadorObjectID")); end; + function bibItem:getLoginCriador() return _obj_getProp(self.handle, "LoginCriador"); end; + function bibItem:getVisivel() return _obj_getProp(self.handle, "Visivel"); end; + function bibItem:getVisivelRecursivamente() return _obj_getProp(self.handle, "VisivelNaHierarquia"); end; + function bibItem:getTipo() return _obj_getProp(self.handle, "Tipo"); end; + function bibItem:getCodigoInterno() return _obj_getProp(self.handle, "CodigoInterno"); end; + + wObj.props["mesa"] = {getter = "getMesa", tipo = "table"}; + wObj.props["filhos"] = {getter = "getFilhos", tipo = "table"}; + wObj.props["pai"] = {getter = "getPai", tipo = "table"}; + wObj.props["nome"] = {getter = "getNome", tipo = "string"}; + wObj.props["dono"] = {getter = "getDono", tipo = "table"}; + wObj.props["loginDono"] = {getter = "getLoginDono", tipo = "string"}; + wObj.props["criador"] = {getter = "getCriador", tipo = "table"}; + wObj.props["loginCriador"] = {getter = "getLoginCriador", tipo = "string"}; + wObj.props["visivel"] = {getter = "getVisivel", tipo = "bool"}; + wObj.props["visivelRecursivamente"] = {getter = "getVisivelRecursivo", tipo = "bool"}; + wObj.props["tipo"] = {getter = "getTipo", tipo = "string"}; + wObj.props["codigoInterno"] = {getter = "getCodigoInterno", tipo = "int"}; + + wObj.props["room"] = wObj.props["mesa"]; + wObj.props["parent"] = wObj.props["pai"]; + wObj.props["name"] = wObj.props["nome"]; + wObj.props["children"] = wObj.props["filhos"]; + wObj.props["firecastURI"] = {getter = "getFirecastURI", tipo = "string"}; + wObj.props["ownerLogin"] = wObj.props["loginDono"]; + wObj.props["creatorLogin"] = wObj.props["loginCriador"]; + wObj.props["creator"] = wObj.props["criador"]; + wObj.props["owner"] = wObj.props["dono"]; + wObj.props["visible"] = wObj.props["visivel"]; + wObj.props["recursiveVisible"] = wObj.props["visivelRecursivamente"]; + return wObj; +end; + +--[ OBJETO PERSONAGEM ]-- + +local __PersonagemWrappedObjectProps = {}; + +for i = 0, 3 do + local barIndex = i; + + __PersonagemWrappedObjectProps["bar" .. tostring(i) .. "Val"] = {tipo = "int", getter = function (personagem) + return _obj_invokeEx(personagem.handle, "GetBarVal", barIndex) + end}; + + __PersonagemWrappedObjectProps["bar" .. tostring(i) .. "Max"] = {tipo = "int", getter = function (personagem) + return _obj_invokeEx(personagem.handle, "GetBarMax", barIndex) + end}; +end; + +for i = 0, 1 do + local edtLineIndex = i; + + __PersonagemWrappedObjectProps["edtLine" .. tostring(i)] = {tipo = "string", getter = function (personagem) + return _obj_invokeEx(personagem.handle, "GetEdtLine", edtLineIndex) + end}; +end; + +local function initBibPersonagemWrappedObjectFromHandle(handle) + local wObj = initBibliotecaItemWrappedObjectFromHandle(handle); + local bibItem = wObj; + + function bibItem:getDataType() return _obj_getProp(self.handle, "DataType"); end; + function bibItem:getEscritaBloqueada() return _obj_getProp(self.handle, "EscritaBloqueada"); end; + + function bibItem:loadSheetNDB(callback, params) + params = params or {}; + + local ndbBib = require("ndb.lua"); + local ndbHandle = _obj_invokeEx(self.handle, 'GetOrCreateSheetNDB'); + + local function scheduleFailReturn() + if callback ~= nil then + setTimeout(callback, 1, nil); + end; + end; + + if ndbHandle == nil then + scheduleFailReturn(); + return; + end; + + local ndbObj = nil; + local rootNode = nil; + + if ndbHandle ~= nil then + ndbObj = ndbBib.openNodeDatabaseFromHandle(ndbHandle); + end; + + if ndbObj ~= nil then + rootNode = ndbBib.getRoot(ndbObj); + end; + + if rootNode == nil then + scheduleFailReturn(); + return; + end; + + local state = ndbBib.getState(rootNode); + + if (state == "open") or + ((state == "opening") and (params.skipLoad)) then + -- Already loaded + if callback ~= nil then + callback(rootNode); + end; + + return; + end; + + -- Not loaded yet, letz monitor + + local jaNotificou = false; + local listenerProvider = nil; + local listenerLoaded = nil; + + local function checkState() + if not jaNotificou then + state = ndbBib.getState(rootNode); + + if state == "open" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, rootNode); + end; + elseif state == "closed" then + jaNotificou = true; + scheduleFailReturn(); + end; + + if jaNotificou then + ndbObj:removeEventListener(listenerProvider); + ndbObj:removeEventListener(listenerLoaded); + end; + end; + end; + + listenerProvider = ndbObj:addEventListener("OnProviderStateChange", checkState); + listenerLoaded = ndbObj:addEventListener("OnLoaded", checkState); + + checkState(); + end; + + function bibItem:asyncOpenNDB(options) + options = options or {}; + local promise, resolution = Async.Promise.pending(); + + self:loadSheetNDB( + function (loadedNDB) + if loadedNDB ~= nil then + resolution:setSuccess(loadedNDB); + else + resolution:setFailure("Could not load character nodedatabase"); + end; + end, options); + + return promise; + end; + + wObj.props["dataType"] = {getter = "getDataType", tipo = "string"}; + wObj.props["escritaBloqueada"] = {getter = "getEscritaBloqueada", tipo = "bool"}; + wObj.props["avatar"] = {readProp="Avatar", tipo = "string"}; + + for k, v in pairs(__PersonagemWrappedObjectProps) do + wObj.props[k] = v; + end; + + wObj.props["editionBlocked"] = wObj.props["escritaBloqueada"]; + return wObj; +end; + +--[ OBJETO SceneUnitClass ]-- + +local function initBibSceneUnitClassWrappedObjectFromHandle(handle) + local wObj = initBibliotecaItemWrappedObjectFromHandle(handle); + + wObj.props["tamanhoX"] = {readProp = "TamanhoX", tipo = "double"}; + wObj.props["tamanhoY"] = {readProp = "TamanhoY", tipo = "double"}; + wObj.props["camada"] = {readProp = "Camada", tipo = "enum", values={"tokens", "objects", "background"}}; + wObj.props["descricao"] = {readProp = "Descricao", tipo = "string"}; + wObj.props["urlImg"] = {readProp = "URLImg", tipo = "string"}; + wObj.props["facing"] = {readProp = "Facing", tipo = "enum", values={"rotate", "drawArrow"}}; + wObj.props["snapToGrid"] = {readProp = "SnapToGrid", tipo = "bool"}; + wObj.props["direcaoImg"] = {readProp = "DirecaoImg", tipo = "double"}; + wObj.props["layoutCenterX"] = {readProp = "LayoutCenterX", tipo = "double"}; + wObj.props["layoutCenterY"] = {readProp = "LayoutCenterY", tipo = "double"}; + wObj.props["layoutTamX"] = {readProp = "LayoutTamX", tipo = "double"}; + wObj.props["layoutTamY"] = {readProp = "LayoutTamY", tipo = "double"}; + + return wObj; +end; + + +--[ OBJETO CHAT ]-- + +local function _setupCallbackTrapForUniqueRoll(idOfRoll, callbackFunction) + local trabTable = {}; + + trabTable.listenerId = rrpg.messaging.listenOnce("InternalRollCallbackReceive", + function(msg) + clearTimeout(trabTable.timeoutId); + trabTable.timeoutId = nil; + + if type(callbackFunction) == "function" then + local rolagemObject = rrpg.loadRolagemFromBase64EncodedString(msg.rollBase64 or ""); + callbackFunction(rolagemObject); + end; + end, {id=idOfRoll}); + + trabTable.timeoutId = setTimeout( + function() + rrpg.messaging.unlisten(trabTable.listenerId); + trabTable.listenerId = nil; + end, 120000); +end; + +local _NULL_FUNCTION = function() end; +local _NULL_ARRAY_FUNCTION = function() return {}; end; +local _NULL_PROMISE_FUNCTION = function() Async.Promise.failed("Chat is not alive"); end; + +rrpgWrappers.NullChatWrapper = {enviarMensagem = _NULL_FUNCTION, + rolarDados = _NULL_FUNCTION, + enviarAcao = _NULL_FUNCTION, + enviarRisada = _NULL_FUNCTION, + enviarMensagemNPC = _NULL_FUNCTION, + enviarNarracao = _NULL_FUNCTION, + setImpersonation = _NULL_FUNCTION, + readLogRecs = _NULL_ARRAY_FUNCTION, + asyncQueryLogRecs = _NULL_PROMISE_FUNCTION, + asyncSendLaugh = _NULL_PROMISE_FUNCTION, + asyncSendAction = _NULL_PROMISE_FUNCTION, + asyncSendStd = _NULL_PROMISE_FUNCTION, + asyncInvite = _NULL_PROMISE_FUNCTION, + participants = {}, + medium = {kind="undefined"} + }; + +local function initBaseChatWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local wChat = wObj; + + function wChat:_getTimedJobQueue() + local queue = rawget(self, "_timedJobQueue"); + + if queue == nil then + queue = newTimedJobQueue(250); + rawset(self, "_timedJobQueue", queue); + end; + + return queue; + end; + + function wChat:_getLongTimedJobQueue() + local queue = rawget(self, "_longTimedJobQueue"); + + if queue == nil then + queue = newTimedJobQueue(1000); + rawset(self, "_longTimedJobQueue", queue); + end; + + return queue; + end; + + function wChat:escrever(texto, quebrarLinha, permitirSmileys) + if quebrarLinha == nil then + quebrarLinha = true; + end; + + if permitirSmileys == nil then + permitirSmileys = true; + end; + + if texto ~= nil then + return _obj_invokeEx(self.handle, "Escrever", tostring(texto), quebrarLinha, permitirSmileys); + end; + end; + + function wChat:enviarMensagem(msg, callback) + msg = Locale.autoEval(tostring(msg)); + + if msg ~= nil then + local queue = self:_getTimedJobQueue() + + function queuedSendTheMessage() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarMensagem", msg); + + if type(callback) == 'function' then + callback(); + end; + end; + end; + + queue:addJob(queuedSendTheMessage); + end; + end; + + function wChat:enviarMensagemNPC(npc, msg, callback) + npc, msg = Locale.autoEval(npc, msg); + + if msg ~= nil and npc ~= nil then + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarMensagemNPC", tostring(npc), tostring(msg)); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + end; + + function wChat:enviarNarracao(msg, callback) + msg = Locale.autoEval(msg); + + if msg ~= nil then + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarNarracao", tostring(msg)); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + end; + + function wChat:enviarAcao(acao, callback) + acao = Locale.autoEval(acao); + + if acao ~= nil then + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarAcao", tostring(acao)); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + end; + + function wChat:enviarRisada(callback) + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invoke(wChat.handle, "EnviarRisada"); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + + function wChat:rolarDados(rolagem, msg, callbackFunction) + local rolAsStr; + msg = Locale.autoEval(msg); + + if type(rolagem) == "string" then + rolAsStr = Locale.autoEval(rolagem); + elseif (type(rolagem) == "table") and (rolagem.getAsString ~= nil) then + rolAsStr = rolagem:getAsString(); + else + rolAsStr = nil; + end; + + if rolAsStr ~= nil then + local queue = self:_getTimedJobQueue() + --local queue = __serverRequestQueue; + + if type(callbackFunction) == "function" then + local idUnicaRolagem = _rrpg_generateUniqueMessageIDForMe(); + _setupCallbackTrapForUniqueRoll(idUnicaRolagem, callbackFunction); + + queue:addJob( + function () + if self.handle ~= nil then + return _obj_invokeNoEval(self.handle, "EnviarRolagemEx", rolAsStr, msg, idUnicaRolagem); + end; + end); + else + queue:addJob( + function () + if self.handle ~= nil then + return _obj_invokeNoEval(self.handle, "EnviarRolagem", rolAsStr, msg); + end; + end); + end; + end; + end; + + function wChat:getRoom() + local selfHandle = rawget(self, "handle"); + + if selfHandle ~= nil then + mesaObjectID = _rrpg_tryGetMesaObjectIDRelatedToHandle(selfHandle); + + if (mesaObjectID ~= nil) then + mesaObjectID = tonumber(mesaObjectID); + end; + + if mesaObjectID ~= nil then + return rrpgWrappers.contextObjectFromID(mesaObjectID); + end; + end; + end; + + function wChat:__asyncSendEx(msgDesc, params) + local finalMsgDesc = Utils.cloneTable(params) or {}; + + for k, v in pairs(msgDesc) do + finalMsgDesc[k] = v; + end; + + local queue = self:_getTimedJobQueue() + + return queue:addAsyncJob( + function() + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncSendEx", finalMsgDesc)); + end); + end; + + function wChat:asyncSendStd(content, params) + return self:__asyncSendEx({msgType="standard", content=content}, params); + end; + + function wChat:asyncSendAction(content, params) + return self:__asyncSendEx({msgType="action", content=content}, params); + end; + + function wChat:asyncSendLaugh(params) + return self:__asyncSendEx({msgType="laugh"}, params); + end; + + function wChat:asyncRoll(expression, message, params) + local expressionAsStr; + + if type(expression) == "string" then + expressionAsStr = Locale.autoEval(expression); + elseif (type(expression) == "table") and (expression.getAsString ~= nil) then + expressionAsStr = expression:getAsString(); + else + expressionAsStr = nil; + end; + + local sendPromise = self:__asyncSendEx({msgType="dice", expression=expressionAsStr, content=message}, params); + + return sendPromise:thenDo( + function(logRec) + local roll = logRec.msg.roll; + assert(roll ~= nil); + + return roll.resultado, roll, logRec; + end); + end; + + function wChat:readLogRecs() + return _obj_invokeEx(self.handle, "ReadValidLogRecs"); + end; + + function wChat:getImpersonation() + return _obj_invokeEx(self.handle, "GetUIImpersonation"); + end; + + function wChat:setImpersonation(impersonation) + return _obj_invokeEx(self.handle, "SetUIImpersonation", impersonation); + end; + + function wChat:getTalemarkOptions() + return _obj_invokeEx(self.handle, "GetTalemarkOptions"); + end; + + function wChat:setTalemarkOptions(options) + return _obj_invokeEx(self.handle, "SetTalemarkOptions", options); + end; + + function wChat:getMedium() + return _obj_invokeEx(self.handle, "GetMedium"); + end; + + function wChat:getParticipants() + return _obj_invokeEx(self.handle, "GetParticipants"); + end; + + function wChat:asyncQueryLogRecs(params) + params = Utils.cloneTable(params or {}); + + local queue = self:_getLongTimedJobQueue() + + return queue:addAsyncJob( + function() + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncQueryLogRecsFromServer", params)); + end); + end; + + function wChat:writeEx(text, talemarkOptions) + return _obj_invokeEx(self.handle, "WriteEx", text, talemarkOptions); + end; + + function wChat:asyncInvite(logins) + local clonedLogins = Utils.cloneTable(logins); + + return __serverRequestQueue:addAsyncJob( + function () + local promiseHandle = _obj_invokeEx(self.handle, "AsyncInvite", clonedLogins); + return Async.Promise.wrap(promiseHandle); + end); + end; + + wChat.props["room"] = {getter = "getRoom", tipo = "table"}; + wChat.props["impersonation"] = {getter = "getImpersonation", setter = "setImpersonation", tipo = "table"}; + wChat.props["talemarkOptions"] = {getter = "getTalemarkOptions", setter="setTalemarkOptions", tipo = "table"}; + wChat.props["medium"] = {getter = "getMedium", tipo = "table" }; + wChat.props["participants"] = {getter = "getParticipants", tipo = "table" }; + + -- aliases + wChat.write = wChat.escrever; + + return wObj; +end; + +function rrpgWrappers.contextObjectFromID(objectID) + local ctxObj = localStrongRefContextoObjects[objectID]; + + if ctxObj ~= nil then + return ctxObj; + end; + + local objWrapperHandle; + objWrapperHandle = _rrpg_GetOrCreateObjectWrapperForObjectID(objectID); + + if objWrapperHandle == nil then + return nil; + end; + + ctxObj = objs.tryFindFromHandle(objWrapperHandle); + + if ctxObj ~= nil then + if _rrpg_IsObjectIDAlive(objectID) then + localStrongRefContextoObjects[objectID] = ctxObj; + end; + + return ctxObj; + end; + + + if _rrpg_IsWrapperOfType(objWrapperHandle, "mesa") then + ctxObj = initMesaWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "jogador") then + ctxObj = initJogadorWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "personagem") then + ctxObj = initBibPersonagemWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "sceneUnitClass") then + ctxObj = initBibSceneUnitClassWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "bibliotecaItem") then -- Deve ser o ultimo dos IFs dos Wrappers dos tipos de item de biblioteca + ctxObj = initBibliotecaItemWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "chatBase") then -- Deve ser o ultimo dos IFs dos Wrappers dos tipos de CHAT + ctxObj = initBaseChatWrappedObjectFromHandle(objWrapperHandle); + else + ctxObj = initWrappedObjectFromHandle(objWrapperHandle); + end; + + objs.registerHandle(objWrapperHandle, ctxObj); + + if _rrpg_IsObjectIDAlive(objectID) then + localStrongRefContextoObjects[objectID] = ctxObj; + end; + + return ctxObj; +end; + +function rrpgWrappers.objectFromID(objectID) + return rrpgWrappers.contextObjectFromID(objectID); +end; + +function _INTERNAL_EVE_OnWrappedObjectWasDestroyed(objectID) + localStrongRefContextoObjects[objectID] = nil; -- Permitir o Garbage Collector coletar este objeto +end; + +function _INTERNAL_AUX_ContextObjectFromID(objectID) + return rrpgWrappers.contextObjectFromID(objectID); +end; + +function _INTERNAL_AUX_NullChatWrapper() + return rrpgWrappers.NullChatWrapper; +end; + +SharedObjects.registerUnpacker(SHARED_OBJECT_TYPE, + function (sid) + local objectIdN = tonumber(sid.objectID); + + if objectIdN ~= nil then + return rrpgWrappers.contextObjectFromID(objectIdN); + else + return nil; + end; + end); + +return rrpgWrappers; \ No newline at end of file diff --git a/sdk/scene.lua b/sdk/scene.lua new file mode 100644 index 00000000..ff21abba --- /dev/null +++ b/sdk/scene.lua @@ -0,0 +1,13 @@ +local _SceneLib = require("delayedLoad.dlua").new("sceneCore.dlua"); +local _SceneWrapperLib = nil; + +function _INTERNAL_export_getSceneObjectFromID(objectID) + if _SceneWrapperLib == nil then + _SceneWrapperLib = require("sceneWrappers.dlua"); + end; + + return _SceneWrapperLib.objectFromID(objectID); +end; + +SceneLib = _SceneLib; +return _SceneLib; diff --git a/sdk/sceneCore.dlua b/sdk/sceneCore.dlua new file mode 100644 index 00000000..c0651997 --- /dev/null +++ b/sdk/sceneCore.dlua @@ -0,0 +1,146 @@ +local Objs = require("rrpgObjs.lua") +local SceneWrappers = require("sceneWrappers.dlua"); +require("utils.lua"); +require("rrpg.lua"); + +local SceneLib = {}; +local LocalSceneLib = {}; + + +-- OBJETO SC3PLUGIN + +local __runningPlugins = {}; + +function LocalSceneLib.newPlugin() + local handle = _obj_newObject('TSC3LuaPlugin'); + local o = Objs.objectFromHandle(handle); + + + Objs.registerHandle(handle, o); + return o; +end; + +-- Funções públicas da SceneLib + +function SceneLib.registerPlugin(attachCallback) + local plug = LocalSceneLib.newPlugin(); + local pluginAttachments = {}; + + __runningPlugins[plug.handle] = plug; + + setTimeout( + function() + if __runningPlugins[plug.handle] ~= nil then + _obj_invoke(plug.handle, "RegisterYourself"); + end; + end, 1); + + local function startAttachToScene(scene) + local oID = scene.objectID; + local att = pluginAttachments[oID]; + + if att ~= nil then + return; + end; + + att = Objs.objectFromHandle(_obj_invoke(plug.handle, "LuaCreatePluginAttachment", oID)); + + if att ~= nil then + Objs.registerHandle(att.handle, att); + + local eves = att.eves; + + if eves == nil then + att.eves = {}; + eves = att.eves; + end; + + eves["OnDettach"] = ""; + + pluginAttachments[oID] = att; + + if attachCallback ~= nil then + setTimeout(function() + if scene ~= nil and scene.isObjectAlive then + attachCallback(scene, att); + end; + end, 1) + end; + end; + end; + + local function startDettachFromScene(scene) + local oID = scene.objectID; + local att = pluginAttachments[oID]; + + if att ~= nil then + pluginAttachments[oID] = nil; + end; + end; + + -- Anexar aos scenes já rodando... + local scenes = SceneLib.getLoadedScenes(); + + for i = 1, #scenes, 1 do + startAttachToScene(scenes[i]); + end; + + -- Instalar listeners para detectar novos scenes rodando + + plug._lstSceneLoaded = RRPG.listen('SC3SceneLoaded', + function(msg) + if msg.scene ~= nil then + startAttachToScene(msg.scene); + msg.scene = nil; + end; + end); + + plug._lstSceneUnloaded = RRPG.listen('SC3SceneUnloaded', + function(msg) + if msg.scene ~= nil then + startDettachFromScene(msg.scene); + msg.scene = nil; + end; + end); + + return plug.handle; +end; + +function SceneLib.unregisterPlugin(pluginHandle) + local plug = __runningPlugins[pluginHandle]; + + if plug ~= nil then + if plug._lstSceneUnloaded ~= nil then + RRPG.unlisten(plug._lstSceneUnloaded); + plug._lstSceneUnloaded = nil; + end; + + if plug._lstSceneLoaded ~= nil then + RRPG.unlisten(plug._lstSceneLoaded); + plug._lstSceneLoaded = nil; + end; + + _obj_invoke(plug.handle, "UnregisterYourself"); + __runningPlugins[pluginHandle] = nil; + _obj_invoke(plug.handle, "DettachAllAttachments"); + end; +end; + +function SceneLib.getLoadedScenes() + local L = _scene3_GetLoadedScenesObjectIDs(); + + for i = 1, #L, 1 do + L[i] = SceneWrappers.objectFromID(L[i]); + end; + + return L; +end; + + +SceneLib.Math = {}; + +SceneLib.Math.newRotationMatrix = _scene3_math_newRotationMatrix; +SceneLib.Math.transformPoint = _scene3_math_transformPoint; +SceneLib.Math.rotatePoint = _scene3_math_rotatePoint; + +return SceneLib; \ No newline at end of file diff --git a/sdk/sceneWrappers.dlua b/sdk/sceneWrappers.dlua new file mode 100644 index 00000000..d93f30c7 --- /dev/null +++ b/sdk/sceneWrappers.dlua @@ -0,0 +1,1123 @@ +local Objs = require("rrpgObjs.lua"); +local objs = Objs; +local NDB = require("ndb.lua"); +local GUI = nil; + +local _userDataScopeAttr = '__userDataScope'; + +local SceneWrappers = {}; + +local _localStrongRefSceneObjects = {}; + +--- [[ Wrapper Object BASE ]] +local function initWrappedObjectFromHandle(handle) + local wObj = Objs.objectFromHandle(handle); + + if (wObj.props == nil) then + wObj.props = {}; + end; + + function wObj:getObjectID() return _obj_getProp(self.handle, "ObjectID"); end; + function wObj:getObjectType() return _obj_getProp(self.handle, "WrappedObjectType"); end; + function wObj:getIsObjectAlive() return _obj_getProp(self.handle, "IsObjectAlive"); end; + function wObj:isType(typeName) return _scene3_IsWrapperOfType(self.handle, typeName); end; + function wObj:beginUpdate() _obj_invoke(self.handle, "BeginUpdate"); end; + function wObj:endUpdate() _obj_invoke(self.handle, "EndUpdate"); end; + function wObj:getUserData() return _obj_invokeEx(self.handle, "GetUserData"); end; + + function wObj:newUserDataLink(field) + if GUI == nil then + GUI = require("gui.lua"); + end; + + local dataScope = rawget(self, _userDataScopeAttr); + + if dataScope == nil then + dataScope = Objs.hierarchyObjectFromHandle(_obj_newObject("nonVisualDataScope")); + rawset(self, _userDataScopeAttr, dataScope); + _obj_invokeEx(self.handle, "PrepareUserDataScope", dataScope.handle); + end + + local dl = GUI.newDataLink(); + + if field ~= nil then + dl.field = field; + end; + + dl:setParent(dataScope); + return dl; + end; + + wObj.props["objectType"] = {getter = "getObjectType", tipo = "string"}; + wObj.props["isObjectAlive"] = {getter = "getIsObjectAlive", tipo = "bool"}; + wObj.props["objectID"] = {getter = "getObjectID", tipo = "int"}; + wObj.props["userData"] = {getter = "getUserData", tipo = "table"}; + + rawset(wObj, "objectID", wObj:getObjectID()); + return wObj; +end; + +--- [[ Wrapper Object SCENE ]] + +local __sceneProps = {worldWidth = {tipo = "double", readProp = "WorldWidth", writeProp = "WorldWidth"}, + worldHeight = {tipo = "double", readProp = "WorldHeight", writeProp = "WorldHeight"}, + worldMetricName = {tipo = "string", readProp = "WorldMetricName", writeProp = "WorldMetricName"}, + bkgColor = {tipo = "color", readProp = "BkgColor", writeProp = "BkgColor"}, + bkgImageURL = {tipo = "string", readProp="BkgImageURL", writeProp = "BkgImageURL"}, + workingLayer = {tipo = "enum", readProp = "WorkingLayer", writeProp = "WorkingLayer", values={"background", "objects", "tokens"}}, + viewport = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_scene3_getViewportObjectIDOfScene(obj.objectID)); end;}, + grid = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "GridLayerObjectID")); end;}, + items = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "ItemsObjectID")); end}, + fogOfWar = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "FogOfWarObjectID")); end}, + isGM = {tipo="bool", readProp="IsGM"}, + currentUserID = {tipo="string", readProp="CurrentUserID"}, + isViewingAsGM = {tipo="bool", readProp="IsViewingAsGM", writeProp = "IsViewingAsGM"}, + isViewingWalls = {tipo="bool", readProp="IsViewingWalls", writeProp = "IsViewingWalls"}, + renderAsPlayer = {tipo="bool", readProp="RenderAsPlayer"}}; + +local __sceneEvents = {onWorkingLayerChange="", + onGMStateChange=""}; + +local __sceneMethods = { + newTransaction = function(scene) + local tr = Objs.objectFromHandle(_obj_newObject("TLuaScene3Transaction")); + Objs.registerHandle(tr.handle, tr); + _obj_invoke(tr.handle, "Initialize", scene.objectID); + + tr.commit = function(trObj) + _obj_invoke(trObj.handle, "Commit"); + end; + + tr.rollback = function(trObj) + _obj_invoke(trObj.handle, "Rollback"); + end; + + tr.createUndoData = function (trObj) + local handle = _obj_invoke(trObj.handle, "CreateUndoData"); + local obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + return obj; + end; + + tr.applyUndoData = function(trObj, undoData) + _obj_invoke(trObj.handle, "ApplyUndoData", undoData.handle); + end; + + return tr; + end, + + pushTransaction = function(scene, transaction) + local trHandle; + + if transaction ~= nil then + trHandle = transaction.handle or 0; + else + trHandle = 0; + end; + + _obj_invoke(scene.handle, "PushTransaction", trHandle); + end, + + popTransaction = function(scene) + _obj_invoke(scene.handle, "PopTransaction"); + end, + + processCommand = function(scene, command) + return _obj_invokeEx(scene.handle, "ProcessCommand", command); + end, + + broadcastMessage = function(scene, messageId, message, loopBack) + local node = _obj_invokeEx(scene.handle, "LuaGetSceneNode"); + + if node ~= nil then + return NDB.broadcastMessage(node, messageId, message, loopBack); + end; + end, + + newBroadcastListener = function(scene, messageId, callback) + local node = _obj_invokeEx(scene.handle, "LuaGetSceneNode"); + + if node ~= nil then + return NDB.newBroadcastListener(node, messageId, + function(sender, returnedMessageId, message) + if scene.isObjectAlive and (callback ~= nil) then + callback(sender, returnedMessageId, message); + end; + end); + end; + end, + + sendDelayedUpdates = function(scene) + return _obj_invoke(scene.handle, "SendDelayedUpdates"); + end + + }; + +local function initWrappedSceneFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__sceneProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__sceneMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __sceneEvents; + return wObj; +end; + +--- [[ Wrapper Object VIEWPORT ]] + +local __viewportProps = {width = {tipo = "double", readProp = "Width"}, + height = {tipo = "double", readProp = "Height"}, + worldX = {tipo = "double", readProp = "WorldX", writeProp = "WorldX"}, + worldY = {tipo = "double", readProp = "WorldY", writeProp = "WorldY"}, + scale = {tipo = "double", readProp = "Scale", writeProp = "Scale"}, + cursor = {tipo = "enum", readProp = "Cursor", writeProp = "Cursor"}, + scene = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "SceneObjectID")); end;}}; + +local __viewportMethods = {screenToWorld = + function(vp, screenX, screenY) + return _obj_invokeEx(vp.handle, "ScreenToWorld", screenX, screenY); + end, + + worldToScreen = + function (vp, worldX, worldY) + return _scene3_ViewPort_WorldToScreen(vp.handle, worldX, worldY); + end, + + getScrollBounds = function(vp) return _obj_invokeEx(vp.handle, "GetScrollBounds"); end; + + setupToolCategory = + function(vp, name, title, order) + _obj_invoke(vp.handle, "SetupToolCategory", tostring(name), tostring(title), tonumber(order)); + end, + + addToolButton = + function (vp, categoryName, title, iconURL, order, options, callback, deactivationCallback) + if type(options) ~= "table" then + options = {}; + end; + + local hBtn = _obj_newObject("SC3ToolButton"); + local o = Objs.objectFromHandle(hBtn); + Objs.registerHandle(hBtn, o); + + if callback ~= nil then + o:listen("OnCallback", callback); + end; + + if deactivationCallback ~= nil then + o:listen("OnDeactivationCallback", deactivationCallback); + end; + + _obj_invoke(hBtn, "SetViewport", vp.objectID); + _obj_invokeEx(hBtn, "SetupButton", categoryName, title, iconURL, order, options); + + local tblTools = rawget(vp, "_TblTools"); + + if tblTools == nil then + tblTools = {}; + rawset(vp, "_TblTools", tblTools); + end; + + local genID = (tblTools.generator or 0) + 1; + tblTools.generator = genID; + + tblTools[genID] = o; + return genID; + end, + + removeToolButton = + function (vp, toolID) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + _obj_invoke(o.handle, "RemoveButton"); + tblTools[toolID] = nil; + end; + end; + end, + + checkToolButton = function(vp, toolID, checked) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + if checked == nil then + checked = true; + end; + + _obj_invoke(o.handle, "CheckToolButton", not not checked); + end; + end; + end, + + isToolButtonChecked = function(vp, toolID) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + return _obj_getProp(o.handle, "IsChecked"); + end; + end; + + return false; + end, + + selectToolButton = function(vp, toolID) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + _obj_invoke(o.handle, "Select"); + end; + end; + end, + + selectDefaultToolButton = function(vp) + _obj_invoke(vp.handle, "SelectDefaultToolButton"); + end, + + needRepaint = function (vp) + _obj_invoke(vp.handle, "NeedRepaint"); + end, + + showForm = function(vp, form, options) + if (form == nil) then + error("invalid parameter - form is nil"); + return false; + end; + + if type(options) ~= "table" then + options = {}; + end; + + local _popupFormShowers = vp._popupFormShowers; + + if _popupFormShowers == nil then + _popupFormShowers = {}; + setmetatable(_popupFormShowers, {__mode="k"}); -- popupFormShowers possui chaves weak-reference + vp._popupFormShowers = _popupFormShowers; + end; + + local popupShower = _popupFormShowers[form]; + + if popupShower == nil then + popupShower = Objs.objectFromHandle(_obj_newObject('TSC3ViewportFormShower')); + Objs.registerHandle(popupShower.handle, popupShower); + _popupFormShowers[form] = popupShower; + + _obj_invoke(popupShower.handle, "SetFormHandle", form.handle); + end; + + local closeListenerId = rawget(popupShower, "__closeListenerID"); + + if closeListenerId ~= nil then + popupShower:removeEventListener(closeListenerId); + rawset(popupShower, "__closeListenerID", nil); + end; + + if type(options.onClose) == "function" then + closeListenerId = popupShower:addEventListener("OnPopupClose", options.onClose); + rawset(popupShower, "__closeListenerID", closeListenerId); + end; + + _obj_setProp(popupShower.handle, "PopupPlacement", options.placement); + return _obj_invoke(popupShower.handle, "Show", vp.handle); + end, + + closeForm = function(vp, form) + local _popupFormShowers = vp._popupFormShowers; + + if type(form) == "table" and _popupFormShowers ~= nil then + local v = _popupFormShowers[form]; + + if v ~= nil then + _popupFormShowers[form] = nil; + return _obj_invoke(v.handle, "Close"); + end; + else + return false; + end; + end + }; + +local __viewportEvents = {onChange = "", + onMouseDown = "event", + onMouseUp = "event", + onMouseMove = "event", + onMouseWheel = "event", + onMouseDblClick = "event", + onFallbackMouseWheel = "event", + onGestureBeginZoom = "x, y", + onGestureZoom = "x, y, delta", + onGestureEndZoom = "x, y", + onGestureBeginRotation = "x, y", + onGestureRotation = "x, y, angle", + onGestureEndRotation = "x, y", + onGestureBeginPan = "x, y", + onGesturePan = "x, y", + onGestureEndPan = "x, y", + onGestureLongTap = "x, y"; + onKeyDown = "event", + onKeyUp = "event", + onBeforeDrawBkgLayer="", + onBeforeDrawGridLayer="", + onBeforeDrawObjsLayer="", + onBeforeDrawTokensLayer="", + onAfterDrawLayers="", + onStartDrop="drop, x, y, drag"}; + +local __viewportRenderMethods = { + prepareFill = _scene3_gfx_prepareFill, + fillRect = _scene3_gfx_fillRect, + fillEllipse = _scene3_gfx_fillEllipse, + fillPolygon = _scene3_gfx_fillPolygon, + fillACell = function(vp, i, j, opacity) _scene3_gfx_fillACell(vp.handle, i, j, opacity); end, + prepareDraw = _scene3_gfx_prepareDraw, + drawRect = _scene3_gfx_drawRect, + drawEllipse = _scene3_gfx_drawEllipse, + drawLine = _scene3_gfx_drawLine, + prepareFont = _scene3_gfx_prepareFont, + textSize = _scene3_gfx_textSize, + fillText = _scene3_gfx_fillText, + fillTextFit = _scene3_gfx_fillTextFit, + pushRenderState = _scene3_gfx_pushState, + popRenderState = _scene3_gfx_popState, + pushRotationTransform = _scene3_gfx_pushRotationTransform, + pushWorldToScreenTransform = function(vp) _scene3_gfx_pushWorldToScreenTransform(vp.handle) end, + popTransform = _scene3_gfx_popTransform + }; + +local function initWrappedViewportFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__viewportProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__viewportMethods) do + rawset(wObj, k, v); + end; + + for k, v in pairs(__viewportRenderMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __viewportEvents; + + return wObj; +end; + + +--- [[ Wrapper Object GRIDLayer ]] + +local __gridLayerProps = {gridType = {tipo = "enum", readProp = "GridType", writeProp="GridType", values={"square", "vertHex", "horzHex"}}, + offsetX = {tipo = "double", readProp = "OffsetX", writeProp = "OffsetX"}, + offsetY = {tipo = "double", readProp = "OffsetY", writeProp = "OffsetY"}, + cellSize = {tipo = "double", readProp = "CellSize", writeProp = "CellSize"}, + gridColor = {tipo = "color", readProp = "GridColor", writeProp = "GridColor"}, + grickThickness = {tipo = "double", readProp = "GridThickness", writeProp = "GridThickness"}, + drawGrid = {tipo = "bool", readProp = "DrawGrid", writeProp = "DrawGrid"}, + rowCount = {tipo = "int", readProp = "RowCount"}, + colCount = {tipo = "int", readProp = "ColumnCount"}, + squareDiagonals = {tipo="enum", readProp = "SquareDiagonals", writeProp="SquareDiagonals", values={"simplified", "manhattan", "alternated", "euclidean"}}, + scene = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "SceneObjectID")); end;}}; + +local __gridLayerMethods = {cellToWorld = + function(grid, i, j) + return _obj_invokeEx(grid.handle, "GetCellCenter", i, j); + end, + + worldToCell = + function (grid, worldX, worldY) + return _obj_invokeEx(grid.handle, "GetGridCellAtPos", worldX, worldY); + end, + + shortestPath = function (grid, srcI, srcJ, destI, destJ, options) + if (options ~= nil) and type(options) ~= "table" then + options = nil; + end; + + return _obj_invokeEx(grid.handle, "ShortestPath", srcI, srcJ, destI, destJ, options); + end}; + +local __gridLayerEvents = {onChange = ""}; + +local function initWrappedGridLayerFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__gridLayerProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__gridLayerMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __gridLayerEvents; + + return wObj; +end; + +--- [[ Wrapper Object GraphicItemList ]] + +local __GIL_Selection = "_xx_selection"; + +local __GILProps = {count = {tipo = "int", readProp = "Count"}, + selection = {tipo="table", getter="getSelection"}}; + +local __GILMethods = { get = function(t, idx) + local objID = _obj_invoke(t.handle, "GetItemObjectID", idx - 1); + local o = SceneWrappers.objectFromID(objID); + + if o == nil then + error("Invalid Scene GraphicItem Index"); + else + return o; + end; + end, + + enumInRect = function(t, rect, layer) + local retObjs = _obj_invokeEx(t.handle, "EnumInRect", rect, layer); + + for i = 1, #retObjs, 1 do + retObjs[i] = SceneWrappers.objectFromID(retObjs[i]); + end; + + return retObjs; + end, + + enumAtPoint = function(t, worldX, worldY, layer) + local retObjs = _obj_invokeEx(t.handle, "EnumInPoint", worldX, worldY, layer); + + for i = 1, #retObjs, 1 do + retObjs[i] = SceneWrappers.objectFromID(retObjs[i]); + end; + + return retObjs; + end, + + itemAtPoint = function(t, worldX, worldY, layer) + local retObjs = t:enumAtPoint(worldX, worldY, layer); + + if #retObjs > 0 then + return retObjs[#retObjs]; + else + return nil; + end; + end, + + getSelection = function(t) + local ss; + + ss = rawget(t, __GIL_Selection); + + if ss ~= nil then + return ss; + end; + + ss = _obj_invokeEx(t.handle, "EnumSelection"); + + for i = 1, #ss, 1 do + ss[i] = SceneWrappers.objectFromID(ss[i]); + end; + + rawset(t, __GIL_Selection, ss); + return ss; + end, + + clearSelection = function(t) + local ss = t.selection; + + for k, v in pairs(ss) do + v.selected = false; + end; + end, + + addToken = function(t, layer) + return SceneWrappers.objectFromID(_obj_invokeEx(t.handle, "AddToken", layer)); + end; + + addUserDrawing = function(t, layer) + return SceneWrappers.objectFromID(_obj_invokeEx(t.handle, "AddUserDrawing", layer)); + end; + }; + +local __GILEvents = {onChange = "", + onItemAdded="item", + onItemRemoved="item", + onItemSelected="item", + onItemDeselected="item", + onItemLayerChange="item"}; +local __GILMetatable = nil; + +local function initialize_GILMetatable(mtbase) + __GILMetatable = {}; + local oldIndexMT = mtbase.__index; + local oldNewIndexMT = mtbase.__newindex; + + for k, v in pairs(mtbase) do + __GILMetatable[k] = v; + end + + __GILMetatable.__len = function(t) + return _obj_getProp(t.handle, "Count"); + end; + + __GILMetatable.__index = function(t, k) + if type(k) == "number" then + local objID = _obj_invoke(t.handle, "GetItemObjectID", k - 1); + local o = SceneWrappers.objectFromID(objID); + + if o == nil then + error("Invalid Scene GraphicItem Index"); + else + return o; + end; + elseif oldIndexMT ~= nil then + return oldIndexMT(t, k); + else + return rawget(t, k); + end; + end; + + __GILMetatable.__newindex = function(t, k, v) + if type(k) == "number" then + error("Scene Graphic Item Index: Read-Only property"); + elseif oldNewIndexMT ~= nil then + return oldNewIndexMT(t, k, v); + else + rawset(t, k, v); + end; + end; +end; + +local function initWrappedGraphicItemListFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + if __GILMetatable == nil then + initialize_GILMetatable(getmetatable(wObj)); + end; + + setmetatable(wObj, __GILMetatable); + + for k, v in pairs(__GILProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__GILMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __GILEvents; + + -- Resetar o cache do selection + wObj:listen("OnItemSelected", function() rawset(wObj, __GIL_Selection, nil); end); + wObj:listen("OnItemDeselected", function() rawset(wObj, __GIL_Selection, nil); end); + return wObj; +end; + +--- [[ Wrapper Object GraphicItem ]] + +local __graphicItemProps = {width = {tipo = "double", readProp = "Width", writeProp="Width"}, + height = {tipo = "double", readProp = "Height", writeProp = "Height"}, + x = {tipo = "double", readProp = "X", writeProp = "X"}, + y = {tipo = "double", readProp = "Y", writeProp = "Y"}, + z = {tipo = "double", readProp = "Z", writeProp = "Z"}, + rotation = {tipo = "double", readProp = "Rotation", writeProp = "Rotation"}, + visible = {tipo = "bool", readProp = "Visible", writeProp = "Visible"}, + snapToGrid = {tipo = "bool", readProp = "SnapToGrid", writeProp="SnapToGrid"}, + locked = {tipo = "bool", readProp = "Locked", writeProp = "Locked"}, + selected = {tipo = "bool", readProp = "Selected", writeProp = "Selected"}, + isHover = {tipo = "bool", readProp = "IsHover", writeProp = "IsHover"}, + layer = {tipo = "enum", readProp = "Layer", writeProp = "Layer", values={"background", "objects", "token"}}, + isMine = {tipo = "bool", readProp = "IsMine"}, + canBeRendered = {tipo = "bool", readProp = "CanBeRendered"}, + ownerUserID = {tipo = "string", readProp = "OwnerUserID", writeProp="OwnerUserID"}, + canvas = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "CanvasObjectID")); end;}, + scene = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "SceneObjectID")); end;}}; + +local __graphicItemMethods = {getCenter = + function(t, snapToGrid) + return _obj_invokeEx(t.handle, "GetCenter", snapToGrid); + end, + + setCenter = + function (t, worldX, worldY, snapToGrid) + return _obj_invokeEx(t.handle, "SetCenter", worldX, worldY, snapToGrid); + end, + + getBounds = + function(t) + return _scene3_GraItem_getBounds(t.objectID); + end, + + setBounds = function(t, left, top, right, bottom, rotation) + return _scene3_GraItem_setBounds(t.objectID, left, top, right, bottom, rotation); + end, + + getCellsOccupied = function (t) + return _obj_invokeEx(t.handle, "GetCellsOccupied"); + end, + + compareZOrder = function(t, otherItem) + return _obj_invokeEx(t.handle, "CompareZOrder", otherItem.handle); + end, + + delete = function(t) _obj_invoke(t.handle, "Delete"); end, + + doSnapToGrid = function(t) _obj_invoke(t.handle, "DoSnapToGrid"); end; + }; + +local __graphicItemEvents = {onChange = "", + onBeforeDraw = "", + onAfterDraw = "", + onBoundsChange = "item"}; + +local function initWrappedGraphicItemFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__graphicItemProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__graphicItemMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __graphicItemEvents; + + return wObj; +end; + + +--- [[ Wrapper Object Token ]] + +local __tokenItemProps = {facingMode = {tipo = "enum", readProp = "FacingMode", writeProp="FacingMode", values={"rotate", "arrow"}}, + ownerCharacter = {tipo = "int", readProp = "OwnerCharacter", writeProp="OwnerCharacter"}, + friendOrFoe = {tipo = "enum", readProp = "FriendOrFoe", writeProp="FriendOrFoe", values={"unknown", "friend", "neutral", "foe"}}, + name = {tipo="string", readProp="Name", writeProp="Name"}, + visionIntenseLightRange = {tipo = "double", readProp = "VisIntenseLightRange", writeProp="VisIntenseLightRange"}, + visionWeakLightRange = {tipo = "double", readProp = "VisWeakLightRange", writeProp="VisWeakLightRange"}, + visionDarknessRange = {tipo = "double", readProp = "VisDarkRange", writeProp="VisDarkRange"}, + visionAngle = {tipo = "double", readProp = "VisionAngle", writeProp="VisionAngle"}, + visionHaveVision = {tipo = "bool", readProp = "VisHaveVision", writeProp="VisHaveVision"}, + lightIntenseRange = {tipo = "double", readProp = "LightIntenseRange", writeProp="LightIntenseRange"}, + lightWeakRange = {tipo = "double", readProp = "LightWeakRange", writeProp="LightWeakRange"}, + lightAngle = {tipo = "double", readProp = "LightAngle", writeProp="LightAngle"}, + image = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "ImageOpObjectID")); end;} + }; + +for i = 1, 3, 1 do + __tokenItemProps["barValue" .. i] = {tipo="string", + getter = function(obj) return _obj_invoke(obj.handle, "GetBarValue", i - 1); end, + setter = function(obj, value) _obj_invoke(obj.handle, "SetBarValue", i - 1, value); end}; + + __tokenItemProps["barMax" .. i] = {tipo="string", + getter = function(obj) return _obj_invoke(obj.handle, "GetBarMax", i - 1); end, + setter = function(obj, value) _obj_invoke(obj.handle, "SetBarMax", i - 1, value); end}; + + __tokenItemProps["barColor" .. i] = {tipo="color", + getter = function(obj) return _obj_invoke(obj.handle, "GetBarColor", i - 1); end, + setter = function(obj, value) _obj_invoke(obj.handle, "SetBarColor", i - 1, value); end}; +end; + +local __tokenMethods = {clearMemoryAreas = function(t) _obj_invoke(t.handle, "ClearMemoryAreas"); end + }; +local __tokenEvents = {}; + +for k, v in pairs(__graphicItemEvents) do + __tokenEvents[k] = v; +end; + + __tokenEvents.onChange = ""; + +local function initWrappedTokenFromHandle(handle) + local wObj = initWrappedGraphicItemFromHandle(handle); + + for k, v in pairs(__tokenItemProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__tokenMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __tokenEvents; + + return wObj; +end; + +--- [[ Wrapper UserDrawing ]] + +local __userDrawingItemProps = {}; + +local __userDrawingMethods = { + markAsMyDrawing = + function(t) + local scene = t.scene; + + if scene ~= nil then + if scene.isGM then + t.ownerUserID = ''; + else + t.ownerUserID = scene.currentUserID; + end; + end; + end + }; +local __userDrawingEvents = {}; + +for k, v in pairs(__graphicItemEvents) do + __userDrawingEvents[k] = v; +end; + +local function initWrappedUerDrawingFromHandle(handle) + local wObj = initWrappedGraphicItemFromHandle(handle); + + for k, v in pairs(__userDrawingItemProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__userDrawingMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __userDrawingEvents; + return wObj; +end; + +--- [[ Wrapper Object Persisted Canvas ]] + +local __PerCanvasProps = {opCount = {tipo = "int", readProp = "OpCount"}}; + + +local __PerCanvasMethods = {getOp = function(t, idx) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "GetOpObjectID", idx)); + end, + + addBitmap = function(t) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "AddBitmapOpObjectID")); + end, + + addPath = function(t) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "AddPathOpObjectID")); + end, + + addText = function(t) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "AddTextOpObjectID")); + end, + + findByName = function(t, name) + return SceneWrappers.objectFromID(_obj_invokeEx(t.handle, "FindByName", tostring(name))); + end, + + clear = function(t) _obj_invoke(t.handle, "Clear"); end; + }; + +local __PerCanvasEvents = {onChange = ""}; + +local function initWrappedPerCanvasFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__PerCanvasProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__PerCanvasMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __PerCanvasEvents; + + return wObj; +end; + + +--- [[ Wrapper Object DrawingOp ]] + +local __DOPBaseProps = {x = {tipo = "double", readProp = "X", writeProp="X"}, + y = {tipo = "double", readProp = "Y", writeProp="Y"}, + z = {tipo = "double", readProp = "Z", writeProp="Z"}, + width = {tipo = "double", readProp = "Width", writeProp="Width"}, + height = {tipo = "double", readProp = "Height", writeProp="Height"}, + rotMode = {tipo = "enum", readProp="RotMode", writeProp = "RotMode", values={"default", "ignoreCanvasRot"}}, + name = {tipo = "string", readProp = "Name", writeProp="Name"}, + opacity = {tipo = "double", readProp = "Opacity", writeProp="Opacity"}, + visibility = {tipo = "enum", readProp = "Visibility", writeProp="Visibility", values={"everyone", "gmOnly"}}, + rotation = {tipo="double", readProp="Rotation", writeProp="Rotation"}, + rotCenterX = {tipo="double", readProp="RotCenterX", writeProp="RotCenterX"}, + rotCenterY = {tipo="double", readProp="RotCenterY", writeProp="RotCenterY"}, + drawingTrigger = {tipo="set", readProp="DrawingTrigger", writeProp="DrawingTrigger", values={"hover", "selected"}}, + outOfOrderMode = {tipo="enum", readProp="OutOfOrderMode", writeProp="OutOfOrderMode", values={"noOutOfOrder", "afterFogOfWarLayer", "beforeOwnerLayer", "afterOwnerLayer"}}, + xMetric = {tipo="enum", readProp="XMetric", writeProp="XMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + yMetric = {tipo="enum", readProp="YMetric", writeProp="YMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + widthMetric = {tipo="enum", readProp="WidthMetric", writeProp="WidthMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + heightMetric = {tipo="enum", readProp="HeightMetric", writeProp="HeightMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + xOrigin = {tipo = "double", readProp = "XOrigin", writeProp="XOrigin"}, + yOrigin = {tipo = "double", readProp = "YOrigin", writeProp="YOrigin"} + }; + +local __DOPBaseMethods = {delete = function(t) + _obj_invoke(t.handle, "Delete"); + end + }; + +local __DOPBaseEvents = {onChange = ""}; + +local function initWrappedDrawingOpBaseFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__DOPBaseProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPBaseMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPBaseEvents; + + return wObj; +end; + + +--- [[ Wrapper Object DrawingOpBitmap ]] + +local __DOPBitmapProps = {url = {tipo = "string", readProp = "URL", writeProp="URL"}, + flipHorz = {tipo = "bool", readProp="FlipHorz", writeProp = "FlipHorz"}, + flipVert = {tipo = "bool", readProp="FlipVert", writeProp = "FlipVert"}, + grayscale = {tipo = "bool", readProp="Grayscale", writeProp = "Grayscale"}, + colorBlend = {tipo = "color", readProp="ColorBlend", writeProp = "ColorBlend"}, + colorMask = {tipo = "color", readProp="ColorMask", writeProp = "ColorMask"}, + filterEx = {tipo = "enum", readProp="FilterEx", writeProp = "FilterEx", + values={"none", "glow", "innerGlow", "blur", "sepia"}}, + filterExColor = {tipo = "color", readProp="FilterExColor", writeProp = "FilterExColor"}, + frame = {tipo = "enum", readProp="Frame", writeProp = "Frame", + values={"none", "boton"}}, + sourceRect = {tipo="table", readProp="SourceRect", writeProp="SourceRect"}}; + +local __DOPBitmapMethods = {}; +local __DOPBitmapEvents = {onChange = ""}; + +local function initWrappedDrawingOpBitmapFromHandle(handle) + local wObj = initWrappedDrawingOpBaseFromHandle(handle); + + for k, v in pairs(__DOPBitmapProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPBitmapMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPBitmapEvents; + + return wObj; +end; + +--- [[ Wrapper Object DrawingOpPath ]] + +local __DOPPathProps = {pathData = {tipo = "string", readProp = "PathData", writeProp="PathData"}, + data = {tipo = "string", readProp = "PathData", writeProp="PathData"}, + path = {tipo = "string", readProp = "PathData", writeProp="PathData"}, + color = {tipo="color", readProp="FillColor", writeProp="FillColor"}, + strokeColor = {tipo="color", readProp="StrokeColor", writeProp="StrokeColor"}, + strokeSize = {tipo="double", readProp="StrokeThickness", writeProp="StrokeThickness"}, + strokeSizeMetric = {tipo="enum", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}, readProp="StrokeThicknessMetric", writeProp="StrokeThicknessMetric"}, + strokeCap = {tipo="enum", readProp="StrokeCap", writeProp="StrokeCap", values={"flat", "round"}}, + strokeJoin = {tipo="enum", readProp="StrokeJoin", writeProp="StrokeJoin", values={"miter", "round", "bevel"}}, + strokeDash = {tipo="enum", readProp="StrokeDash", writeProp="StrokeDash", values={"solid", "dash", "dot", "dashDot", "dashDotDot"}} + } + +local __DOPPathMethods = {}; +local __DOPPathEvents = {onChange = ""}; + +local function initWrappedDrawingOpPathFromHandle(handle) + local wObj = initWrappedDrawingOpBaseFromHandle(handle); + + for k, v in pairs(__DOPPathProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPPathMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPPathEvents; + + return wObj; +end; + + + +--- [[ Wrapper Object DrawingOpText ]] + +local __DOPTextProps = {text = {tipo = "string", readProp = "Text", writeProp="Text"}, + color = {tipo = "color", readProp = "Color", writeProp="Color"}, + aspect = {tipo = "double", readProp = "Aspect"}, + fontStyle = {tipo="set", readProp="FontStyle", writeProp="FontStyle"}, + horzTextAlign = {tipo="enum", readProp="TextAlign", writeProp="TextAlign", values={"leading", "center", "trailing"}}, + vertTextAlign = {tipo="enum", readProp="VertTextAlign", writeProp="VertTextAlign", values={"leading", "center", "trailing"}} + } + +local __DOPTextMethods = {}; +local __DOPTextEvents = {}; + +local function initWrappedDrawingOpTextFromHandle(handle) + local wObj = initWrappedDrawingOpBaseFromHandle(handle); + + for k, v in pairs(__DOPTextProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPTextMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPTextEvents; + + return wObj; +end; + +--- [[ Wrapper Object FogOfWar FOW ]] + +local __fowProps = {enabled = {tipo="bool", readProp="Enabled", writeProp="Enabled"}, + ambientLight = {tipo="enum", readProp="AmbientLight", writeProp="AmbientLight", values={"intense", "weak", "none"}}, + sharingMode = {tipo="enum", readProp="SharingMode", writeProp="SharingMode", values={"individual", "group"}}}; + + +local __fowMethods = {setArea = function(t, polygon, areaType) + _obj_invokeEx(t.handle, "SetArea", polygon, areaType); + end, + + resetAreas = function(t) _obj_invoke(t.handle, "ResetAreas"); end, + + addOpaqueArea = function(t, polygon) + _obj_invokeEx(t.handle, "AddOpaqueArea", polygon); + end, + + removeOpaqueArea = function(t, polygon) + _obj_invokeEx(t.handle, "RemoveOpaqueArea", polygon); + end, + + resetOpaqueAreas = function(t) _obj_invoke(t.handle, "ResetOpaqueAreas"); end, + + testCircleMovementCollisionVsOpaqueAreas = function(t, centerX, centerY, r, offsetX, offsetY) + return _obj_invokeEx(t.handle, "TestCircleMovementCollisionVsOpaqueAreas", centerX, centerY, r, offsetX, offsetY); + end + + }; + +local __fowEvents = {onChange = ""}; + +local function initWrappedFogOfWarFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__fowProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__fowMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __fowEvents; + + return wObj; +end; + +------------------------------------------ + + +local __wrappersInitializers = { + token = initWrappedTokenFromHandle, + userDrawing = initWrappedUerDrawingFromHandle, + graphicItem = initWrappedGraphicItemFromHandle, + scene = initWrappedSceneFromHandle, + pluginAttachment = initWrappedObjectFromHandle, + viewport = initWrappedViewportFromHandle, + persistedCanvas = initWrappedPerCanvasFromHandle, + gridLayer = initWrappedGridLayerFromHandle, + graphicItemList = initWrappedGraphicItemListFromHandle, + drawingOpBase = initWrappedDrawingOpBaseFromHandle, + opBitmap = initWrappedDrawingOpBitmapFromHandle, + opPath = initWrappedDrawingOpPathFromHandle, + opText = initWrappedDrawingOpTextFromHandle, + fogOfWar = initWrappedFogOfWarFromHandle, + } + +function SceneWrappers.objectFromID(objectID) + if (objectID == nil) or (objectID == 0) then + return nil; + end; + + local scObj = _localStrongRefSceneObjects[objectID]; + + if scObj ~= nil then + return scObj; + end; + + local objWrapperHandle; + objWrapperHandle = _scene3_GetOrCreateObjectWrapperForObjectID(objectID); + + if objWrapperHandle == nil then + return nil; + end; + + scObj = objs.tryFindFromHandle(objWrapperHandle); + + if scObj ~= nil then + if _scene3_IsObjectIDAlive(objectID) then + _localStrongRefSceneObjects[objectID] = scObj; + end; + + return scObj; + end; + + local oType = _scene3_GetWrapperType(objWrapperHandle); + local initer = __wrappersInitializers[oType]; + + if initer == nil then + -- Olhar por um wrapper na herança. + + for k, v in pairs(__wrappersInitializers) do + if _scene3_IsWrapperOfType(objWrapperHandle, k) then + initer = v; + break; + end; + end; + + if initer == nil then + initer = initWrappedObjectFromHandle; + end; + end; + + scObj = initer(objWrapperHandle); + objs.registerHandle(objWrapperHandle, scObj); + + if _scene3_IsObjectIDAlive(objectID) then + _localStrongRefSceneObjects[objectID] = scObj; + end; + + return scObj; +end; + +function _INTERNAL_EVE_OnWrappedSceneObjectWasDestroyed(objectID) + _localStrongRefSceneObjects[objectID] = nil; -- Permitir o Garbage Collector coletar este objeto +end; + +return SceneWrappers; \ No newline at end of file diff --git a/sdk/sdk3.lang b/sdk/sdk3.lang new file mode 100644 index 00000000..e3fdc8c5 --- /dev/null +++ b/sdk/sdk3.lang @@ -0,0 +1,11 @@ +[pt] +sdk3.err.ndb.functionAssign=Tentativa de armazenar uma função Lua na propriedade "%s", porém não é possível salvar funções em NodeDatabases +sdk3.err.ndb.func.exportToXML.invalidPar=Não foi passado um objeto Nodo válido no parâmetro da função NDB.exportXML +sdk3.err.ndb.func.importXML.invalidPar=Não foi passado um objeto Nodo válido no primeiro parâmetro da função NDB.importXML +sdk3.err.ndb.func.copy.invalidPar2=Não foi passado um objeto Nodo válido no segundo parâmetro da função NDB.copy + +[en] +sdk3.err.ndb.functionAssign=Attempting to store a Lua function in the property "%s", but it is not possible to store functions in NodeDatabases +sdk3.err.ndb.func.exportToXML.invalidPar=A valid Node object was not passed in the NDB.exportXML's first parameter +sdk3.err.ndb.func.importXML.invalidPar=A valid Node object was not passed in the NDB.importXML's first parameter +sdk3.err.ndb.func.copy.invalidPar2=A valid Node object was not passed in the NDB.copy's second parameter \ No newline at end of file diff --git a/sdk/serpent.dlua b/sdk/serpent.dlua new file mode 100644 index 00000000..62f268a6 --- /dev/null +++ b/sdk/serpent.dlua @@ -0,0 +1,172 @@ +local function firecastQuotedStr(s) + local buildingStr = ""; + + for p, c in utf8.codes(s) do + if c == 22 then + buildingStr = buildingStr .. '\"' + elseif c == 10 then + buildingStr = buildingStr .. "\n" + elseif c == 13 then + buildingStr = buildingStr .. "\013" + else + buildingStr = buildingStr .. utf8.char(c); + end; + end; + + return '"' .. buildingStr .. '"'; +end; + +local n, v = "serpent", "0.303" -- (C) 2012-18 Paul Kulchenko; MIT License +local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" +local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'} +local badtype = {thread = true, userdata = true, cdata = true} +local getmetatable = debug and debug.getmetatable or getmetatable + +-- local pairs = function(t) return next, t end -- avoid using __pairs in Lua 5.2+ -- it should use pairs because of nodeDatabase + +local keyword, globals, G = {}, {}, (_G or _ENV) +for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false', + 'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', + 'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end +for k,v in pairs(G) do globals[v] = k end -- build func to name mapping +for _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do + for k,v in pairs(type(G[g]) == 'table' and G[g] or {}) do globals[v] = g..'.'..k end end + +local function s(t, opts) + local name, indent, fatal, maxnum = opts.name, opts.indent, opts.fatal, opts.maxnum + local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge + local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge) + local maxlen, metatostring = tonumber(opts.maxlength), opts.metatostring + local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge) + local numformat = opts.numformat or "%.17g" + local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0 + local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)", + -- tostring(val) is needed because __tostring may return a non-string value + function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return tostring(syms[s]) end)) end + local function safestr(s) return type(s) == "number" and (huge and snum[tostring(s)] or numformat:format(s)) + or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026 + or firecastQuotedStr(s):gsub("\010","n"):gsub("\026","\\026") end + -- handle radix changes in some locales + if opts.fixradix and (".1f"):format(1.2) ~= "1.2" then + local origsafestr = safestr + safestr = function(s) return type(s) == "number" + and (nohuge and snum[tostring(s)] or numformat:format(s):gsub(",",".")) or origsafestr(s) + end + end + local function comment(s,l) return comm and (l or 0) < comm and ' --[['..select(2, pcall(tostring, s))..']]' or '' end + local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal + and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end + local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r'] + local n = name == nil and '' or name + local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n] + local safe = plain and n or '['..safestr(n)..']' + return (path or '')..(plain and path and '.' or '')..safe, safe end + local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding + local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'} + local function padnum(d) return ("%0"..tostring(maxn).."d"):format(tonumber(d)) end + table.sort(k, function(a,b) + -- sort numeric keys first: k[key] is not nil for numerical keys + return (k[a] ~= nil and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum)) + < (k[b] ~= nil and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end + local function val2str(t, name, indent, insref, path, plainindex, level) + local ttype, level, mt = type(t), (level or 0), getmetatable(t) + local spath, sname = safename(path, name) + local tag = plainindex and + ((type(name) == "number") and '' or name..space..'='..space) or + (name ~= nil and sname..space..'='..space or '') + if seen[t] then -- already seen this element + sref[#sref+1] = spath..space..'='..space..seen[t] + return tag..'nil'..comment('ref', level) + end + -- protect from those cases where __tostring may fail + if type(mt) == 'table' and metatostring ~= false then + local to, tr = pcall(function() return mt.__tostring(t) end) + local so, sr = pcall(function() return mt.__serialize(t) end) + if (to or so) then -- knows how to serialize itself + seen[t] = insref or spath + t = so and sr or tr + ttype = type(t) + end -- new value falls through to be serialized + end + if ttype == "table" then + if level >= maxl then return tag..'{}'..comment('maxlvl', level) end + seen[t] = insref or spath + if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty + if maxlen and maxlen < 0 then return tag..'{}'..comment('maxlen', level) end + local maxn, o, out = math.min(#t, maxnum or #t), {}, {} + for key = 1, maxn do o[key] = key end + if not maxnum or #o < maxnum then + local n = #o -- n = n + 1; o[n] is much faster than o[#o+1] on large tables + for key in pairs(t) do + if o[key] ~= key then n = n + 1; o[n] = key end + end + end + if maxnum and #o > maxnum then o[maxnum+1] = nil end + if opts.sortkeys and #o > maxn then alphanumsort(o, t, opts.sortkeys) end + local sparse = sparse and #o > maxn -- disable sparsness if only numeric keys (shorter output) + for n, key in ipairs(o) do + local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse + if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing + or opts.keyallow and not opts.keyallow[key] + or opts.keyignore and opts.keyignore[key] + or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types + or sparse and value == nil then -- skipping nils; do nothing + elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then + if not seen[key] and not globals[key] then + sref[#sref+1] = 'placeholder' + local sname = safename(iname, gensym(key)) -- iname is table for local variables + sref[#sref] = val2str(key,sname,indent,sname,iname,true) + end + sref[#sref+1] = 'placeholder' + local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']' + sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path)) + else + out[#out+1] = val2str(value,key,indent,nil,seen[t],plainindex,level+1) + if maxlen then + maxlen = maxlen - #out[#out] + if maxlen < 0 then break end + end + end + end + local prefix = string.rep(indent or '', level) + local head = indent and '{\n'..prefix..indent or '{' + local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space)) + local tail = indent and "\n"..prefix..'}' or '}' + return (custom and custom(tag,head,body,tail,level) or tag..head..body..tail)..comment(t, level) + elseif badtype[ttype] then + seen[t] = insref or spath + return tag..globerr(t, level) + elseif ttype == 'function' then + seen[t] = insref or spath + if opts.nocode then return tag.."function() --[[..skipped..]] end"..comment(t, level) end + local ok, res = pcall(string.dump, t) + local func = ok and "((loadstring or load)("..safestr(res)..",'@serialized'))"..comment(t, level) + return tag..(func or globerr(t, level)) + else return tag..safestr(t) end -- handle all other types + end + local sepr = indent and "\n" or ";"..space + local body = val2str(t, name, indent) -- this call also populates sref + local tail = #sref>1 and table.concat(sref, sepr)..sepr or '' + local warn = opts.comment and #sref>1 and space.."--[[incomplete output with shared/self-references skipped]]" or '' + return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end" +end + +local function deserialize(data, opts) + local env = (opts and opts.safe == false) and G + or setmetatable({}, { + __index = function(t,k) return t end, + __call = function(t,...) error("cannot call functions") end + }) + local f, res = (loadstring or load)('return '..data, nil, nil, env) + if not f then f, res = (loadstring or load)(data, nil, nil, env) end + if not f then return f, res end + if setfenv then setfenv(f, env) end + return pcall(f) +end + +local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end +return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s, + load = deserialize, + dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end, + line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end, + block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end } diff --git a/sdk/slaxdom.dlua b/sdk/slaxdom.dlua new file mode 100644 index 00000000..46b5bc87 --- /dev/null +++ b/sdk/slaxdom.dlua @@ -0,0 +1,49 @@ +-- Optional parser that creates a flat DOM from parsing +local SLAXML = require 'slaxml.dlua' +function SLAXML:dom(xml,opts) + if not opts then opts={} end + local rich = not opts.simple + local push, pop = table.insert, table.remove + local stack = {} + local doc = { type="document", name="#doc", kids={} } + local current = doc + local builder = SLAXML:parser{ + startElement = function(name,nsURI) + local el = { type="element", name=name, kids={}, el=rich and {} or nil, attr={}, nsURI=nsURI, parent=rich and current or nil } + if current==doc then + if doc.root then error(("Encountered element '%s' when the document already has a root '%s' element"):format(name,doc.root.name)) end + doc.root = el + end + push(current.kids,el) + if current.el then push(current.el,el) end + current = el + push(stack,el) + end, + attribute = function(name,value,nsURI) + if not current or current.type~="element" then error(("Encountered an attribute %s=%s but I wasn't inside an element"):format(name,value)) end + local attr = {type='attribute',name=name,nsURI=nsURI,value=value,parent=rich and current or nil} + if rich then current.attr[name] = value end + push(current.attr,attr) + end, + closeElement = function(name) + if current.name~=name or current.type~="element" then error(("Received a close element notification for '%s' but was inside a '%s' %s"):format(name,current.name,current.type)) end + pop(stack) + current = stack[#stack] + end, + text = function(value) + if current.type~='document' then + if current.type~="element" then error(("Received a text notification '%s' but was inside a %s"):format(value,current.type)) end + push(current.kids,{type='text',name='#text',value=value,parent=rich and current or nil}) + end + end, + comment = function(value) + push(current.kids,{type='comment',name='#comment',value=value,parent=rich and current or nil}) + end, + pi = function(name,value) + push(current.kids,{type='pi',name=name,value=value,parent=rich and current or nil}) + end + } + builder:parse(xml,opts) + return doc +end +return SLAXML \ No newline at end of file diff --git a/sdk/slaxml.dlua b/sdk/slaxml.dlua new file mode 100644 index 00000000..5929b785 --- /dev/null +++ b/sdk/slaxml.dlua @@ -0,0 +1,257 @@ +--[=====================================================================[ +v0.7 Copyright © 2013-2014 Gavin Kistner ; MIT Licensed +See http://github.com/Phrogz/SLAXML for details. +--]=====================================================================] +local SLAXML = { + VERSION = "0.7", + _call = { + pi = function(target,content) + --print(string.format("",target,content)) + end, + comment = function(content) + --print(string.format("",content)) + end, + startElement = function(name,nsURI,nsPrefix) + --[[ io.write("<") + if nsPrefix then io.write(nsPrefix,":") end + io.write(name) + if nsURI then io.write(" (ns='",nsURI,"')") end + print(">")]]-- + end, + attribute = function(name,value,nsURI,nsPrefix) + --[[ io.write(' ') + if nsPrefix then io.write(nsPrefix,":") end + io.write(name,'=',string.format('%q',value)) + if nsURI then io.write(" (ns='",nsURI,"')") end + io.write("\n")]]-- + end, + text = function(text) + --print(string.format(" text: %q",text)) + end, + closeElement = function(name,nsURI,nsPrefix) + --print(string.format("",name)) + end, + } +} + +function SLAXML:parser(callbacks) + return { _call=callbacks or self._call, parse=SLAXML.parse } +end + +function SLAXML:parse(xml,options) + if not options then options = { stripWhitespace=false } end + + -- Cache references for maximum speed + local find, sub, gsub, char, push, pop, concat = string.find, string.sub, string.gsub, string.char, table.insert, table.remove, table.concat + local first, last, match1, match2, pos2, nsURI + local unpack = table.unpack + local pos = 1 + local state = "text" + local textStart = 1 + local currentElement={} + local currentAttributes={} + local currentAttributeCt -- manually track length since the table is re-used + local nsStack = {} + local anyElement = false + + local utf8markers = { {0x7FF,192}, {0xFFFF,224}, {0x1FFFFF,240} } + function utf8(decimal) -- convert unicode code point to utf-8 encoded character string + if decimal<128 then return char(decimal) end + local charbytes = {} + for bytes,vals in ipairs(utf8markers) do + if decimal<=vals[1] then + for b=bytes+1,2,-1 do + local mod = decimal%64 + decimal = (decimal-mod)/64 + charbytes[b] = char(128+mod) + end + charbytes[1] = char(vals[2]+decimal) + return concat(charbytes) + end + end + end + local entityMap = { ["lt"]="<", ["gt"]=">", ["amp"]="&", ["quot"]='"', ["apos"]="'" } + local entitySwap = function(orig,n,s) return entityMap[s] or n=="#" and utf8(tonumber('0'..s)) or orig end + local function unescape(str) return gsub( str, '(&(#?)([%d%a]+);)', entitySwap ) end + + local function finishText() + if first>textStart and self._call.text then + local text = sub(xml,textStart,first-1) + if options.stripWhitespace then + text = gsub(text,'^%s+','') + text = gsub(text,'%s+$','') + if #text==0 then text=nil end + end + if text then self._call.text(unescape(text)) end + end + end + + local function findPI() + first, last, match1, match2 = find( xml, '^<%?([:%a_][:%w_.-]*) ?(.-)%?>', pos ) + if first then + finishText() + if self._call.pi then self._call.pi(match1,match2) end + pos = last+1 + textStart = pos + return true + end + end + + local function findComment() + first, last, match1 = find( xml, '^', pos ) + if first then + finishText() + if self._call.comment then self._call.comment(match1) end + pos = last+1 + textStart = pos + return true + end + end + + local function nsForPrefix(prefix) + if prefix=='xml' then return 'http://www.w3.org/XML/1998/namespace' end -- http://www.w3.org/TR/xml-names/#ns-decl + for i=#nsStack,1,-1 do if nsStack[i][prefix] then return nsStack[i][prefix] end end + error(("Cannot find namespace for prefix %s"):format(prefix)) + end + + local function startElement() + anyElement = true + first, last, match1 = find( xml, '^<([%a_][%w_.-]*)', pos ) + if first then + currentElement[2] = nil -- reset the nsURI, since this table is re-used + currentElement[3] = nil -- reset the nsPrefix, since this table is re-used + finishText() + pos = last+1 + first,last,match2 = find(xml, '^:([%a_][%w_.-]*)', pos ) + if first then + currentElement[1] = match2 + currentElement[3] = match1 -- Save the prefix for later resolution + match1 = match2 + pos = last+1 + else + currentElement[1] = match1 + for i=#nsStack,1,-1 do if nsStack[i]['!'] then currentElement[2] = nsStack[i]['!']; break end end + end + currentAttributeCt = 0 + push(nsStack,{}) + return true + end + end + + local function findAttribute() + first, last, match1 = find( xml, '^%s+([:%a_][:%w_.-]*)%s*=%s*', pos ) + if first then + pos2 = last+1 + first, last, match2 = find( xml, '^"([^<"]*)"', pos2 ) -- FIXME: disallow non-entity ampersands + if first then + pos = last+1 + match2 = unescape(match2) + else + first, last, match2 = find( xml, "^'([^<']*)'", pos2 ) -- FIXME: disallow non-entity ampersands + if first then + pos = last+1 + match2 = unescape(match2) + end + end + end + if match1 and match2 then + local currentAttribute = {match1,match2} + local prefix,name = string.match(match1,'^([^:]+):([^:]+)$') + if prefix then + if prefix=='xmlns' then + nsStack[#nsStack][name] = match2 + else + currentAttribute[1] = name + currentAttribute[4] = prefix + end + else + if match1=='xmlns' then + nsStack[#nsStack]['!'] = match2 + currentElement[2] = match2 + end + end + currentAttributeCt = currentAttributeCt + 1 + currentAttributes[currentAttributeCt] = currentAttribute + return true + end + end + + local function findCDATA() + first, last, match1 = find( xml, '^', pos ) + if first then + finishText() + if self._call.text then self._call.text(match1) end + pos = last+1 + textStart = pos + return true + end + end + + local function closeElement() + first, last, match1 = find( xml, '^%s*(/?)>', pos ) + if first then + state = "text" + pos = last+1 + textStart = pos + + -- Resolve namespace prefixes AFTER all new/redefined prefixes have been parsed + if currentElement[3] then currentElement[2] = nsForPrefix(currentElement[3]) end + if self._call.startElement then self._call.startElement(unpack(currentElement)) end + if self._call.attribute then + for i=1,currentAttributeCt do + if currentAttributes[i][4] then currentAttributes[i][3] = nsForPrefix(currentAttributes[i][4]) end + self._call.attribute(unpack(currentAttributes[i])) + end + end + + if match1=="/" then + pop(nsStack) + if self._call.closeElement then self._call.closeElement(unpack(currentElement)) end + end + return true + end + end + + local function findElementClose() + first, last, match1, match2 = find( xml, '^', pos ) + if first then + nsURI = nil + for i=#nsStack,1,-1 do if nsStack[i]['!'] then nsURI = nsStack[i]['!']; break end end + else + first, last, match2, match1 = find( xml, '^', pos ) + if first then nsURI = nsForPrefix(match2) end + end + if first then + finishText() + if self._call.closeElement then self._call.closeElement(match1,nsURI) end + pos = last+1 + textStart = pos + pop(nsStack) + return true + end + end + + while pos<#xml do + if state=="text" then + if not (findPI() or findComment() or findCDATA() or findElementClose()) then + if startElement() then + state = "attributes" + else + first, last = find( xml, '^[^<]+', pos ) + pos = (first and last or pos) + 1 + end + end + elseif state=="attributes" then + if not findAttribute() then + if not closeElement() then + error("Was in an element and couldn't find attributes or the close.") + end + end + end + end + + if not anyElement then error("Parsing did not discover any elements") end + if #nsStack > 0 then error("Parsing ended with unclosed elements") end +end + +return SLAXML \ No newline at end of file diff --git a/sdk/system.lua b/sdk/system.lua new file mode 100644 index 00000000..5e7bcf15 --- /dev/null +++ b/sdk/system.lua @@ -0,0 +1,3 @@ +system = require("delayedLoad.dlua").new("systemCore.dlua"); +System = system; +return system; diff --git a/sdk/systemCore.dlua b/sdk/systemCore.dlua new file mode 100644 index 00000000..622f8288 --- /dev/null +++ b/sdk/systemCore.dlua @@ -0,0 +1,51 @@ +local system = {}; + +function system.setClipboardText(text) + return _system_setClipboardText(text); +end; + +function system.getClipboardText() + return _system_getClipboardText(); +end; + +function system.readClipboardAsDragNDrop(callback, options) + if (type(callback) ~= 'function') then + return false; + end; + + options = options or {}; + options.x = tonumber(options.x) or 0; + options.y = tonumber(options.y) or 0; + + return _gui_readClipboardAsDragNDrop(options.x, options.y, callback); +end; + +function system.getScreenSize() + return _system_getScreenSize(); +end; + +function system.isMobile() + return _system_isMobile(); +end; + +function system.getTickCount() + return _system_getTickCount(); +end; + +function system.checkAPIVersion(major, minor) + return system.getAPIVersion() >= system.makeAPIVersionNumber(major, minor); +end; + +function system.getAPIVersion() + if _system_getAPIVersion ~= nil then + return _system_getAPIVersion(); + else + return system.makeAPIVersionNumber(87, 0); + end; +end; + +function system.makeAPIVersionNumber(major, minor) + return ((major or 0) << 16) | ((minor or 0) & 0xFFFF); +end; + +return system; \ No newline at end of file diff --git a/sdk/utils.lua b/sdk/utils.lua new file mode 100644 index 00000000..f1fe1671 --- /dev/null +++ b/sdk/utils.lua @@ -0,0 +1 @@ +return require("rrpgUtil.lua"); \ No newline at end of file diff --git a/sdk/utils.serializer.dlua b/sdk/utils.serializer.dlua new file mode 100644 index 00000000..2c5de095 --- /dev/null +++ b/sdk/utils.serializer.dlua @@ -0,0 +1,339 @@ +local utils = require("utils.lua"); +local SharedObjects = require("rrpgSharedObjects.lua"); + +local serializer = {}; + +local TYPE_STRING = 1; +local TYPE_NUMBER = 2; +local TYPE_BOOLEAN = 3; +local TYPE_TABLE = 4; +local TYPE_NIL = 5; +local TYPE_NUMBER_AS_INTEGER = 10; + +local typeToId = {string=TYPE_STRING, number=TYPE_NUMBER, boolean=TYPE_BOOLEAN, table=TYPE_TABLE}; +typeToId["nil"] = TYPE_NIL; + +local typesForKey = {}; +typesForKey[TYPE_STRING] = true; +typesForKey[TYPE_NUMBER] = true; +typesForKey[TYPE_BOOLEAN] = true; + +local typesForValue = {}; +typesForValue[TYPE_STRING] = true; +typesForValue[TYPE_NUMBER] = true; +typesForValue[TYPE_BOOLEAN] = true; +typesForValue[TYPE_TABLE] = true; + +local function binaryWrite(format, value, scope) + local buffer = scope._buffer; + + if buffer == nil then + buffer = {}; + scope._buffer = buffer; + end; + + local tam = utils.binaryEncode(buffer, format, value); + return scope.writer(buffer, tam); +end; + +local function binaryWriteString(value, scope) + local buffer2 = scope._buffer2; + + if buffer2 == nil then + buffer2 = {}; + scope._buffer2 = buffer2; + end; + + local tam = utils.binaryEncode(buffer2, "utf8", value); + local writed1 = binaryWrite("u32", tam, scope); + local writed2 = scope.writer(buffer2, tam); + + return writed1 + writed2; +end; + +function serializer.outputValue(value, scope) + local idType = typeToId[type(value)]; + + if idType == TYPE_TABLE then + local conseguiu, so = serializer.tryPackSharedObject(value); + + if conseguiu then + value = so; + idType = typeToId[type(value)]; + end; + end; + + if idType == nil then + error("Tipo não tratado"); + elseif idType == TYPE_NUMBER then + local numberType = math.type(value); + + if numberType == "integer" then + idType = TYPE_NUMBER_AS_INTEGER; + end; + end; + + binaryWrite("u8", idType, scope); + + if idType == TYPE_STRING then + binaryWriteString(value, scope); + elseif idType == TYPE_NUMBER then + binaryWrite("double", value, scope); + elseif idType == TYPE_NUMBER_AS_INTEGER then + binaryWrite("s64", value, scope); + elseif idType == TYPE_BOOLEAN then + if value then + binaryWrite("u8", 1, scope); + else + binaryWrite("u8", 0, scope); + end; + elseif idType == TYPE_TABLE then + serializer.outputTable(value, scope); + else + if idType ~= TYPE_NIL then + error("Tipo desconhecido"); + end; + end; +end; + +function serializer.outputTable(tabela, scope) + local toWrite = {}; + + for k, v in pairs(tabela) do + local kType = typeToId[type(k)]; + local vType = typeToId[type(v)]; + + if (kType ~= nil) and (typesForKey[kType]) and (vType ~= nil) and (typesForValue[vType]) then + toWrite[#toWrite + 1] = k; + end; + end; + + binaryWrite("u32", #toWrite, scope); + + for i = 1, #toWrite, 1 do + local k = toWrite[i]; + local v = tabela[k]; + serializer.outputValue(k, scope); + serializer.outputValue(v, scope); + end; +end; + + +local function binaryRead(format, scope) + local buffer = scope._buffer; + + if buffer == nil then + buffer = {}; + scope._buffer = buffer; + end; + + local bTam = utils.getBinarySize(format); + + if (bTam ~= nil) and (bTam > 0) then + local tamLido = scope.reader(buffer, bTam); + + if tamLido ~= bTam then + error("End of Stream"); + end; + + local value = utils.binaryDecode(buffer, format, 1, tamLido); + return value, tamLido; + else + error("Não é possível prever o tamanho do binaryRead"); + end; +end; + +local function binaryReadString(scope) + local buffer2 = scope._buffer2; + + if buffer2 == nil then + buffer2 = {}; + scope._buffer2 = buffer2; + end; + + local stringTam = binaryRead("u32", scope); + local tamLido = scope.reader(buffer2, stringTam); + + if tamLido ~= stringTam then + error("End of stream"); + end; + + local value = utils.binaryDecode(buffer2, "utf8", 1, tamLido); + return value, tamLido; +end; + +function serializer.inputValue(scope) + local tipo = binaryRead("u8", scope); + + if tipo == TYPE_STRING then + local vstr = binaryReadString(scope); + local conseguiu, so = serializer.tryUnpackSharedObject(vstr); + + if conseguiu then + return so; + else + return vstr; + end; + elseif tipo == TYPE_NIL then + return nil; + elseif tipo == TYPE_NUMBER then + return binaryRead("double", scope); + elseif tipo == TYPE_NUMBER_AS_INTEGER then + return binaryRead("s64", scope); + elseif tipo == TYPE_TABLE then + return serializer.inputTable(scope); + elseif tipo == TYPE_BOOLEAN then + return binaryRead("u8", scope) == 1; + else + error("Tipo Desconhecido: " .. tostring(tipo)); + end; +end; + +function serializer.inputTable(scope) + local qtProps = binaryRead("u32", scope); + local r = {}; + + for i = 1, qtProps, 1 do + local k = serializer.inputValue(scope); + local v = serializer.inputValue(scope); + r[k] = v; + end; + + return r; +end; + +function serializer.valueToStream(value, stream) + local scope = {}; + + scope.writer = function(bytes, qtBytes) + return stream:write(bytes, qtBytes); + end; + + return serializer.outputValue(value, scope); +end; + +function serializer.streamToValue(stream) + local scope = {}; + + scope.reader = function(bytes, qtBytes) + return stream:read(bytes, qtBytes); + end; + + return serializer.inputValue(scope); +end; + +function serializer.serialize(value) + local stream = utils.newMemoryStream(); + local stream2 = utils.newMemoryStream(); + local ret; + serializer.valueToStream(value, stream); + stream.position = 0; + + if stream.size > 512 then + -- compactar + stream2.position = 0; + local buffer = {1}; + stream2:write(buffer, 1); -- sinalizar que está compactado + + utils.zlibCompress(stream, stream2); + else + -- Não compactar + stream2.position = 0; + local buffer = {0}; + stream2:write(buffer, 1); -- sinalizar que não está compactado + + stream2:copyFrom(stream, stream.size); + end; + + stream.size = 0; + stream2.position = 0; + + ret = stream2:readAsBase64(); + stream2.size = 0; + + return ret; +end; + +function serializer.deserialize(base64str) + local stream = utils.newMemoryStream(); + local buffer = {}; + local ret; + + stream:writeBase64(base64str); + stream.position = 0; + + if stream:read(buffer, 1) ~= 1 then + error("End of Stream"); + end; + + if buffer[1] == 1 then + -- compactado + local stream2 = utils.newMemoryStream(); + utils.zlibDecompress(stream, stream2); + stream.size = 0; + stream2.position = 0; + + ret = serializer.streamToValue(stream2); + stream2.size = 0; + else + -- descompactado + ret = serializer.streamToValue(stream); + stream.size = 0; + end; + + return ret; +end; + +function serializer.tryPackSharedObject(tabela) + return SharedObjects.tryPack(tabela); +end; + +function serializer.tryUnpackSharedObject(str) + return SharedObjects.tryUnpack(str); +end; + +local _SERIALIZER_PREFIX = "###SERIALIZER_"; +local _SERIALIZER_SUFIX = "_###"; +local _SERIALIZER_MATCH_MASK = _SERIALIZER_PREFIX .. "(.+)" .. _SERIALIZER_SUFIX; + +function serializer.packData(data) + local typeId = typeToId[type(data)]; + + if typeId ~= nil then + if typeId == TYPE_TABLE then + local conseguiu, so = serializer.tryPackSharedObject(data); + + if conseguiu then + return so; + else + return _SERIALIZER_PREFIX .. serializer.serialize(data) .. _SERIALIZER_SUFIX; + end; + else + return data; + end; + else + return nil; + end +end; + +function serializer.unpackData(data) + if type(data) == "string" then + local conseguiu, so = serializer.tryUnpackSharedObject(data); + + if conseguiu then + return so; + else + local mData = string.match(data, _SERIALIZER_MATCH_MASK); + + if mData ~= nil then + return serializer.deserialize(mData); + else + return data; + end; + end; + else + return data; + end; +end; + +return serializer; \ No newline at end of file diff --git a/sdk/vhd.lua b/sdk/vhd.lua new file mode 100644 index 00000000..d5875959 --- /dev/null +++ b/sdk/vhd.lua @@ -0,0 +1,77 @@ +local localVHD = {}; + +vhd = localVHD; +VHD = vhd; + +function vhd.expandFileName(shortFileName) + return __vhd__expandFileName(shortFileName); +end; + +function vhd.addSearchPath(directory) + __vhd_addSearchPath(directory); +end; + +function vhd.removeSearchPath(directory) + __vhd_removeSearchPath(directory); +end; + +function vhd.fileExists(fileName) + return __vhd_fileExists(fileName); +end; + +local rrpgUtils = nil; + +function vhd.openFile(fileName, mode) + if rrpgUtils == nil then + rrpgUtils = require("rrpgUtil.lua"); + end; + + if type(mode) ~= "string" then + mode = "r"; + end; + + local expandedFileName = vhd.expandFileName(fileName); + local streamHandle, msgError = _vhd_openFile(expandedFileName, mode); + + if streamHandle ~= nil then + return rrpgUtils.streamFromHandle(streamHandle); + else + return nil, msgError; + end; +end; + +function VHD.forceDirectory(directoryPath) + return __vhd_forceDirectory(directoryPath); +end; + +function VHD.deleteFile(fileName) + return __vhd_deleteFile(fileName); +end + +function VHD.deleteDirectory(directoryPath) + return __vhd_deleteDirectory(directoryPath); +end + +function VHD.directoryExists(path) + return __vhd_directoryExists(path); +end + +function VHD.enumerateContent(directoryPath) + return __vhd_enumerateContent(directoryPath); +end + +function VHD.registerAlias(aliases) + return __vhd_registerAlias(aliases); +end; + +function VHD.copyFile(srcFileName, dstFileName) + local srcFile = VHD.openFile(srcFileName, "r"); + local dstFile = VHD.openFile(dstFileName, "w+"); + + dstFile:copyFrom(srcFile, srcFile.size); + + dstFile:close(); + srcFile:close(); +end; + +return localVHD; \ No newline at end of file diff --git a/sdk/vkCodes.dlua b/sdk/vkCodes.dlua new file mode 100644 index 00000000..9c8b7462 --- /dev/null +++ b/sdk/vkCodes.dlua @@ -0,0 +1,190 @@ +local codes = { + vkLButton = 0x01, + vkRButton = 0x02, + vkCancel = 0x03, + vkMButton = 0x04, + vkXButton1 = 0x05, + vkXButton2 = 0x06, + vkBack = 0x08, + vkTab = 0x09, + vkLineFeed = 0x0A, + vkClear = 0x0C, + vkReturn = 0x0D, + vkShift = 0x10, + vkControl = 0x11, + vkMenu = 0x12, + vkPause = 0x13, + vkCapital = 0x14, + vkKana = 0x15, + vkHangul = 0x15, + vkJunja = 0x17, + vkFinal = 0x18, + vkHanja = 0x19, + vkKanji = 0x19, + vkConvert = 0x1C, + vkNonConvert = 0x1D, + vkAccept = 0x1E, + vkModeChange = 0x1F, + vkEscape = 0x1B, + vkSpace = 0x20, + vkPrior = 0x21, + vkNext = 0x22, + vkEnd = 0x23, + vkHome = 0x24, + vkLeft = 0x25, + vkUp = 0x26, + vkRight = 0x27, + vkDown = 0x28, + vkSelect = 0x29, + vkPrint = 0x2A, + vkExecute = 0x2B, + vkSnapshot = 0x2C, + vkInsert = 0x2D, + vkDelete = 0x2E, + vkHelp = 0x2F, + + vk0 = 0x30, + vk1 = 0x31, + vk2 = 0x32, + vk3 = 0x33, + vk4 = 0x34, + vk5 = 0x35, + vk6 = 0x36, + vk7 = 0x37, + vk8 = 0x38, + vk9 = 0x39, + + vkA = 0x41, + vkB = 0x42, + vkC = 0x43, + vkD = 0x44, + vkE = 0x45, + vkF = 0x46, + vkG = 0x47, + vkH = 0x48, + vkI = 0x49, + vkJ = 0x4A, + vkK = 0x4B, + vkL = 0x4C, + vkM = 0x4D, + vkN = 0x4E, + vkO = 0x4F, + vkP = 0x50, + vkQ = 0x51, + vkR = 0x52, + vkS = 0x53, + vkT = 0x54, + vkU = 0x55, + vkV = 0x56, + vkW = 0x57, + vkX = 0x58, + vkY = 0x59, + vkZ = 0x5A, + vkLWin = 0x5B, + vkRWin = 0x5C, + vkApps = 0x5D, + vkSleep = 0x5F, + vkNumpad0 = 0x60, + vkNumpad1 = 0x61, + vkNumpad2 = 0x62, + vkNumpad3 = 0x63, + vkNumpad4 = 0x64, + vkNumpad5 = 0x65, + vkNumpad6 = 0x66, + vkNumpad7 = 0x67, + vkNumpad8 = 0x68, + vkNumpad9 = 0x69, + vkMultiply = 0x6A, + vkAdd = 0x6B, + vkSeparator = 0x6C, + vkSubtract = 0x6D, + vkDecimal = 0x6E, + vkDivide = 0x6F, + vkF1 = 0x70, + vkF2 = 0x71, + vkF3 = 0x72, + vkF4 = 0x73, + vkF5 = 0x74, + vkF6 = 0x75, + vkF7 = 0x76, + vkF8 = 0x77, + vkF9 = 0x78, + vkF10 = 0x79, + vkF11 = 0x7A, + vkF12 = 0x7B, + vkF13 = 0x7C, + vkF14 = 0x7D, + vkF15 = 0x7E, + vkF16 = 0x7F, + vkF17 = 0x80, + vkF18 = 0x81, + vkF19 = 0x82, + vkF20 = 0x83, + vkF21 = 0x84, + vkF22 = 0x85, + vkF23 = 0x86, + vkF24 = 0x87, + + vkCamera = 0x88, + vkHardwareBack = 0x89, + + vkNumLock = 0x90, + vkScroll = 0x91, + vkLShift = 0xA0, + vkRShift = 0xA1, + vkLControl = 0xA2, + vkRControl = 0xA3, + vkLMenu = 0xA4, + vkRMenu = 0xA5, + + vkBrowserBack = 0xA6, + vkBrowserForward = 0xA7, + vkBrowserRefresh = 0xA8, + vkBrowserStop = 0xA9, + vkBrowserSearch = 0xAA, + vkBrowserFavorites = 0xAB, + vkBrowserHome = 0xAC, + vkVolumeMute = 0xAD, + vkVolumeDown = 0xAE, + vkVolumeUp = 0xAF, + vkMediaNextTrack = 0xB0, + vkMediaPrevTrack = 0xB1, + vkMediaStop = 0xB2, + vkMediaPlayPause = 0xB3, + vkLaunchMail = 0xB4, + vkLaunchMediaSelect= 0xB5, + vkLaunchApp1 = 0xB6, + vkLaunchApp2 = 0xB7, + + vkSemicolon = 0xBA, + vkEqual = 0xBB, + vkComma = 0xBC, + vkMinus = 0xBD, + vkPeriod = 0xBE, + vkSlash = 0xBF, + vkTilde = 0xC0, + vkLeftBracket = 0xDB, + vkBackslash = 0xDC, + vkRightBracket = 0xDD, + vkQuote = 0xDE, + vkPara = 0xDF, + + vkOem102 = 0xE2, + vkIcoHelp = 0xE3, + vkIco00 = 0xE4, + vkProcessKey = 0xE5, + vkIcoClear = 0xE6, + vkPacket = 0xE7, + vkAttn = 0xF6, + vkCrsel = 0xF7, + vkExsel = 0xF8, + vkErEof = 0xF9, + vkPlay = 0xFA, + vkZoom = 0xFB, + vkNoname = 0xFC, + vkPA1 = 0xFD, + vkOemClear = 0xFE, + vkNone = 0xFF +}; + +return codes; \ No newline at end of file From 5104f0a3ded6325ac7bea5f86800aba066c5361d Mon Sep 17 00:00:00 2001 From: VilacaGabriel Date: Wed, 24 Sep 2025 18:15:53 -0300 Subject: [PATCH 3/3] Corrigido plugin Tormenta20 --- .../FichaT20_Jogodor.lfm | 857 +++++++ .../assets/fonts/Tormenta20x.ttf | Bin 0 -> 27316 bytes .../assets/imgs/atributos_ficha.png | Bin 0 -> 8547 bytes .../assets/imgs/card_magia.png | Bin 0 -> 14388 bytes .../assets/imgs/defesa_armadura.png | Bin 0 -> 8488 bytes .../assets/imgs/fundo_dinheiro.png | Bin 0 -> 3343 bytes .../assets/imgs/info_ficha.png | Bin 0 -> 29642 bytes .../assets/imgs/quadro_armas.png | Bin 0 -> 12569 bytes .../assets/imgs/quadro_carga.png | Bin 0 -> 7748 bytes .../assets/imgs/quadro_deslocamento.png | Bin 0 -> 1342 bytes .../assets/imgs/quadro_detalhes.png | Bin 0 -> 11279 bytes .../assets/imgs/quadro_dinheiro.png | Bin 0 -> 1294 bytes .../assets/imgs/quadro_direita.png | Bin 0 -> 6254 bytes .../assets/imgs/quadro_imagem.png | Bin 0 -> 6516 bytes .../assets/imgs/quadro_item.png | Bin 0 -> 6109 bytes .../assets/imgs/quadro_outros_poderes.png | Bin 0 -> 22221 bytes .../assets/imgs/quadro_pericias.png | Bin 0 -> 20853 bytes .../assets/imgs/quadro_poderes_classe.png | Bin 0 -> 19793 bytes .../imgs/quadro_raca_divindade_origem.png | Bin 0 -> 6223 bytes .../assets/imgs/quadro_tamanho.png | Bin 0 -> 1781 bytes .../assets/imgs/quadro_xp.png | Bin 0 -> 1559 bytes .../assets/imgs/seta_icone.png | Bin 0 -> 4324 bytes .../assets/imgs/titulo_magia.png | Bin 0 -> 4644 bytes .../assets/imgs/vida_mana.png | Bin 0 -> 8585 bytes .../assets/style/ficha_css.xml | 87 + .../assets/style/geralFichaT20Jogador_css.xml | 992 ++++++++ .../forms/cardItensJogador.lfm | 25 + .../forms/cardMagiaJogdor.lfm | 70 + .../script/functionsFichaJogador.xml | 328 +++ .../script/functionsMagias.xml | 46 + .../Ficha Tormenta 20 Jogo do Ano/README.md | 43 + .../Ficha Tormenta 20 Jogo do Ano/module.xml | 14 + .../output/Ficha Tormente20 Jogo do Ano.rpk | Bin 0 -> 371909 bytes .../output/Tormente20 Firecast.rpk | Bin 0 -> 370185 bytes .../sdk/README.md | 10 + .../sdk/async.lua | 486 ++++ .../sdk/audio.lua | 2 + .../sdk/audioCore.dlua | 194 ++ .../sdk/btree.dlua | 141 ++ .../sdk/btree_private.dlua | 849 +++++++ .../sdk/delayedLoad.dlua | 42 + .../sdk/dialogs.lua | 1 + .../sdk/fireDrive.lua | 3 + .../sdk/fireDriveCore.dlua | 261 +++ .../sdk/firecast.lua | 1 + .../Ficha Tormenta 20 Jogo do Ano/sdk/gui.lua | 1 + .../sdk/internet.lua | 3 + .../sdk/internetCore.dlua | 188 ++ .../sdk/locale.lua | 19 + .../sdk/localeCore.dlua | 99 + .../Ficha Tormenta 20 Jogo do Ano/sdk/log.lua | 39 + .../Ficha Tormenta 20 Jogo do Ano/sdk/ndb.lua | 929 ++++++++ .../sdk/ndb_observer.dlua | 51 + .../sdk/ndb_transaction.dlua | 53 + .../sdk/plugins.lua | 6 + .../sdk/pluginsCore.dlua | 243 ++ .../sdk/rrpg.lua | 442 ++++ .../sdk/rrpgDialogs.lua | 519 +++++ .../sdk/rrpgEventMessages.lua | 236 ++ .../sdk/rrpgEventMessagesAdapters.lua | 308 +++ .../sdk/rrpgEvents.lua | 133 ++ .../sdk/rrpgGUI.lua | 2060 +++++++++++++++++ .../sdk/rrpgGUI_grid.dlua | 244 ++ .../sdk/rrpgLFM.lua | 428 ++++ .../sdk/rrpgObjs.lua | 775 +++++++ .../sdk/rrpgRequests.lua | 83 + .../sdk/rrpgSharedObjects.lua | 149 ++ .../sdk/rrpgUtil.lua | 485 ++++ .../sdk/rrpgUtil_async.dlua | 78 + .../sdk/rrpgWrappers.lua | 1185 ++++++++++ .../sdk/scene.lua | 13 + .../sdk/sceneCore.dlua | 146 ++ .../sdk/sceneWrappers.dlua | 1123 +++++++++ .../sdk/sdk3.lang | 11 + .../sdk/serpent.dlua | 172 ++ .../sdk/slaxdom.dlua | 49 + .../sdk/slaxml.dlua | 257 ++ .../sdk/system.lua | 3 + .../sdk/systemCore.dlua | 51 + .../sdk/utils.lua | 1 + .../sdk/utils.serializer.dlua | 339 +++ .../Ficha Tormenta 20 Jogo do Ano/sdk/vhd.lua | 77 + .../sdk/vkCodes.dlua | 190 ++ Plugins/Sheets/Ficha Tormente20 Jogo do Ano | 1 - 84 files changed, 15640 insertions(+), 1 deletion(-) create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/FichaT20_Jogodor.lfm create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/fonts/Tormenta20x.ttf create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/atributos_ficha.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/card_magia.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/defesa_armadura.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/fundo_dinheiro.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/info_ficha.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_armas.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_carga.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_deslocamento.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_detalhes.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_dinheiro.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_direita.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_imagem.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_item.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_outros_poderes.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_pericias.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_poderes_classe.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_raca_divindade_origem.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_tamanho.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_xp.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/seta_icone.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/titulo_magia.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/vida_mana.png create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/style/ficha_css.xml create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/style/geralFichaT20Jogador_css.xml create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/forms/cardItensJogador.lfm create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/forms/cardMagiaJogdor.lfm create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsFichaJogador.xml create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsMagias.xml create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/README.md create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/module.xml create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/output/Ficha Tormente20 Jogo do Ano.rpk create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/output/Tormente20 Firecast.rpk create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/README.md create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/async.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audio.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audioCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree_private.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/delayedLoad.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/dialogs.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDrive.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDriveCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/firecast.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/gui.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internet.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internetCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/locale.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/localeCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/log.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_observer.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_transaction.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/plugins.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/pluginsCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpg.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgDialogs.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessages.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessagesAdapters.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEvents.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI_grid.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgLFM.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgObjs.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgRequests.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgSharedObjects.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil_async.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgWrappers.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/scene.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneWrappers.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sdk3.lang create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/serpent.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxdom.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxml.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/system.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/systemCore.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.serializer.dlua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vhd.lua create mode 100644 Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vkCodes.dlua delete mode 160000 Plugins/Sheets/Ficha Tormente20 Jogo do Ano diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/FichaT20_Jogodor.lfm b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/FichaT20_Jogodor.lfm new file mode 100644 index 00000000..c74f1da2 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/FichaT20_Jogodor.lfm @@ -0,0 +1,857 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + calcNivel(self) + + + + + calcVidaMana(self, "fldVidaMaxima", "fldVidaAtual","fldVidaTemporaria","fldCalculadoraVida") + + + + + calcVidaMana(self, "fldManaMaxima", "fldManaAtual","fldManaTemporaria","fldCalculadoraMana") + + + + + calcBonusArmadura(self) + + + + + calcBonusEscudo(self) + + + + + calcAtributoDefesa(self) + + + + + alteraAtributoChave(self) + calcSobrecargaMaxima(self) + + + calcTotalPericia(self, "fldAcrobaciaOutros","acro_treino","acro_atrib_name","fldAcrobaciaTotal",true) + + + calcTotalPericia(self, "flsAdestramentoOutros","ades_treino","ades_atrib_name","fldAdestramentoTotal",false) + + + calcTotalPericia(self, "fldAtletismoOutros","atle_treino","atle_atrib_name","fldAtletismoTotal",false) + + + calcTotalPericia(self, "fldAtuacaoOutros","atua_treino","atua_atrib_name","fldAtuacaoTotal",false) + + + calcTotalPericia(self, "fldCavalgarOutros","cava_treino","cava_atrib_name","fldCavalgarTotal",false) + + + calcTotalPericia(self, "fldConhecimentoOutros","conh_treino","conh_atrib_name","fldConhecimentoTotal",false) + + + calcTotalPericia(self, "fldCuraOutros","cura_treino","cura_atrib_name","fldCuraTotal",false) + + + calcTotalPericia(self, "fldDiplomaciaOutros","dipl_treino","dipl_atrib_name","fldDiplomaciaTotal",false) + + + calcTotalPericia(self, "fldEnganacaoOutros","enga_treino","enga_atrib_name","fldEnganacaoTotal",false) + + + calcTotalPericia(self, "fldFortitudeOutros","fort_treino","fort_atrib_name","fldFortitudeTotal",false) + + + calcTotalPericia(self, "fldFurtividadeOutros","furt_treino","furt_atrib_name","fldFurtividadeTotal",true) + + + calcTotalPericia(self, "fldGuerraOutros","guer_treino","guer_atrib_name","fldGuerraTotal",false) + + + calcTotalPericia(self, "fldIniciativaOutros","inic_treino","inic_atrib_name","fldIniciativaTotal",false) + + + calcTotalPericia(self, "fldIntimidacaoOutros","init_treino","inti_atrib_name","fldInitimidacaoTotal",false) + + + calcTotalPericia(self, "fldIntuicaoOutros","intu_treino","intu_atrib_name","fldIntuicaoTotal",false) + + + calcTotalPericia(self, "fldInvestigacaoOutros","inve_treino","inve_atrib_name","fldInvestigacaoTotal",false) + + + calcTotalPericia(self, "fldJogatinaOutros","joga_treino","joga_atrib_name","fldJogatinaTotal",false) + + + calcTotalPericia(self, "fldLadinagemOutros","ladi_treino","ladi_atrib_name","fldLadinagemTotal",true) + + + calcTotalPericia(self, "fldLutaOutros","luta_treino","luta_atrib_name","fldLutaTotal",false) + + + calcTotalPericia(self, "fldMisticismoOutros","mist_treino","mist_atrib_name","fldMisticismoTotal",false) + + + calcTotalPericia(self, "fldNobrezaOutros","nobr_treino","nobr_atrib_name","fldNobrezaTotal",false) + + + calcTotalPericia(self, "fldOficio1Outros","ofi1_treino","ofi1_atrib_name","fldOficio1Total",false) + + + calcTotalPericia(self, "fldOficio2Outros","ofi2_treino","ofi2_atrib","fldOficio2Total",false) + + + calcTotalPericia(self, "fldPercepcaoOutros","perc_treino","perc_atrib_name","fldPercepcaoTotal",false) + + + calcTotalPericia(self, "fldPilotagemOutros","pilo_treino","pilo_atrib_name","fldPilotagemTotal",false) + + + calcTotalPericia(self, "fldPontariaOutros","pont_treino","pont_atrib_name","fldPontariaTotal",false) + + + calcTotalPericia(self, "fldReflexosOutros","refl_treino","refl_atrib","fldReflexosTotal",false) + + + calcTotalPericia(self, "fldReligiaoOutros","reli_treino","reli_atrib_name","fldReligiaoTotal",false) + + + calcTotalPericia(self, "fldSobrevivenciaOutros","sobr_treino","sobr_atrib_name","fldSobrevivenciaTotal",false) + + + calcTotalPericia(self, "fldVontadeOutros","vont_treino","vont_atrib_name","fldVontadeTotal",false) + + + + + calcCargaAtual(self) + + + + diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/fonts/Tormenta20x.ttf b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/fonts/Tormenta20x.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4cb8be66f26294c350cbd23e343f64b078f4d8a6 GIT binary patch literal 27316 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 literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/atributos_ficha.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/atributos_ficha.png new file mode 100644 index 0000000000000000000000000000000000000000..9eee06ac41cfcb636adf3a94e848afe084fc8140 GIT binary patch literal 8547 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 WwvDe}6NCTw1GLrk5tVB8QU3?`5)#}1 literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/defesa_armadura.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/defesa_armadura.png new file mode 100644 index 0000000000000000000000000000000000000000..fda58e26ad8b79de5554aac32f899de31206aa43 GIT binary patch literal 8488 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 N$Vw_nRErq}{U3+9ZFB$t literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_armas.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_armas.png new file mode 100644 index 0000000000000000000000000000000000000000..ece5076064dcf3170c4e3aeecb9289e083f9c940 GIT binary patch literal 12569 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 literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_item.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_item.png new file mode 100644 index 0000000000000000000000000000000000000000..77f7d9a1f9b214a2d233a636793230d650cb4760 GIT binary patch literal 6109 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 literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_pericias.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_pericias.png new file mode 100644 index 0000000000000000000000000000000000000000..ba994e46271f5ac96c17d1227672566b635db244 GIT binary patch literal 20853 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 g+6Xz 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 ON8B*f%GbR6@IL_TOjLjX literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_tamanho.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_tamanho.png new file mode 100644 index 0000000000000000000000000000000000000000..fd3824d1f3e4f1c433e19f8d35bec1d9f3d5424a GIT binary patch literal 1781 zcmY*adsvcL9wsko-ftNu77O~QlZb$pDBxmfXz3U_h1HbYBjf`GgE7q1ZBg@5=B>$G zG2NL~6YXMYF)da$rdc_qnWfX13aMk3*SySp%=XOg{&CLvUCw!b?|IKT&&i32-eGOA z(Em>gfZPzoWp!- zYBDD_H9C%!Dq!K+o*^V_3xYfdL=bYM47gmF2uOnDM8qG!L7;62qY)%RGMgJjqlAB+ z0eVElVX0Icghm^9%5VmTXbc{YNBd#XSS$*hfs%X!NEvbzAVGcxpl~FtWWHF+7Xfes zAcHANkrELpDSUPim%$BSve^MBCIiPtVK8h4iowQVP;4BIy)6I}h~;9Kh|lGveC~hi z1Cq}&fP$b688pV%&p_E=2Ys2$=YT8>B}o{u^#P_V^lK?+e9-L!C07?07YAVrZ;`dO9JLHE$XX17QlFx-331oH2Xgo(I1=nS#8 z>gf8X>QA+I{g`f<4yi;t=9BrA`Oc9KszIE#byL00x$=|B_sH?2HJy6@>?ZMc?`z+p zo(TfHYTGoHOvI0?@t1+|6vz5;Z7x8rp?Uk%lxb(+6~^|~D=_boT9cg?IqlsxHgoez zGeKI~>*>O!V^(aX5_-{&YQM9VcJsnx{blNl{=sm;4LpGkiP;zLW`_(uL#_06MgIKF zCT2m_^1Ix@+`r*W$4>?e%%#+u&>P5c#P<;Fe>7`=xL9K+z|_8acd%!=e)Wlu9_e3OcCoPvUW+h zrStW`u`kRU-lh~`+OH{P&rPbj+&blZazBP?))MKFA4-d9rfmdPK21Gv|6rYIXY?ev>{)sf?CfZnVP4+C%Fm`9-gUn5%{#Z64&`W_0g%y>N8DXh&t= z)Wx)Ce|MA=bAmb4In+NQ9<3zq@7_}J6x{K}oO|wp+qRUV9a&bmt5+L^uFo%9+&;cJ zHZ~TXyPAA6OOqD&@I2H?(UG0*?6vr^eYD-?&7Ikve45_TGN&VA1(&z; z=UHN6N$2TM_+Bw`seWXM^ll(vruA!&+KEpY=~Gk5i`ug!vlCeO{-q^bUeQlWv`c$Y z-QH*X1y{ngSA4o^N5u+79`Ie3zTYK{>ORps9{6c2CZoyhf$`MHqsWoMpH`m4*2FD5 zYDRTj)^)2XM)tql0QAp)TxUeC?mKpib_u4_yifIMb719F6OwqZtlpfHWqVw5j~^}I z95_AKaN5~81U|5J$vf}VI`Eh$Zrd4^axyswc6rfDC!KQ4^9qN$8k4SHGr1)7adthG z6Fi)H@;ld>UHAft;r>+%>0eK0V;&^Z-85s|yZ;(*O;S$(v!9tBP+5nXYcIj$o!A)7 z@{HbZOkASO^zz=VCJw9M?IqX;P!}YoC#w(O;XJ1h#K+q;t=8(HZDwj0o@_(oJMit- zIBd4J-%meiGzOd9XAOx!C>#Yhh88tXb?^ELGS~H%w|FZDzD>wiofpIA@0{XnAGS4G Rd}#PqBEq664WS8{zXPoU6`=qC literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_xp.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/quadro_xp.png new file mode 100644 index 0000000000000000000000000000000000000000..82263348e2fe6ba823ed6b9c273f2c24809163ad GIT binary patch literal 1559 zcmY*ZdpML?9R8+^WrS5oq}33s%#3l1akt-yTsC83(ysdE#x%?f-)IJ@s5CA~_gtph z+FfH@mL#FcShsz!<9Sli(@H6cT_m+5#D3Fy_VUL$=lA=a_j`Zud7pE>oL%8N^fBfb z008uZgFp%Zpd66cN=F-+WxtS{kOc)(b_4*`s*U4Fq7~;K<_`e1r}Y*gG?MEIg7&}w zV9=@=s5@u4lSpxckW3Rs^4UTWl*|G|A`za$1`M78s-=#_=*+J2}(<5 zMW%&Q8EIUG2h+~iM<3%QCLs)oEFokiPE6pzB(XR46EO*iHDv1h)*xoPb zfs65(_&MhS2PN-|I_F+Q0iIbf~8rx6nlDJLikwY9I# z&E)9zs`^YA*y}q}JT1Q|-KR`n7Q>>ky2UjWRN6KueaLUq(55fix;?oamnAaF-aa=$ zN~-Qphcmb$b;a_xYXg$5?V5AJ*@EDOSq^45n!4|052g*%qZFa63SQ7bklI+8Zv5J` zjspFlL;*IztEMxEwpe+-dQMLvGyM@l_sa(MmA;wnW*+FHHf+c!BIBlt*jeg@ z-ifAebpVd4Ed|*K=kKC|?pb>FfJu~maJ|tKf~y*F&z2|`T(+{!qG%O)lP6V=4Z-6r zYu83p-M7h_d<*ae)rB7~2~s)Z{Yvz(1;h4*yPK#utQUv3(#aaBmq@mnbP<~t zEK9GHD$(K3lg`?XU$RJl;@h)xFn0a3GxetO+z%b((C{H#>@kTf%5F#3YtRVP;uHsD zPX7VUs?KHC)s?HKEB;)Hb9eJG;4V~b=M49BxW`KjD9?W!a@C2bLmVxwtv z8|rQs^Sf1@sBN6uh^Sh%vD)1p06@B zHG0^GHt3}JbvswyFXp=@EN{W8rLb9JN`=`vqumqp^X8ms*-JYM&nN0xQM2K;N*zB= lU7kc1z6!Kx_Jr=$ETNM08%z!ds{{6D{RO1fm;V3& literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/seta_icone.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/seta_icone.png new file mode 100644 index 0000000000000000000000000000000000000000..f9355ed74757d4022b93558afaea7e6ba1f9d893 GIT binary patch literal 4324 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 YoLQISg+u3Kp??vG_D*(Xwx`bj7j2WkMgRZ+ literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/titulo_magia.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/titulo_magia.png new file mode 100644 index 0000000000000000000000000000000000000000..e27810fe540aeac01fc7b9baeffa1b1da6a1e3d1 GIT binary patch literal 4644 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 Z={V}2uP%L~%X0b)V+w&9*6BOP{TKFf$`Swo literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/vida_mana.png b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/imgs/vida_mana.png new file mode 100644 index 0000000000000000000000000000000000000000..652e0d31645fa0dd1b1a548ea7404b3a4c670b7e GIT binary patch literal 8585 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 UbV!cmzd9J|ndsK(+ + + \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/style/geralFichaT20Jogador_css.xml b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/style/geralFichaT20Jogador_css.xml new file mode 100644 index 00000000..ca31fb74 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/assets/style/geralFichaT20Jogador_css.xml @@ -0,0 +1,992 @@ + + + \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/forms/cardItensJogador.lfm b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/forms/cardItensJogador.lfm new file mode 100644 index 00000000..b8a9db6a --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/forms/cardItensJogador.lfm @@ -0,0 +1,25 @@ + +
+ + + + + + + + diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsFichaJogador.xml b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsFichaJogador.xml new file mode 100644 index 00000000..b7ccc0c0 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsFichaJogador.xml @@ -0,0 +1,328 @@ + + \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsMagias.xml b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsMagias.xml new file mode 100644 index 00000000..ca64b650 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/Ficha Tormenta20 Jogador/script/functionsMagias.xml @@ -0,0 +1,46 @@ + + \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/README.md b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/README.md new file mode 100644 index 00000000..6ce04ba8 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/README.md @@ -0,0 +1,43 @@ +# Ficha Tormenta20 para Firecast + +Este repositório contém um **plugin para Firecast/RRPG** que implementa a ficha digital do sistema **Tormenta20**. +O objetivo é facilitar a vida de jogadores e mestres, permitindo controle automático de atributos, rolagens, carga e muito mais. + +⚠️ **Aviso:** Este projeto está em **desenvolvimento ativo**. Algumas funcionalidades podem estar incompletas ou sujeitas a mudanças. + +--- + +## ✨ Funcionalidades + +- 🎲 **Rolagens automáticas** de atributos, perícias e testes diretamente pela ficha. +- ⚔️ **Integração com tokens**: atributos de vida, mana e outros sincronizados com o mapa. +- 📦 **Controle de mochila e carga**: +- 🛡️ **Gestão de defesas**: armaduras leves, médias, pesadas e escudos com cálculo automático. +- 📜 **Campos de anotações** para poderes, magias e inventário. + +--- + +## 📂 Estrutura do Projeto + +📦 Tormenta20-Firecast +┣ 📂 forms/ # Arquivos XML de interface +┣ 📂 scripts/ # Funções auxiliares em Lua +┣ 📂 assets/ # Imagens e estilos +┣ 📜 FichaT20_Jogador.lfm # Ficha principal +┣ 📜 FichaT20_Jogador.lfm.lua # Lógica da ficha +┣ 📜 plugin.xml # Configurações do plugin +┗ 📜 README.md # Este arquivo + +--- + +##🚀 Instalação + +1.Baixe o arquivo Tormente20 Firecast.rpk em Tormente20 Firecast/output/. +2.Com o Firecast aberto e logado, dê dois cliques no arquivo .rpk. +3.O plugin será instalado automaticamente. + +--- +## Versão Atual + +A versão atual 1.0.2 + diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/module.xml b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/module.xml new file mode 100644 index 00000000..1399a0f2 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/module.xml @@ -0,0 +1,14 @@ + + + T20_Fichas_Jogo_do_Ano + 1.0.3 + + + Fichas para Tormenta20 edição Jogo do Ano + Ficha para Tormenta20 edição Jogo do Ano (fichas de jogadores) + Gabriel Vilaça + https://github.com/VilacaGabriel/Plugin-do-Firecast-T20 + gabriel.felipe1234@hotmail.com + + + diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/output/Ficha Tormente20 Jogo do Ano.rpk b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/output/Ficha Tormente20 Jogo do Ano.rpk new file mode 100644 index 0000000000000000000000000000000000000000..e8ee8c7ec7121a21db1e2287563b58dc5c6fd3da GIT binary patch literal 371909 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%0DbqN7Zt1AM_kAqfv?FI_CkN(ie71=J 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%0A3C&2NZ&z`Nt71QoO6FeI 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%0DDVtHi9&K$vzs_n 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 literal 0 HcmV?d00001 diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/output/Tormente20 Firecast.rpk b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/output/Tormente20 Firecast.rpk new file mode 100644 index 0000000000000000000000000000000000000000..32a86f30f2ece4f0407ef892d1aaace88817033a GIT binary patch literal 370185 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 EVL8*qk?Q+er{?LQ~$X3 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 z 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 0 then + local co = _asyncExecution.idleCoroutines[_asyncExecution.idleCoroutinesCount]; + _asyncExecution.idleCoroutinesCount = _asyncExecution.idleCoroutinesCount - 1; + return co; + else + return _asyncExecution.createIdleCoroutine(); + end; +end; + +function _asyncExecution.releaseIdleCoroutine(co) + if _asyncExecution.idleCoroutinesCount < _asyncExecution.maxIdleCoroutines then + _asyncExecution.idleCoroutinesCount = _asyncExecution.idleCoroutinesCount + 1; + _asyncExecution.idleCoroutines[_asyncExecution.idleCoroutinesCount] = co; + else + coroutine.resume(co, false, nil, nil, nil); + end; +end; + +-- Exported API to the Firecast Executable + +function __async_start_execution(fn, ...) + return Async.execute(fn, ...); +end; + +-- Async.Promise public API + +function Promise.resolved(...) + if Async.haveNativeBackendSupport() then + return Promise.wrap(_async_promise_newResolved(...)); + else + return Promise.__newStubSuccessPromise(...); + end; +end; + +function Promise.withError(errorMsg) + if Async.haveNativeBackendSupport() then + return Promise.wrap(_async_promise_newWithException(errorMsg)); + else + return Promise.__newStubFailedPromise(errorMsg); + end; +end; + +function Promise.toResolve() + local promiseHandle, promiseResolutionHandle = _async_promise_newToResolve(); + + local promise = Promise.wrap(promiseHandle); + local promiseResolution = Promise.wrapPromiseResolution(promiseResolutionHandle); + + return promise, promiseResolution; +end; + +function Promise.toHandle(promise, successCallback, failureCallback) + assert(promise ~= nil); + + local outerPromise, outerResolution = Promise.toResolve(); + + promise:thenDo( + function (...) + if successCallback ~= nil then + local ret = table.pack(pcall(successCallback, ...)); + + if ret[1] then + outerResolution:setSuccess(table.unpack(ret, 2)); + else + outerResolution:setFailure(ret[2]); + end; + else + outerResolution:setSuccess(...); + end; + end, + + function (originalErrorMsg) + if failureCallback ~= nil then + local ret = table.pack(pcall(failureCallback, originalErrorMsg)); + + if ret[1] then + outerResolution:setSuccess(table.unpack(ret, 2)); + else + outerResolution:setFailure(ret[2]); + end; + else + outerResolution:setFailure(originalErrorMsg); + end; + end); + + return outerPromise; +end; + +function Promise.isPromise(value) + return (type(value) == "table") and + (value.thenDo ~= nil) and + (value.onError ~= nil) and + (value.await ~= nil); +end; + +function Promise.all(...) + local normalized = {}; + local argsTable = table.pack(...); + + for i = 1, #argsTable, 1 do + local item = argsTable[i]; + + if Promise.isPromise(item) then + normalized[#normalized + 1] = item.handle; + else + for j = 1, #item, 1 do + local subItem = item[j]; + + if Promise.isPromise(subItem) then + normalized[#normalized + 1] = subItem.handle; + end; + end; + end; + end; + + return Promise.wrap(_async_promise_newAll(normalized)); +end; + +-- Async library public API + +function Async.await(promise) + if (coroutine.isyieldable ~= nil) and not coroutine.isyieldable() then + error("Is not possible to await outside a coroutine. Please consider using the Async.execute function"); + end; + + if not Promise.isPromise(promise) then + return promise; + end; + + local ret = table.pack(promise:peek()); + + if ret[1] then + if ret[2] then + if #ret >= 3 then + return table.unpack(ret, 3); + else + return nil; + end; + else + local traceMessage = ret[3] .. "\n" .. debug.traceback(coroutine.running(), nil, 2); + reraise(traceMessage); + end; + end; + + ret = table.pack(coroutine.yield(_ASYNC_EXEC_AWAIT_CO_RET, promise)); + + if ret[1] then + if #ret >= 2 then + return table.unpack(ret, 2); + else + return nil; + end; + else + local traceMessage = ret[2] .. "\n" .. debug.traceback(coroutine.running(), nil, 2); + reraise(traceMessage); + end; +end; + +function Async.pawait(promise) + if (coroutine.isyieldable ~= nil) and not coroutine.isyieldable() then + error("Is not possible to pawait outside a coroutine. Please consider using the Async.execute function"); + end; + + if not Promise.isPromise(promise) then + return true, promise; + end; + + local ret = table.pack(promise:peek()); + + if ret[1] then + return table.unpack(ret, 2); + else + return coroutine.yield(_ASYNC_EXEC_AWAIT_CO_RET, promise); + end; +end; + +function Async.execute(fn, ...) + local co = _asyncExecution.acquireIdleCoroutine(); + local promise, resolution = Async.Promise.pending(); + + _asyncExecution.resume(co, true, fn, table.pack(...), resolution); + + return promise; +end; + +Promise.withException = Promise.withError; +Promise.failed = Promise.withError; +Promise.pending = Promise.toResolve; +Promise.succeeded = Promise.resolved; +Promise.resolve = Promise.resolved; +Promise.reject = Promise.withError; +await = Async.await; +pawait = Async.pawait; + +return Async \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audio.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audio.lua new file mode 100644 index 00000000..7f84d685 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audio.lua @@ -0,0 +1,2 @@ +Audio = require("delayedLoad.dlua").new("audioCore.dlua"); +return Audio; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audioCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audioCore.dlua new file mode 100644 index 00000000..e42afa46 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/audioCore.dlua @@ -0,0 +1,194 @@ +local Async = require("async.lua"); +local Objs = require("rrpgObjs.lua"); + +local audioLib = Objs.objectFromHandle(_obj_newObject("TRRPGAudioLibWrapper")); +assert(audioLib ~= nil); + +if audioLib.props == nil then + audioLib.props = {}; +end; + +-- AudioStream Class wrapper + +function audioLib._newAudioStreamWrapperFromStreamReader(streamReader) + local objHandle = _obj_invokeEx(audioLib.handle, 'CreateAudioStream', streamReader); + return audioLib._newAudioStreamWrapperFromObjectHandle(objHandle); +end; + +function audioLib._newAudioStreamWrapperFromObjectHandle(objHandle) + local stream = Objs.objectFromHandle(objHandle); + stream.props = stream.props or {}; + stream.eves = stream.eves or {}; + + function stream:getLength() + return _obj_invokeEx(self.handle, "GetLengthInSecs"); + end; + + function stream:getPosition() + return _obj_invokeEx(self.handle, "GetPositionInSecs"); + end; + + function stream:setPosition(newPosition) + return _obj_invokeEx(self.handle, "SetPositionInSecs", newPosition); + end; + + function stream:waitEOF() + return Async.Promise.wrap(_obj_invokeEx(self.handle, 'WaitEOF')); + end; + + stream.props["enabled"] = {readProp="Enabled", writeProp="Enabled", tipo="bool"}; + stream.props["eof"] = {readProp="IsEOF", tipo="bool"}; + stream.props["length"] = {getter="getLength", tipo="float"}; + stream.props["position"] = {getter="getPosition", setter="setPosition", tipo="float"}; + stream.props["volume"] = {readProp="Volume", writeProp="Volume", tipo="float"}; + + stream.eves["onEOF"] = ""; + return stream; +end; + +-- AudioTrack Class wrapper + +function audioLib._audioTrackWrapperFromHandle(audioStream, objHandle) + local track = Objs.objectFromHandle(objHandle); + track.props = track.props or {}; + track.eves = track.eves or {}; + + rawset(track, "_attachedStream", audioStream); + + function track:getAudioStream() + return rawget(self, "_attachedStream"); + end; + + function track:remove() + return Async.Promise.wrap(_obj_invokeEx(self.handle, 'AsyncRemoveTrack')); + end; + + function track:waitRemoval() + return Async.Promise.wrap(_obj_invokeEx(self.handle, 'WaitRemoval')); + end; + + track.props["audioStream"] = {getter = "getAudioStream", tipo="table"}; + track.props["removed"] = {readProp = "Removed", tipo="bool"}; + + track.eves["onRemoved"] = ""; + return track; +end; + +function audioLib._newNullAudioTrackWrapper(audioStream) + local track = Objs.newPureLuaObject(); + track.props = {}; + + rawset(track, "audioStream", audioStream); + rawset(track, "removed", true); + + function track:remove() + return Async.Promise.resolved(); + end; + + function track:waitRemoval() + return Async.Promise.resolved(); + end; + + return track; +end; + +-- AudioPlayer Class internal utility + +local function __keepStrongReferenceToTrackUntilRemoved(track) + track:waitRemoval():thenFinally( + function() + track = nil; + end) +end; + +local function __keepStrongReferenceToTrackPromiseUntilRemoved(trackPromise) + trackPromise:thenDo( + function (track) + __keepStrongReferenceToTrackUntilRemoved(track); + end); +end; + +-- AudioPlayer Class wrapper + +function audioLib._audioPlayerWrapperFromHandle(objHandle) + local sa = Objs.objectFromHandle(objHandle); + + function sa:asyncAddTrack(audioStream, params) + local trackHandlePromise = Async.Promise.wrap(_obj_invokeEx(self.handle, 'AsyncCreateAudioTrack', audioStream.handle, params)); + + return trackHandlePromise:thenDo( + function(trackHandle) + return audioLib._audioTrackWrapperFromHandle(audioStream, trackHandle); + end); + end; + + function sa:play(source, volume) + local streamPromise = audioLib.asyncLoadAudioStream(source); + + local trackPromise = streamPromise:thenDo( + function(audioStream) + if type(volume) == "number" then + audioStream.volume = volume; + end; + + local trackPromise = self:asyncAddTrack(audioStream, {autoRemoveOnEOF=true}); + __keepStrongReferenceToTrackPromiseUntilRemoved(trackPromise); + return trackPromise; + end); + + return trackPromise; + end; + + return sa; +end; + +function audioLib._newNullAudioPlayerWrapper(errorMessage) + local sa = Objs.newPureLuaObject(); + + if errorMessage == nil then + errorMessage = "No API Support"; + end; + + function sa:asyncAddTrack(audioStream, params) + return Async.Promise.failed(errorMessage); + end; + + function sa:play(source, volume) + return Async.Promise.failed(errorMessage); + end; + + return sa; +end; + +-- AudioLib public API + +function audioLib.asyncLoadAudioStream(source) + local loadPromise = Async.Promise.wrap(_obj_invokeEx(audioLib.handle, 'AsyncLoadStreamReader', source)); + + return loadPromise:thenDo( + function(streamReader) + return audioLib._newAudioStreamWrapperFromStreamReader(streamReader); + end); +end; + +function audioLib:getDefaultPlayer() + local cachedPlayer = rawget(audioLib, "__cachedDefaultAudioPlayer"); + + if cachedPlayer == nil then + local handle = _obj_invokeEx(self.handle, 'CreateGlobalAudioPlayer'); + cachedPlayer = audioLib._audioPlayerWrapperFromHandle(handle); + + assert(cachedPlayer ~= nil); + rawset(audioLib, "__cachedDefaultAudioPlayer", cachedPlayer); + end; + + return cachedPlayer; +end; + +function audioLib.play(source, volume) + return audioLib.defaultPlayer:play(source, volume); +end; + +audioLib.props["defaultPlayer"] = {getter="getDefaultPlayer", tipo="table"}; + +return audioLib; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree.dlua new file mode 100644 index 00000000..14b21fcf --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree.dlua @@ -0,0 +1,141 @@ +local BTreeInner = require("btree_private.dlua"); +local BTree = {}; + +local function DEFAULT_BTREE_COMPARER(left, right) + if left < right then + return -1; + elseif left > right then + return 1; + else + return 0; + end; +end; + +function BTree.new(theComparer) + local bt = {}; + + -- Atributos privados + bt.comparer = theComparer or DEFAULT_BTREE_COMPARER; + bt.raiz = nil; + bt.count = 0; + + local comparer = bt.comparer; + + -- métodos privados + + for k, v in pairs(BTreeInner) do + bt[k] = v; + end; + + -- Funções Públicas + + function bt:inserir(chave, valor) + if self.raiz == nil then + self.raiz = self:alocarPagina(); + end; + + local inserirEm, indiceInserir = self:innerLocalizarForInsert(self.raiz, chave); + + if inserirEm == nil then + error("InnerLocalizarForInsert retornou nil"); + end; + + if (indiceInserir <= inserirEm.countChaves) and (comparer(inserirEm.chaves[indiceInserir].valorChave, chave) == 0) then + error("Esta chave já existe"); + end; + + self:innerInsertCollated(inserirEm, indiceInserir, chave, valor); + end; + + function bt:alterar(chave, valor) + local pEncontrado, indice = self:innerLocateCollated(self.raiz, chave); + + if pEncontrado ~= nil then + pEncontrado.chaves[indice].valor = valor; + else + error("Esta chave não existe para que seu valor seja alterado"); + end; + end; + + function bt:inserirOuAlterar(chave, valor) + + if self.raiz == nil then + self.raiz = self:alocarPagina(); + end; + + local inserirEm, indiceInserir = self:innerLocalizarForInsert(self.raiz, chave); + + if inserirEm == nil then + error("InnerLocalizarForInsert retornou nil"); + end; + + if (indiceInserir <= inserirEm.countChaves) and (comparer(inserirEm.chaves[indiceInserir].valorChave, chave) == 0) then + inserirEm.chaves[indiceInserir].valor = valor; + else + self:innerInsertCollated(inserirEm, indiceInserir, chave, valor); + end; + end; + + function bt:remover(chave) + local pEncontrado, indice = self:innerLocateCollated(self.raiz, chave); + + if pEncontrado ~= nil then + pEncontrado.chaves[indice].valorChave = nil; + pEncontrado.chaves[indice].valor = nil; + self:innerDelete(pEncontrado, indice); + self.count = self.count - 1; + end; + end; + + function bt:limpar() + self.raiz = nil; + self.count = 0; + end; + + function bt:existe(chave) + local pEncontrado = self:innerLocateCollated(self.raiz, chave); + return (pEncontrado ~= nil); + end; + + function bt:tryGet(chave) + local pEncontrado, indice = self:innerLocateCollated(self.raiz, chave); + + if pEncontrado ~= nil then + return true, pEncontrado.chaves[indice].valor; + else + return false, nil; + end; + end; + + function bt:menorChave() + if self.root == nil then + return nil; + end; + + local pEncontrada, indice = self:innerFindLowest(self.raiz); + + if pEncontrada ~= nil then + return pEncontrada.chaves[indice].valorChave, pEncontrada.chaves[indice].valor; + end; + end; + + function bt:maiorChave() + if self.root == nil then + return nil; + end; + + local pEncontrada, indice = self:innerFindHighest(self.raiz); + + if pEncontrada ~= nil then + return pEncontrada.chaves[indice].valorChave, pEncontrada.chaves[indice].valor; + end; + end; + + function bt:navigator() + return self:createNavigator(); + end; + + return bt; +end; + +return BTree; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree_private.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree_private.dlua new file mode 100644 index 00000000..c91c3cbb --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/btree_private.dlua @@ -0,0 +1,849 @@ +local BTreeIN = {}; + +local ARV_GRAU = 4; +local MAX_CHAVES = (ARV_GRAU * 2) - 1; +local MAX_FILHOS = (ARV_GRAU * 2); + +local MIN_CHAVES = ARV_GRAU - 1; + + +-- Funções privadas + +local function pagina_setCountChaves(pagina, count) + if count < pagina.countChaves then + for i = count + 1, pagina.countChaves, 1 do + pagina.chaves[i].valorChave = nil; + pagina.chaves[i].valor = nil; + end; + end; + + pagina.countChaves = count; +end; + +function BTreeIN:alocarPagina() + local pagina = {countChaves=0, filhos={}, pai=nil, indiceNoPai=1}; + local chaves = {}; + + for i = 1, MAX_CHAVES, 1 do + chaves[i] = {valorChave = nil, valor = nil}; + end; + + pagina.chaves = chaves; + return pagina; +end; + + +function BTreeIN:innerLocalizarForInsert(paginaOrigem, chaveALocalizar) + local comp, pOrg, min, max, meio; + + pOrg = paginaOrigem; + + while pOrg ~= nil do + min = 1; + max = pOrg.countChaves; + + while min <= max do + meio = math.ceil((min + max) / 2); + comp = self.comparer(chaveALocalizar, pOrg.chaves[meio].valorChave); + + if comp == 0 then + return pOrg, meio; + elseif comp < 0 then + max = meio - 1; + else + min = meio + 1; + end; + end; + + if pOrg.filhos[min] ~= nil then + pOrg = pOrg.filhos[min]; + else + return pOrg, min; + end; + end; + + return nil, -1; +end; + +function BTreeIN:innerAlocarEspaco(pagina, indiceEspaco) + local mediana, indiceNoPai, countToLeft, countToRight, countSemMediana, qtRetirado; + local novoIrmaoEsq, oPai; + + if pagina.countChaves >= MAX_CHAVES then + -- Vamos precisar dividir a página em 2 páginas. + mediana = math.ceil(pagina.countChaves / 2); + oPai = pagina.pai; + + if oPai == nil then + -- Estamos na raiz; + oPai = self:alocarPagina(); + self.raiz = oPai; + end; + + indiceNoPai = pagina.indiceNoPai; + + -- Subir Mediana + oPai, indiceNoPai = self:innerAlocarEspaco(oPai, indiceNoPai); + oPai.chaves[indiceNoPai].valorChave = pagina.chaves[mediana].valorChave; + oPai.chaves[indiceNoPai].valor = pagina.chaves[mediana].valor; + + novoIrmaoEsq = self:alocarPagina(); + + -- Copiar as chaves que estão antes da mediana para o novo irmão da esquerda + + countSemMediana = pagina.countChaves - 1; + countToLeft = math.ceil(countSemMediana / 2); + countToRight = countSemMediana - countToLeft; + qtRetirado = pagina.countChaves - countToRight; + + for i = 1, countToLeft, 1 do + novoIrmaoEsq.chaves[i].valorChave = pagina.chaves[i].valorChave; + novoIrmaoEsq.chaves[i].valor = pagina.chaves[i].valor; + end; + + for i = 1, countToLeft + 1, 1 do + novoIrmaoEsq.filhos[i] = pagina.filhos[i]; + + if novoIrmaoEsq.filhos[i] ~= nil then + novoIrmaoEsq.filhos[i].pai = novoIrmaoEsq; + end; + end; + + -- Reduzir o tamanho da Direita + + for i = 1, countToRight, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + qtRetirado].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + qtRetirado].valor; + end; + + for i = 1, countToRight + 1, 1 do + pagina.filhos[i] = pagina.filhos[i + qtRetirado]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + for i = countToRight + 2, MAX_FILHOS, 1 do + pagina.filhos[i] = nil; + end; + + pagina_setCountChaves(novoIrmaoEsq, countToLeft); + pagina_setCountChaves(pagina, countToRight); + + -- Ligar os pontos no OPai + oPai.filhos[indiceNoPai] = novoIrmaoEsq; + oPai.filhos[indiceNoPai + 1] = pagina; + + novoIrmaoEsq.pai = oPai; + novoIrmaoEsq.indiceNoPai = indiceNoPai; + + pagina.pai = oPai; + pagina.indiceNoPai = indiceNoPai + 1; + + if indiceEspaco > mediana then + indiceEspaco = indiceEspaco - qtRetirado; + else + pagina = novoIrmaoEsq; + end; + end; + + for i = pagina.countChaves + 1, indiceEspaco + 1, -1 do + pagina.chaves[i].valorChave = pagina.chaves[i - 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i - 1].valor; + end; + + for i = pagina.countChaves + 2, indiceEspaco + 2, -1 do + pagina.filhos[i] = pagina.filhos[i - 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina.filhos[indiceEspaco + 1] = nil; + pagina_setCountChaves(pagina, pagina.countChaves + 1); + return pagina, indiceEspaco; +end; + +function BTreeIN:innerInsertCollated(inserirEm, indice, chave, valor) + inserirEm, indice = self:innerAlocarEspaco(inserirEm, indice); + inserirEm.chaves[indice].valorChave = chave; + inserirEm.chaves[indice].valor = valor; + self.count = self.count + 1; +end; + +function BTreeIN:innerLocateCollated(paginaOrigem, chaveALocalizar) + local comp, min, max, meio, pOrg; + + pOrg = paginaOrigem; + + while pOrg ~= nil do + min = 1; + max = pOrg.countChaves; + + while min <= max do + meio = math.ceil((min + max) / 2); + comp = self.comparer(chaveALocalizar, pOrg.chaves[meio].valorChave); + + if comp == 0 then + return pOrg, meio; + elseif comp < 0 then + max = meio - 1; + else + min = meio + 1; + end; + end; + + pOrg = pOrg.filhos[min]; + end; + + return nil, nil; +end; + +function BTreeIN:innerFindLowest(pagina) + local pOrg = pagina; + + while (pOrg ~= nil) and (pOrg.countChaves > 0) do + if pOrg.filhos[1] ~= nil then + pOrg = pOrg.filhos[1]; + else + return pOrg, 1; + end; + end; +end; + +function BTreeIN:innerFindHighest(pagina) + local pOrg = pagina; + + while (pOrg ~= nil) and (pOrg.countChaves > 0) do + local ind = pOrg.countChaves; + + if pOrg.filhos[ind + 1] ~= nil then + pOrg = pOrg.filhos[ind + 1]; + else + return pOrg, ind; + end; + end; +end; + +function BTreeIN:destruirPagina(_) + -- faz nada +end; + +function BTreeIN:innerDeletePucharDeCima(pagina, indice) + local retIndice; + local oPai, irmaoEsq, irmaoDir, paginaAux; + local indiceTemp, qtACopiar, tempChave, tempValor; + + oPai = pagina.pai; + retIndice = indice; + + if oPai == nil then + -- Estamos na raiz, não temos irmao nem pai. nao temos de onde puxar + -- Remover a chave + + for i = indice, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + -- Mover os filhos + + for i = indice + 1, pagina.countChaves do + pagina.filhos[i] = pagina.filhos[i + 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(pagina, pagina.countChaves - 1); + return pagina, indice, retIndice; + end; + + if pagina.indiceNoPai > 1 then + irmaoEsq = oPai.filhos[pagina.indiceNoPai - 1]; + else + irmaoEsq = nil; + end; + + if pagina.indiceNoPai < oPai.countChaves + 1 then + irmaoDir = oPai.filhos[pagina.indiceNoPai + 1]; + else + irmaoDir = nil; + end; + + + if (irmaoDir ~= nil) and (irmaoDir.countChaves > MIN_CHAVES) then + -- Vamos pegar uma chave do irmão da direita + -- Remover a chave do indice + + for i = indice, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + for i = indice + 1, pagina.countChaves, 1 do + pagina.filhos[i] = pagina.filhos[i + 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar a chave do pai; + pagina.chaves[pagina.countChaves].valorChave = oPai.chaves[pagina.indiceNoPai].valorChave; + pagina.chaves[pagina.countChaves].valor = oPai.chaves[pagina.indiceNoPai].valor; + + -- Pegar os primeiros filhos do irmão da direita + paginaAux = irmaoDir.filhos[1]; + pagina.filhos[pagina.countChaves + 1] = paginaAux; + + if paginaAux ~= nil then + paginaAux.pai = pagina; + paginaAux.indiceNoPai = pagina.countChaves + 1; + end; + + -- Mover a chave do irmao direita para o pai + + oPai.chaves[pagina.indiceNoPai].valorChave = irmaoDir.chaves[1].valorChave; + oPai.chaves[pagina.indiceNoPai].valor = irmaoDir.chaves[1].valor; + + -- excluir a chave do irmao da direita + + for i = 1, irmaoDir.countChaves - 1, 1 do + irmaoDir.chaves[i].valorChave = irmaoDir.chaves[i + 1].valorChave; + irmaoDir.chaves[i].valor = irmaoDir.chaves[i + 1].valor; + end; + + for i = 1, irmaoDir.countChaves, 1 do + irmaoDir.filhos[i] = irmaoDir.filhos[i + 1]; + + if irmaoDir.filhos[i] ~= nil then + irmaoDir.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(irmaoDir, irmaoDir.countChaves - 1); + return pagina, indice, retIndice; + end; + + if (irmaoEsq ~= nil) and (irmaoEsq.countChaves > MIN_CHAVES) then + -- Não conseguimos negociar com o irmão da direita. Vamos tentar no da esquerda + -- Remover a chave do Indice abrindo espaço no inicio para caber a Chave do Pai + qtACopiar = 1; + + -- Copiar os que estão do lado esquerdo da chave que vai ser apagada + for i = indice + qtACopiar, qtACopiar + 2, -1 do + pagina.chaves[i - 1].valorChave = pagina.chaves[i - qtACopiar - 1].valorChave; + pagina.chaves[i - 1].valor = pagina.chaves[i - qtACopiar - 1].valor; + end; + + for i = indice + qtACopiar, qtACopiar + 1, -1 do + pagina.filhos[i] = pagina.filhos[i - qtACopiar]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar a chave do pai + pagina.chaves[1].valorChave = oPai.chaves[pagina.indiceNoPai - 1].valorChave; + pagina.chaves[1].valor = oPai.chaves[pagina.indiceNoPai - 1].valor; + + -- Pegar os ultimos filhos do irmao da esquerda + paginaAux = irmaoEsq.filhos[irmaoEsq.countChaves + 1]; + pagina.filhos[1] = paginaAux; + + if paginaAux ~= nil then + paginaAux.pai = pagina; + paginaAux.indiceNoPai = 1; + end; + + oPai.chaves[pagina.indiceNoPai - 1].valorChave = irmaoEsq.chaves[irmaoEsq.countChaves].valorChave; + oPai.chaves[pagina.indiceNoPai - 1].valor = irmaoEsq.chaves[irmaoEsq.countChaves].valor; + pagina_setCountChaves(irmaoEsq, irmaoEsq.countChaves - 1); + return pagina, indice, retIndice; + end; + + -- Se chegou aqui, os irmãos não podem doar uma chave. Devemos mesclar + + if irmaoDir ~= nil then + -- Mesclar com o irmão da direita + + -- Obtendo a chave que vai vir de cima + tempChave = oPai.chaves[pagina.indiceNoPai].valorChave; + tempValor = oPai.chaves[pagina.indiceNoPai].valor; + + -- Remover a chave do indice + for i = indice, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + for i = indice + 1, pagina.countChaves, 1 do + pagina.filhos[i] = pagina.filhos[i + 1]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar uma chave do pai + pagina.chaves[pagina.countChaves].valorChave = tempChave; + pagina.chaves[pagina.countChaves].valor = tempValor; + + -- Copiar as chaves e filhos do irmão + qtACopiar = irmaoDir.countChaves; + + for i = pagina.countChaves + 1, pagina.countChaves + qtACopiar, 1 do + pagina.chaves[i].valorChave = irmaoDir.chaves[i - pagina.countChaves].valorChave; + pagina.chaves[i].valor = irmaoDir.chaves[i - pagina.countChaves].valor; + end; + + for i = pagina.countChaves + 1, pagina.countChaves + qtACopiar + 1, 1 do + pagina.filhos[i] = irmaoDir.filhos[i - pagina.countChaves]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].pai = pagina; + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(pagina, pagina.countChaves + irmaoDir.countChaves); + + if oPai.countChaves > MIN_CHAVES then + -- Remover a chave + + for i = pagina.indiceNoPai, oPai.countChaves - 1, 1 do + oPai.chaves[i].valorChave = oPai.chaves[i + 1].valorChave; + oPai.chaves[i].valor = oPai.chaves[i + 1].valor; + end; + + -- Mover os filhos + + for i = pagina.indiceNoPai + 1, oPai.countChaves, 1 do + oPai.filhos[i] = oPai.filhos[i + 1]; + + if oPai.filhos[i] ~= nil then + oPai.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(oPai, oPai.countChaves - 1); + else + --local novoIndiceNoPai; + --oPai, novoIndiceNoPai = self:innerDeletePucharDeCima(oPai, pagina.indiceNoPai); + --pagina.indiceNoPai = novoIndiceNoPai; + self:innerDeletePucharDeCima(oPai, pagina.indiceNoPai); + + if oPai.countChaves == 0 then + self.raiz = pagina; + pagina.pai = nil; + pagina.indiceNoPai = 1; + self:destruirPagina(oPai); + --oPai = nil; + end; + end; + + self:destruirPagina(irmaoDir); + return pagina, indice, retIndice; + end; + + if irmaoEsq ~= nil then + --self.deveValidar = true; + + -- Mesclar com o irmão da esquerda + tempChave = oPai.chaves[pagina.indiceNoPai - 1].valorChave; + tempValor = oPai.chaves[pagina.indiceNoPai - 1].valor; + + -- Remover a chave do indice abrinco espaco no inicio para caber a chave do pai + chaves do irmao da esquerda + qtACopiar = irmaoEsq.countChaves; + + -- Copiar os que estão do lado direito da chave que vai ser apagada + + for i = pagina.countChaves + qtACopiar, indice + qtACopiar + 1, -1 do + pagina.chaves[i].valorChave = pagina.chaves[i - qtACopiar].valorChave; + pagina.chaves[i].valor = pagina.chaves[i - qtACopiar].valor; + end; + + for i = pagina.countChaves + qtACopiar + 1, indice + qtACopiar + 1, -1 do + pagina.filhos[i] = pagina.filhos[i - qtACopiar]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].indiceNoPai = i; + end; + end; + + -- Copiar os que estão do lado esquerdo da chave que vai ser apagada + for i = indice + qtACopiar, qtACopiar + 2, -1 do + pagina.chaves[i].valorChave = pagina.chaves[i - qtACopiar - 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i - qtACopiar - 1].valor; + end; + + for i = indice + qtACopiar, qtACopiar + 1, -1 do + pagina.filhos[i + 1] = pagina.filhos[i - qtACopiar]; + + if pagina.filhos[i + 1] ~= nil then + pagina.filhos[i + 1].indiceNoPai = i + 1; + end; + end; + + -- Copiar a chave do pai + pagina.chaves[irmaoEsq.countChaves + 1].valorChave = tempChave; + pagina.chaves[irmaoEsq.countChaves + 1].valor = tempValor; + + -- copiar as chaves e filhos do irmão da esquerda + + for i = 1, irmaoEsq.countChaves, 1 do + pagina.chaves[i].valorChave = irmaoEsq.chaves[i].valorChave; + pagina.chaves[i].valor = irmaoEsq.chaves[i].valor; + end; + + for i = 1, irmaoEsq.countChaves + 1, 1 do + pagina.filhos[i] = irmaoEsq.filhos[i]; + + if pagina.filhos[i] ~= nil then + pagina.filhos[i].pai = pagina; + pagina.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(pagina, pagina.countChaves + irmaoEsq.countChaves); + + if oPai.countChaves > MIN_CHAVES then + -- Remover a chave + + for i = pagina.indiceNoPai, oPai.countChaves - 1, 1 do + oPai.chaves[i].valorChave = oPai.chaves[i + 1].valorChave; + oPai.chaves[i].valor = oPai.chaves[i + 1].valor; + end; + + -- Mover os filhos + + for i = pagina.indiceNoPai - 1, oPai.countChaves, 1 do + oPai.filhos[i] = oPai.filhos[i + 1]; + + if oPai.filhos[i] ~= nil then + oPai.filhos[i].indiceNoPai = i; + end; + end; + + pagina_setCountChaves(oPai, oPai.countChaves - 1); + else + indiceTemp = pagina.indiceNoPai - 1; + --oPai, indiceTemp = self:innerDeletePucharDeCima(oPai, indiceTemp); + oPai = self:innerDeletePucharDeCima(oPai, indiceTemp); + + if oPai.countChaves == 0 then + self.raiz = pagina; + pagina.pai = nil; + pagina.indiceNoPai = 1; + self:destruirPagina(oPai); + oPai = nil; + end; + end; + + if oPai ~= nil then + oPai.filhos[irmaoEsq.indiceNoPai] = pagina; + end; + + pagina.indiceNoPai = irmaoEsq.indiceNoPai; + self:destruirPagina(irmaoEsq); + return pagina, indice, retIndice; + end; + + error("Ops, não deveria ter chegado até aqui"); +end; + +function BTreeIN:innerDelete(pagina, indiceEspaco) + local oPai, filhoEsq, filhoDir; + local pagToDelete; + local indiceToDelete; + + oPai = pagina.pai; + + if (pagina.filhos[indiceEspaco] == nil) and (pagina.filhos[indiceEspaco + 1] == nil) then + -- É uma página folha + + if (oPai ~= nil) and (pagina.countChaves <= MIN_CHAVES) then + -- Não é root e vai atingir limite minimo + indiceToDelete = indiceEspaco; + --pagina, indiceToDelete = self:innerDeletePucharDeCima(pagina, indiceToDelete) + self:innerDeletePucharDeCima(pagina, indiceToDelete) + else + for i = indiceEspaco, pagina.countChaves - 1, 1 do + pagina.chaves[i].valorChave = pagina.chaves[i + 1].valorChave; + pagina.chaves[i].valor = pagina.chaves[i + 1].valor; + end; + + pagina_setCountChaves(pagina, pagina.countChaves - 1); + end; + else + -- Página nó + filhoEsq = pagina.filhos[indiceEspaco]; + filhoDir = pagina.filhos[indiceEspaco + 1]; + + if filhoDir ~= nil then + pagToDelete, indiceToDelete = self:innerFindLowest(filhoDir); + + if pagToDelete ~= nil then + pagina.chaves[indiceEspaco].valorChave = pagToDelete.chaves[indiceToDelete].valorChave; + pagina.chaves[indiceEspaco].valor = pagToDelete.chaves[indiceToDelete].valor; + self:innerDelete(pagToDelete, indiceToDelete); + return; + else + error("Ops"); + end; + end; + + if filhoEsq ~= nil then + pagToDelete, indiceToDelete = self:innerFindHighest(filhoEsq); + + if pagToDelete ~= nil then + pagina.chaves[indiceEspaco].valorChave = pagToDelete.chaves[indiceToDelete].valorChave; + pagina.chaves[indiceEspaco].valor = pagToDelete.chaves[indiceToDelete].valor; + self:innerDelete(pagToDelete, indiceToDelete); + return; + else + error("Ops"); + end; + end; + + error("Ops. Não era para ter chegado ate aqui"); + end; +end; + +function BTreeIN:checarPagina(p, min, max) + local vMin , vMax; + local last = nil; + + for i = 1, p.countChaves, 1 do + if (min ~= nil) and (self.comparer(p.chaves[i].valorChave, min) < 0) then + error("Ops. Existe uma falha na ordem das paginas, min"); + end; + + if (max ~= nil) and (self.comparer(p.chaves[i].valorChave, max) > 0) then + error("Ops. Existe uma falha na ordem das paginas, max"); + end; + + if i > 1 then + if self.comparer(p.chaves[i].valorChave, last) <= 0 then + error("Ops. os numeros de uma página não estão ordenados de forma crescente"); + end; + end; + + last = p.chaves[i].valorChave; + end; + + -- Checar Filhos + + for i = 1, p.countChaves + 1, 1 do + if p.filhos[i] ~= nil then + if i == 1 then + vMax = p.chaves[i].valorChave; + self:checarPagina(p.filhos[i], min, vMax); + elseif i == p.countChaves + 1 then + vMin = p.chaves[i - 1].valorChave; + self:checarPagina(p.filhos[i], vMin, max); + else + vMin = p.chaves[i - 1].valorChave; + vMax = p.chaves[i].valorChave; + self:checarPagina(p.filhos[i], vMin, vMax); + end; + end; + end; + + if p.pai ~= nil then + if p.pai.filhos[p.indiceNoPai] ~= p then + error("Indice no pai de uma pagina esta errada"); + end; + end; +end; + +function BTreeIN:validate(errPrefix) + local ok, err = pcall(self.checarPagina, self, self.raiz, nil, nil); + + if not ok then + --error(err .. "\n\n: " .. tableToStr(self.raiz, true)); + error((errPrefix or "") .. err); + end; +end; + + +function BTreeIN.createNavigator(bt) + local nav = {}; + + local fPaginaAtual = nil; + local fIndiceAtual = -1; + local fEof = true; + local fBof = true; + + function nav:first() + local pagina, indice; + local raiz = bt.raiz; + + if raiz ~= nil then + pagina, indice = bt:innerFindLowest(raiz); + end; + + if pagina ~= nil then + fPaginaAtual = pagina; + fIndiceAtual = indice; + fEof = false; + fBof = true; + else + fPaginaAtual = nil; + fIndiceAtual = -1; + fEof = true; + fBof = true; + end; + end; + + function nav:last() + local pagina, indice; + local raiz = bt.raiz; + + if raiz ~= nil then + pagina, indice = bt:innerFindHighest(raiz); + end; + + if pagina ~= nil then + fPaginaAtual = pagina; + fIndiceAtual = indice; + fEof = true; + fBof = false; + else + fPaginaAtual = nil; + fIndiceAtual = -1; + fEof = true; + fBof = true; + end; + end; + + function nav:next() + local pagAtual, pagEncontrada, oPai; + local indAtual, indEncontrado, indPai; + + pagAtual = fPaginaAtual; + indAtual = fIndiceAtual; + + if (pagAtual == nil) or (indAtual == -1) then + fEof = true; + return; + end; + + if pagAtual.filhos[indAtual + 1] ~= nil then + pagEncontrada, indEncontrado = bt:innerFindLowest(pagAtual.filhos[indAtual + 1]); + + fEof = false; + fBof = false; + fPaginaAtual = pagEncontrada; + fIndiceAtual = indEncontrado; + else + if indAtual < pagAtual.countChaves then + fIndiceAtual = fIndiceAtual + 1; + else + -- Já estamos apontando para o último desta página. vamos procurar recursivamente nos pais + oPai = pagAtual.pai; + indPai = pagAtual.indiceNoPai; + + local deveProcurar = true; + + while deveProcurar do + if oPai == nil then + fEof = true; + deveProcurar = false; + else + if indPai <= oPai.countChaves then + fPaginaAtual = oPai; + fIndiceAtual = indPai; + deveProcurar = false; + else + indPai = oPai.indiceNoPai; + oPai = oPai.pai; + end; + end; + end; + end; + end; + end; + + function nav:previous() + local pagAtual, pagEncontrada, oPai; + local indAtual, indEncontrado, indPai; + + pagAtual = fPaginaAtual; + indAtual = fIndiceAtual; + + if (pagAtual == nil) or (indAtual == -1) then + fBof = true; + return; + end; + + if pagAtual.filhos[indAtual] ~= nil then + pagEncontrada, indEncontrado = bt:innerFindHighest(pagAtual.filhos[indAtual]); + + fEof = false; + fBof = false; + fPaginaAtual = pagEncontrada; + fIndiceAtual = indEncontrado; + else + if indAtual > 1 then + fIndiceAtual = fIndiceAtual - 1; + else + -- Já estamos apontando para o último desta página. vamos procurar recursivamente nos pais + oPai = pagAtual.pai; + indPai = pagAtual.indiceNoPai; + + local deveProcurar = true; + + while deveProcurar do + if oPai == nil then + fBof = true; + deveProcurar = false; + else + if indPai > 1 then + fPaginaAtual = oPai; + fIndiceAtual = indPai - 1; + deveProcurar = false; + else + indPai = oPai.indiceNoPai; + oPai = oPai.pai; + end; + end; + end; + end; + end; + end; + + function nav:key() + if fPaginaAtual ~= nil then + return fPaginaAtual.chaves[fIndiceAtual].valorChave; + else + return nil; + end; + end; + + function nav:value() + if fPaginaAtual ~= nil then + return fPaginaAtual.chaves[fIndiceAtual].valor; + else + return nil; + end; + end; + + function nav:eof() + return fEof; + end; + + function nav:bof() + return fBof; + end; + + nav:first(); + return nav; +end; + +return BTreeIN; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/delayedLoad.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/delayedLoad.dlua new file mode 100644 index 00000000..fbd8902d --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/delayedLoad.dlua @@ -0,0 +1,42 @@ +local dLoadHelper = {}; + +function dLoadHelper.new(moduleName) + local interface = {}; + local moduleObject = nil; + + local metaTable = { + __index = function(table, key) + if moduleObject == nil then + moduleObject = require(moduleName); + end; + + if moduleObject ~= nil then + local r = moduleObject[key]; + + if type(r) == "function" then + rawset(table, key, r); + end; + + return r; + else + return nil; + end; + end, + + __newindex = function(table, key, value) + if moduleObject == nil then + moduleObject = require(moduleName); + end; + + rawset(table, key, value); + end; + }; + + rawset(interface, "__isDelayedLoad", true); + rawset(interface, "__delayedLoadModuleName", moduleName); + + setmetatable(interface, metaTable); + return interface; +end; + +return dLoadHelper; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/dialogs.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/dialogs.lua new file mode 100644 index 00000000..2acdf45d --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/dialogs.lua @@ -0,0 +1 @@ +return require("rrpgDialogs.lua"); \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDrive.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDrive.lua new file mode 100644 index 00000000..77c93b17 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDrive.lua @@ -0,0 +1,3 @@ +fireDrive = require("delayedLoad.dlua").new("fireDriveCore.dlua"); +FireDrive = fireDrive; +return fireDrive; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDriveCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDriveCore.dlua new file mode 100644 index 00000000..b63ac244 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/fireDriveCore.dlua @@ -0,0 +1,261 @@ +require("rrpg.lua"); +local plugins = require("plugins.lua"); +local fdmodule = "RRPG.FIRECAST.FMXModule"; + +plugins.requirePlugin(fdmodule); + +local fireDrive = {}; + +local _uploads = {}; +local _uploadsIdGenerator = 0; + +local function unsetupUpload(uploadId) + local upload =_uploads[uploadId]; + + if upload ~= nil then + plugins.unlistenPM(upload.pmListenerId); + upload.pmListenerId = nil; + _uploads[uploadId] = nil; + end; +end; + +local function fdManageItem(destName, metadata, onSuccess, onProgress, onFailure) + _uploadsIdGenerator = _uploadsIdGenerator + 1; + local esteId = _uploadsIdGenerator; + local esteUpload = {}; + local msg = {}; + + _uploads[esteId] = esteUpload; + esteUpload.destName = destName; + esteUpload.metadata = metadata; + esteUpload.onSuccess = onSuccess; + esteUpload.onProgress = onProgress; + esteUpload.onFailure = onFailure; + esteUpload.pmListener = "L" .. _rrpg_generateUniqueStrID(); + esteUpload.pmListenerId = plugins.listenPM(esteUpload.pmListener, + function (receivedMsg) + plugins.replyPM(receivedMsg, nil); + + if receivedMsg.kind == "progress" then + if onProgress ~= nil then + onProgress(receivedMsg.currentBytes, receivedMsg.maxBytes); + end; + elseif receivedMsg.kind == "error" then + unsetupUpload(esteId); + + if onFailure ~= nil then + onFailure(receivedMsg.errorMsg); + end; + elseif receivedMsg.kind == "end" then + unsetupUpload(esteId); + + if onSuccess ~= nil then + onSuccess(receivedMsg.successData); + end; + elseif receivedMsg.kind == "uploadId" then + esteUpload.remoteUploadId = receivedMsg.uploadId; + end; + end); + + msg.destName = destName; + msg.metadata = metadata; + msg.uploadId = esteId; + msg.pmListener = esteUpload.pmListener; + + plugins.sendPM(fdmodule, "fireDrive:manageItem", msg, + function (_) + + end, + + function (r) + if onFailure ~= nil then + unsetupUpload(esteId); + onFailure(r); + end; + end); + + return esteId; +end; + +local function tryGetMimeFromFileName(fileName) + local ext = string.match(fileName, "%.[^%.\\/]+$"); + + if ext ~= nil then + local r, mime = _util_tryGetMimeFromExtension(ext); + + if r then + return mime; + else + return 'application/octet-stream'; + end; + else + return 'application/octet-stream'; + end; +end; + +local function fdExecuteUpload(params) + if type(params) ~= "table" then + error("fdExecuteUpload - params was not informed"); + end; + + if type(params.stream) ~= "table" then + error("fireDrive upload - stream was not informed"); + end; + + local metadata = {}; + params.stream.position = 0; + + if params.stream.size > 128 * 1024 * 1024 then + if params.onFailure then + params.onFailure("FILE TOO BIG"); + end; + + return nil; + end; + + metadata.headers = {}; + + if params.isQuickUpload then + params.destName = params.suggestedFileName; + metadata.headers.operation = "quickUpload"; + else + metadata.headers.operation = "create"; + metadata.headers.kind = "file"; + end; + + metadata.blobs = {}; + metadata.blobs[1] = {name="content", streamSharedId = params.stream:share(), mimeType = params.mimeType or tryGetMimeFromFileName(params.destName)}; + + if params.isQuickUpload and not _util_isValidMimeType(metadata.blobs[1].mimeType) then + error("INVALID MIME TYPE: " .. tostring(metadata.blobs[1].mimeType)); + end; + + local ret = fdManageItem(params.destName, metadata, params.onSuccess, params.onProgress, params.onFailure); + metadata.blobs[1].data = nil; + return ret; +end; + +function fireDrive.uploadFile(destName, stream, onSuccess, onProgress, onFailure, mimeType) + local params = {}; + params.destName = destName; + params.stream = stream; + params.onSuccess = onSuccess; + params.onProgress = onProgress; + params.onFailure = onFailure; + params.mimeType = mimeType; + + return fdExecuteUpload(params); +end; + +function fireDrive.upload(...) + return fireDrive.uploadFile(...); +end; + +function fireDrive.quickUpload(suggestedFileName, mimeType, stream, onSuccess, onProgress, onFailure) + local params = {}; + params.stream = stream; + params.onSuccess = onSuccess; + params.onProgress = onProgress; + params.onFailure = onFailure; + params.mimeType = mimeType; + params.isQuickUpload = true; + params.suggestedFileName = suggestedFileName; + + return fdExecuteUpload(params); +end; + +function fireDrive.abortOperation(operationId) + local upload = _uploads[operationId]; + + if upload ~= nil then + plugins.sendPM(fdmodule, "fireDrive:abortOperation", {uploadId = upload.remoteUploadId}); + end; + + unsetupUpload(operationId); +end; + +function fireDrive.createDirectory(directoryName, onSuccess, onFailure) + local metadata = {}; + metadata.headers = {}; + metadata.headers.operation = "create"; + metadata.headers.kind = "directory"; + + return fdManageItem(directoryName, metadata, onSuccess, nil, onFailure); +end; + +function fireDrive.delete(destName, onSuccess, onFailure) + local metadata = {}; + metadata.headers = {}; + metadata.headers.operation = "delete"; + return fdManageItem(destName, metadata, onSuccess, nil, onFailure); +end; + +function fireDrive.rename(existingFileName, newFileName, onSuccess, onFailure) + local metadata = {}; + metadata.headers = {}; + metadata.headers.operation = "rename"; + metadata.headers.newFileName = newFileName; + return fdManageItem(existingFileName, metadata, onSuccess, nil, onFailure); +end; + +function fireDrive.getFiles(directory, callback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:enumerateFiles", {dir=directory}, + function(r) + if callback ~= nil then + callback(r); + end; + end, + + function(r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +function fireDrive.refresh(refreshCallback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:refresh", nil, + function (r) + if refreshCallback ~= nil then + refreshCallback(r); + end; + end, + + function (r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +function fireDrive.getFileInfo(fileName, callback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:getFileInfo", {fileName=fileName}, + function (r) + if callback ~= nil then + callback(r); + end; + end, + + function (r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +function fireDrive.getSpaceInfo(callback, failureCallback) + plugins.sendPM(fdmodule, "fireDrive:getSpaceInfo", nil, + function (r) + if callback ~= nil then + callback(r); + end; + end, + + function (r) + if failureCallback ~= nil then + failureCallback(r); + end; + end); +end; + +return fireDrive; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/firecast.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/firecast.lua new file mode 100644 index 00000000..1a3a8b17 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/firecast.lua @@ -0,0 +1 @@ +return require('rrpg.lua'); \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/gui.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/gui.lua new file mode 100644 index 00000000..60ae87f6 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/gui.lua @@ -0,0 +1 @@ +return require("rrpgGUI.lua"); \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internet.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internet.lua new file mode 100644 index 00000000..05ae4b0f --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internet.lua @@ -0,0 +1,3 @@ +internet = require("delayedLoad.dlua").new("internetCore.dlua"); +Internet = internet; +return internet; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internetCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internetCore.dlua new file mode 100644 index 00000000..0a3811d8 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/internetCore.dlua @@ -0,0 +1,188 @@ +local objs = require("rrpgObjs.lua"); +local utils = require("rrpgUtil.lua"); +local Async = require("async.lua"); + +local lInternet = {}; +local _downloadIdGenerator = 1; +local _downloads = {}; +local internet = lInternet; + +function internet.asyncDownload(url, cacheMode, progressCallback) + local promise, resolution = Async.Promise.pending(); + assert((promise ~= nil) and (resolution ~= nil)); + + internet.download(url, + function (stream, contentType) + assert(resolution ~= nil); + assert(stream ~= nil); + + resolution:setSuccess(stream, contentType); + end, + function (errorMessage) + assert(resolution ~= nil); + resolution:setFailure(errorMessage); + end, + progressCallback, + cacheMode); + + return promise; +end; + +function internet.download(url, finishCallback, errorCallback, progressCallback, cacheMode) + local urlGetter = objs.objectFromHandle(_obj_newObject("TLuaURLGetter")); + + _downloadIdGenerator = _downloadIdGenerator + 1; + local idDownload = _downloadIdGenerator; + + objs.registerHandle(urlGetter.handle, urlGetter); + + urlGetter:addEventListener("OnDados", + function(streamObjectHandle, contentType) + _downloads[idDownload] = nil; + local stream = utils.streamFromHandle(streamObjectHandle); + + if finishCallback ~= nil then + finishCallback(stream, contentType); + end; + end); + + urlGetter:addEventListener("OnError", + function(errorMsg) + _downloads[idDownload] = nil; + + if errorCallback ~= nil then + errorCallback(errorMsg); + end; + end); + + urlGetter:addEventListener("OnProgress", + function(downloadedBytes, totalBytes) + + if progressCallback ~= nil then + local ret = progressCallback(downloadedBytes, totalBytes); + + if ret == false then + internet.stopDownload(idDownload); + end; + end; + end); + + if type(cacheMode) == "string" then + _obj_setProp(urlGetter.handle, "CacheMode", cacheMode); + end; + + _downloads[idDownload] = urlGetter; + _obj_invoke(urlGetter.handle, "StartDownload", url); + return idDownload; +end; + +function internet.stopDownload(downloadId) + local urlGetter = _downloads[downloadId]; + + if urlGetter ~= nil then + _obj_invoke(urlGetter.handle, "StopDownload"); + end; +end; + +local __requestsStrongReference = {}; + +function internet.newHTTPRequest(method, url) + local r = objs.objectFromHandle(_obj_newObject("TLuaHTTPRequest")); + objs.registerHandle(r.handle, r); + + if r.props == nil then + r.props = {}; + end; + + if r.eves == nil then + r.eves = {}; + end; + + if type(method) ~= "string" then + method = "GET"; + end; + + function r:getUrl() return _obj_getProp(self.handle, "URL"); end; + function r:setUrl(v) _obj_setProp(self.handle, "URL", v); end; + + function r:getMethod() return _obj_getProp(self.handle, "HTTPMethod"); end; + function r:setMethod(v) _obj_setProp(self.handle, "HTTPMethod", v); end; + + function r:setRequestHeader(header, value) _obj_invoke(self.handle, "SetRequestHeader", header, tostring(value or "")); end; + function r:getRequestHeader(header) return _obj_invoke(self.handle, "GetRequestHeader", header); end; + + function r:getResponseHeader(header) return _obj_invoke(self.handle, "GetResponseHeader", header); end; + function r:getAllResponseHeaders() return _obj_invoke(self.handle, "GetAllResponseHeaders"); end; + function r:getResponseText() return _obj_getProp(self.handle, "ResponseText"); end; + function r:getResponseStream() return utils.streamFromHandle(_obj_invokeEx(self.handle, "GetResponseStreamHandle")); end; + function r:getStatus() return _obj_getProp(self.handle, "Status"); end; + function r:getStatusText() return _obj_getProp(self.handle, "StatusText"); end; + + function r:open(openMethod, openURL) + self.method = openMethod; + self.url = openURL; + end; + + function r:send(body) + __requestsStrongReference[self] = true; -- manter uma referência forte ate o fim da requisicao + local tBody = type(body); + + if tBody == "table" then + if body.handle == nil then + body = tableToStr(body); + end; + elseif body ~= nil then + body = tostring(body); + end; + + if self.__refResponseEventId == nil then + self.__refResponseEventId = self:addEventListener("onResponse", + function() + __requestsStrongReference[self] = nil; -- Remover referencia forte + end); + end; + + if self.__refOnErrorEventId == nil then + self.__refOnErrorEventId = self:addEventListener("onError", + function() + __requestsStrongReference[self] = nil; -- Remover referencia forte + end); + end; + + _obj_invokeEx(self.handle, "Send", body); + end; + + function r:abort() _obj_invoke(self.handle, "Abort"); end; + + r.props["url"] = {setter = "setUrl", getter = "getUrl", tipo = "string"}; + r.props["method"] = {setter = "setMethod", getter = "getMethod", tipo = "string"}; + + r.props["responseText"] = {getter = "getResponseText", tipo = "string"}; + r.props["responseStream"] = {getter = "getResponseStream", tipo = "table"}; + r.props["status"] = {getter = "getStatus", tipo = "int"}; + r.props["statusText"] = {getter = "getStatusText", tipo = "string"}; + r.props["allResponseHeaders"] = {getter = "getAllResponseHeaders", tipo = "string"}; + + r.eves["onError"] = "errorMsg"; + r.eves["onResponse"] = ""; + r.eves["onSendProgress"] = "currentBytes, maxBytes"; + r.eves["onReceiveProgress"] = "currentBytes, maxBytes"; + + r.method = method; + + if url ~= nil then + r.url = url; + end; + + return r; +end; + +function internet.httpEncode(str) + return _internet_HTTPEncode(str); +end; + +function internet.httpDecode(str) + return _internet_HTTPDecode(str); +end; + +return lInternet; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/locale.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/locale.lua new file mode 100644 index 00000000..d4afe9ae --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/locale.lua @@ -0,0 +1,19 @@ +Locale = require("delayedLoad.dlua").new("localeCore.dlua"); + +function LANG(idTxt) + return Locale.lang(idTxt); +end + +function lang(idTxt) + return Locale.lang(idTxt); +end + +function tryLang(idTxt) + return Locale.tryLang(idTxt); +end + +function tryLANG(idTxt) + return Locale.tryLang(idTxt); +end + +return Locale; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/localeCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/localeCore.dlua new file mode 100644 index 00000000..cbba73cc --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/localeCore.dlua @@ -0,0 +1,99 @@ +local Objs = require("rrpgObjs.lua"); +local Locale = {}; + +function Locale.lang(txtId) + return _system_locale_lang(txtId); +end; + +function Locale.tryLang(txtId) + return _system_locale_tryLang(txtId); +end; + +function Locale.loadLangTexts(langTexts) + return _system_locale_loadLangTexts(langTexts); +end; + +function Locale.withDesiredAutoEval(callback, desiredEnabled, ...) + assert(type(callback) == 'function', "callback parameter is not a function"); + + local wasAutoEvalEnabled = Locale.getIsAutoStringEvalEnabled(); + Locale.setIsAutoStringEvalEnabled(desiredEnabled); + + local r = table.pack(pcall(callback, ...)); + + Locale.setIsAutoStringEvalEnabled(wasAutoEvalEnabled); + + if not r[1] then + reraise(r[2]); + else + return table.unpack(r, 2); + end; +end + +function Locale.withEval(callback, ...) + return Locale.withDesiredAutoEval(callback, true, ...); +end; + +function Locale.withNoEval(callback, ...) + return Locale.withDesiredAutoEval(callback, false, ...); +end; + +function Locale.getIsAutoStringEvalEnabled() + return _system_locale_getCurrentThreadAutomaticLocalizedStringEvaluation(); +end; + +function Locale.setIsAutoStringEvalEnabled(enabled) + return _system_locale_setCurrentThreadAutomaticLocalizedStringEvaluation(not not enabled); +end; + +function Locale.eval(...) + return _system_locale_eval(...); +end; + +function Locale.autoEval(...) + return _system_locale_autoEval(...); +end; + +function Locale.__createNullLocalizedTexts() + local nullTxts = {}; + + function nullTxts:lang(textId) + error("No API Support"); + end; + + function nullTxts:tryLang(textId) + return nil; + end; + + function nullTxts:loadTexts(langTexts) + end; + + function nullTxts:addText(localeId, textId, text) + end; + + return nullTxts; +end; + +function Locale.newLocalizedTexts() + local txts = Objs.objectFromHandle(_obj_newObject("TLuaLocalizedTexts")); + + function txts:addText(localeId, textId, text) + return _obj_invokeEx(self.handle, "AddText", localeId, textId, text); + end; + + function txts:lang(textId) + return _obj_invokeEx(self.handle, "Lang", textId); + end; + + function txts:loadTexts(langTexts) + return _obj_invokeEx(self.handle, "LoadTexts", langTexts); + end; + + function txts:tryLang(textId) + return _obj_invokeEx(self.handle, "TryLang", textId); + end; + + return txts; +end; + +return Locale; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/log.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/log.lua new file mode 100644 index 00000000..35d31848 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/log.lua @@ -0,0 +1,39 @@ +require("system.lua"); + +Log = {} + +function Log.haveNativeBackendSupport() + return System.checkAPIVersion(87, 3) +end; + +function Log.v(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_v(tag, msg); + end; +end; + +function Log.d(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_d(tag, msg); + end; +end; + +function Log.i(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_i(tag, msg); + end; +end; + +function Log.w(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_w(tag, msg); + end; +end; + +function Log.e(tag, msg) + if Log.haveNativeBackendSupport() then + return _system_log_e(tag, msg); + end; +end; + +return Log \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb.lua new file mode 100644 index 00000000..a292e42f --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb.lua @@ -0,0 +1,929 @@ +local objs = require("rrpgObjs.lua"); +local vhd = require("vhd"); +require("utils.lua"); +ndb = {} +NDB = ndb; + +local localNDB = {}; + +local _localOpenNDBs = {} +setmetatable(_localOpenNDBs, objs.weakMetatable); + +function localNDB.ndbFromHandle(handle) + local ctrl; + + if handle ~= nil then + ctrl = objs.tryFindFromHandle(handle); + + if ctrl ~= nil then + return ctrl; + end; + else + return nil; + end; + + ctrl = objs.objectFromHandle(handle); + ctrl.__dbFlag = true; + + objs.registerHandle(handle, ctrl); + return ctrl; +end; + +-- [[ Node class ]] -- + +localNDB.Node = objs.newClass(); + +function localNDB.Node:initialize() + rawset(self, "__nodeFlag", true); +end; + +function localNDB.Node:findChild(nodeName) + local nh = _ndb_findChild(self.handle, nodeName); + return localNDB.openNode(nh); +end; + +function localNDB.Node:getFacade() + local nodeFacade = rawget(self, "__nodeFacade"); + + if nodeFacade == nil then + nodeFacade = localNDB.newNodeFacadeFor(self); + rawset(self, "__nodeFacade", nodeFacade); + end; + + return nodeFacade; +end; + +function localNDB.Node:getAttribute(name) + return _ndb_getAttribute(self.handle, name); +end; + +function localNDB.Node:setAttribute(name, value) + return _ndb_setAttribute(self.handle, name, value); +end; + +function localNDB.Node:clearNode() + return _obj_invoke(self.handle, "ClearNode"); +end; + +function localNDB.Node:getAttributesNames() + return _ndb_getAttributesNames(self.handle); +end; + +function localNDB.Node:getAllAttributes() + return _ndb_getAllAttributes(self.handle); +end; + +function localNDB.Node:getChildCount() + return _ndb_getChildCount(self.handle); +end; + +function localNDB.Node:getChild(indice) + return localNDB.openNode(_ndb_getChild(self.handle, indice)); +end; + +function localNDB.Node:getAllChilds() + local ret = {}; + local count = self:getChildCount(); + + for i = 0, count - 1, 1 do + ret[i + 1] = self:getChild(i); + end; + + return ret; +end; + +function localNDB.Node:addChild(nodeName) + return localNDB.openNode(_ndb_addChild(self.handle, nodeName)); +end; + +function localNDB.Node:delete() + _obj_invoke(self.handle, "Delete"); +end; + +function localNDB.Node:getName() + return _ndb_getNodeName(self.handle); +end; + +function localNDB.Node:getPersistedAttributeValue(attributeName) + return _ndb_getPersistedAttributeValue(self.handle, attributeName); +end; + +function localNDB.Node:exportXML() + return _obj_invoke(self.handle, "ExportToXMLString"); +end; + +function localNDB.Node:importXML(xmlString) + return _obj_invoke(self.handle, "ImportXMLString", (tostring(xmlString)) or ""); +end; + +function localNDB.Node:getLocalID() + return _obj_getProp(self.handle, "LocalID"); +end; + +function localNDB.Node:beginUpdate() + _obj_invoke(self.handle, "BeginUpdate"); +end; + +function localNDB.Node:endUpdate() + _obj_invoke(self.handle, "EndUpdate"); +end; + +function localNDB.Node:getState() + return _obj_getProp(self.handle, "ProviderState"); +end; + +function localNDB.Node:setPermission(selKind, selId, permission, allowance) + return _obj_invokeEx(self.handle, "SetPermission", selKind, selId, permission, allowance); +end; + +function localNDB.Node:getPermission(selKind, selId, permission) + return _obj_invokeEx(self.handle, "GetPermission", selKind, selId, permission); +end; + +function localNDB.Node:testPermission(permission) + return _obj_invokeEx(self.handle, "TestPermission", permission); +end; + +function localNDB.Node:enumPermissions() + return _obj_invokeEx(self.handle, "EnumPermissions"); +end; + +function localNDB.nodeFromHandle(nodeHandle) + local node; + + if nodeHandle == nil then + return nil; + end; + + node = objs.tryFindFromHandle(nodeHandle); + + if node ~= nil then + return node; + end; + + node = localNDB.Node.fromHandle(nodeHandle); + node.__nodeDatabase = localNDB.ndbFromHandle(_ndb_getNDBHandleOfNode(nodeHandle)); + + objs.registerHandle(nodeHandle, node); + return node; +end; + +function localNDB.copyNodeToAnother(nodeDest, nodeSrc, ctxCtrl) + if nodeDest.handle == nodeSrc.handle then + return; + end; + + if ctxCtrl == nil then + ctxCtrl = {}; -- avoid circular reference + end; + + if ctxCtrl[nodeSrc.handle] then + return; + else + ctxCtrl[nodeSrc.handle] = true; + end; + + nodeDest:beginUpdate(); + + tryFinally( + function() + nodeDest:clearNode(); + + local allAtts = nodeSrc:getAllAttributes(); + + for k, v in pairs(allAtts) do + localNDB.assignPropValueToNode(nodeDest, k, v); + end; + + local allChilds = nodeSrc:getAllChilds(); + local newChild, srcChild; + + for _, v in pairs(allChilds) do + srcChild = v; + + if not ctxCtrl[srcChild.handle] then + newChild = nodeDest:addChild(srcChild:getName()); + localNDB.copyNodeToAnother(newChild, srcChild, ctxCtrl); + end; + end; + end, + + function() + nodeDest:endUpdate(); + end); +end; + +function localNDB.copyTableToNode(nodeDest, tableValue) + nodeDest:clearNode(); + + for k, v in pairs(tableValue) do + localNDB.assignPropValueToNode(nodeDest, k, v); + end; +end; + +function localNDB.assignPropValueToNode(node, prop, value) + prop = tostring(prop); + + -- Limpando propriedade + if value == nil then + _obj_invoke(node.handle, "RemoveAtributeAndChildNodes", prop); + return; + end; + + if type(value) == "function" then + -- Tipo inválido para setar + require("locale.lua"); + error(string.format(lang("sdk3.err.ndb.functionAssign"), tostring(prop))); + return; + end; + + if type(value) == "table" then + -- Setando um Table/Child Node + _obj_invoke(node.handle, "BeginUpdate"); + + node:setAttribute(prop, nil); -- remover atributo de mesmo nome se existir + local childNode = node:findChild(prop); + + if childNode == nil then + childNode = node:addChild(prop); -- Nodo não existe, vamos criar um + end; + + if rawget(value, "__nodeFlag") then + -- é um node + localNDB.copyNodeToAnother(childNode, value); + elseif rawget(value, "__nodeFacadeFlag") then + -- é um node facade + localNDB.copyNodeToAnother(childNode, value.__node); + else + -- Aparentemente é um table comum + localNDB.copyTableToNode(childNode, value); + end; + + _obj_invoke(node.handle, "EndUpdate"); + else + -- Setando um Atributo + --_obj_invoke(node.handle, "BeginUpdate"); + _obj_invoke(node.handle, "RemoveChildNodes", prop); -- remover todos os child nodes de mesmo nome + node:setAttribute(prop, value); + --_obj_invoke(node.handle, "EndUpdate"); + end; +end; + +local NodeFacadeMetatable = { + --[[ getter padrão de propriedades dos objetos. Chamado quando tentou gettar uma propriedade que não existe ]]-- + __index = function(table, key) + local v = rawget(table, key); + + if (v ~= nil) then + return v; + end; + + local node = rawget(table, "__node"); + + if node ~= nil then + local childNode = node:findChild(key); + + if childNode ~= nil then + -- Achamos um child node com este nome. + return childNode:getFacade(); + end; + + return node:getAttribute(key); + end; + + return nil; + end, + + --[[ setter padrão de propriedades dos objetos. Chamado quando tentou settar uma propriedade que não existe ]]-- + __newindex = function(table, key, value) + local node = rawget(table, "__node"); + + if node ~= nil then + localNDB.assignPropValueToNode(node, key, value); + end; + end, +}; + +function localNDB.newNodeFacadeFor(nodeObj) + local nodeFacade = {__node = nodeObj, __nodeFacadeFlag = true}; + setmetatable(nodeFacade, NodeFacadeMetatable); + return nodeFacade; +end; + +function localNDB.openNode(nodeHandle) + local nodeObj; + + if nodeHandle == nil then + return nil; + end; + + nodeObj = objs.tryFindFromHandle(nodeHandle); + + if nodeObj == nil then + nodeObj = localNDB.nodeFromHandle(nodeHandle); + end; + + return nodeObj; +end; + +function localNDB.openNodeFacade(nodeHandle) + local nodeObj = localNDB.openNode(nodeHandle); + + if nodeObj ~= nil then + return nodeObj:getFacade(); + else + return nil; + end; +end; + +function localNDB.getNodeObjectFromFacade(nodeFacade) + return rawget(nodeFacade, "__node"); +end; + +function _export_ndb_openNodeFacade(nodeHandle) + return localNDB.openNodeFacade(nodeHandle); +end; + +-- Funções exportadas + +function ndb.openNodeDatabaseFromHandle(nodeDatabaseHandle) + return localNDB.ndbFromHandle(nodeDatabaseHandle); +end; + +function ndb.load(fileName, userName) + local expandedName = vhd.expandFileName(fileName); + + if #expandedName > 0 then + if string.sub(expandedName, 1, 1) ~= "/" then + expandedName = "/" .. expandedName; + end; + end; + + if type(userName) ~= "string" then + userName = ""; + end; + + local openDB = _localOpenNDBs[expandedName]; + + if openDB ~= nil then + return ndb.getRoot(openDB); + end; + + openDB = ndb.openNodeDatabaseFromHandle(_obj_newObject("TLocalLuaNodeDatabase")); + _obj_invoke(openDB.handle, "SetupLocalFile", expandedName, userName); + _localOpenNDBs[expandedName] = openDB; + return ndb.getRoot(openDB); +end; + +function ndb.newMemNodeDatabase(initialContent) + local openDB = ndb.openNodeDatabaseFromHandle(_obj_newObject("TLuaMemoryNodeDatabase", initialContent)); + return ndb.getRoot(openDB); +end; + +function ndb.getRoot(node) + if type(node) ~= "table" then + return nil; + end; + + if node.__nodeFlag then + return localNDB.openNodeFacade(_ndb_getTheRoot(node.handle)); + elseif node.__nodeFacadeFlag then + return ndb.getRoot(rawget(node, "__node")); + elseif node.__dbFlag then + return localNDB.openNodeFacade(_ndb_getRoot(node.handle)); + else + return nil; + end; +end; + +function ndb.getParent(node) + if type(node) ~= "table" then + return nil; + end; + + if node.__nodeFlag then + return localNDB.openNodeFacade(_ndb_getParent(node.handle)); + elseif node.__nodeFacadeFlag then + return ndb.getParent(rawget(node, "__node")); + else + return nil; + end; +end; + +function ndb.openNodeFacade(nodeHandle) + return localNDB.openNodeFacade(nodeHandle); +end; + +function ndb.getChildNodes(nodeObj) + if (nodeObj == nil) then + return {}; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local nodesCtrls = node:getAllChilds(); + local ret = {}; + + for i = 1, #nodesCtrls, 1 do + ret[i] = nodesCtrls[i]:getFacade(); + end; + + return ret; + else + return {}; + end; +end; + +function ndb.getAttributes(nodeObj) + if (nodeObj == nil) then + return {}; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getAllAttributes(); + else + return {}; + end; +end; + +function ndb.isNodeObject(value) + if type(value) ~= "table" then + return false; + end; + + return rawget(value, "__nodeFacadeFlag"); +end; + +function ndb.getNodeHandle(nodeObject) + if ndb.isNodeObject(nodeObject) then + return nodeObject.__node.handle; + else + return nil; + end; +end; + +function ndb.createChildNode(nodeObj, childName) + if (nodeObj == nil) then + return nil; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:addChild(childName):getFacade(); + else + return nil; + end; +end; + +function ndb.deleteNode(nodeObj) + if (nodeObj == nil) then + return; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:delete(); + end; +end; + +function ndb.clearNode(nodeObj) + if (nodeObj == nil) then + return; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:clearNode(); + end; +end; + +function ndb.getNodeName(nodeObj) + if (nodeObj == nil) then + return nil; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getName(); + else + return nil; + end; +end; + +function ndb.getPersistedAttributeValue(nodeObj, attributeName) + if (nodeObj == nil) then + return nil; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getPersistedAttributeValue(attributeName); + else + return nil; + end; +end; + +function ndb.exportXML(nodeObj) + if (nodeObj == nil) then + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.exportToXML.invalidPar")); + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:exportXML(); + else + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.exportToXML.invalidPar")); + end; +end; + +function ndb.importXML(nodeObj, xmlString) + if (nodeObj == nil) then + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.importXML.invalidPar")); + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:importXML(xmlString); + else + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.importXML.invalidPar")); + end; +end; + +function ndb.copy(destNodeObj, srcNodeObj) + if (destNodeObj == nil) then + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.copy.invalidPar2")); + end; + + local srcNode; + local dstNode = localNDB.getNodeObjectFromFacade(destNodeObj); + + if srcNodeObj ~= nil then + srcNode = localNDB.getNodeObjectFromFacade(srcNodeObj); + else + srcNode = nil; + end; + + if dstNode ~= nil then + if srcNode ~= nil then + local xmlString = srcNode:exportXML(); + dstNode:importXML(xmlString); + else + dstNode:clearNode(); + end; + else + local aLocale = require("locale.lua"); + error(aLocale.lang("sdk3.err.ndb.func.copy.invalidPar2")); + end; +end; + +function ndb.beginUpdate(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:beginUpdate(); + end; + end; +end; + +function ndb.endUpdate(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + node:endUpdate(); + end; + end; +end; + +function ndb.getState(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return node:getState(); + end; + end; + + return "closed"; +end; + +local _observerBib = nil; + +function ndb.newObserver(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + if _observerBib == nil then + _observerBib = require("ndb_observer.dlua"); + end; + + return _observerBib.newObserver(node.handle, nodeObj); + end; + end; + + return nil; +end; + +function ndb.setPermission(node, selKind, selId, permission, allowance) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:setPermission(tostring(selKind), tostring(selId), tostring(permission), allowance); + end; + end; +end; + +function ndb.getPermission(node, selKind, selId, permission) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:getPermission(tostring(selKind), tostring(selId), tostring(permission)); + end; + end; + + return nil; +end; + +function ndb.testPermission(node, permission) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:testPermission(tostring(permission)); + end; + end; + + return false; +end; + +function ndb.enumPermissions(node) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + return nodeObj:enumPermissions(); + end; + end; + + return {}; +end; + +function ndb.resetPermissions(node) + if node ~= nil then + local nodeObj = localNDB.getNodeObjectFromFacade(node); + + if nodeObj ~= nil then + _obj_invoke(nodeObj.handle, "ResetPermissions"); + end; + end; + + return {}; +end; + +local _transactionBib = nil; + +function ndb.newTransaction(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + if _transactionBib == nil then + _transactionBib = require("ndb_transaction.dlua"); + end; + + return _transactionBib.newTransaction(node.handle, nodeObj); + end; + end; + + return nil; +end; + +function ndb.pushTransaction(nodeObj, transaction) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local trHandle; + + if transaction ~= nil then + trHandle = transaction.handle or 0; + else + trHandle = 0; + end; + + _obj_invoke(node.handle, "PushTransaction", trHandle); + end; + end; +end; + +function ndb.popTransaction(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + _obj_invoke(node.handle, "PopTransaction"); + end; + end; +end; + +function ndb.getServerUTCTime(nodeObj) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + return _obj_getProp(node.handle, "ServerUTCTime"); + end; + end; +end; + +function ndb.editPermissions(nodeObj) + if nodeObj == nil then + return; + end; + + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local plugins = require("plugins.lua"); + local ndbmodule = "RRPG.FIRECAST.FMXModule"; + plugins.sendPM(ndbmodule, "ndbHost:editPermissions", {localNodeID=node:getLocalID()}, nil, nil); + end; +end; + +function ndb.loadNodeFromLocalID(localNodeID) + return _ndb_tryLoadNodeFromLocalID(localNodeID); +end; + +local _Serializer = nil; + +function ndb.broadcastMessage(nodeObj, messageId, message, loopBack) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + if _Serializer == nil then + _Serializer = require("utils.serializer.dlua"); + end; + + if loopBack == nil then + loopBack = false; + end; + + _obj_invokeEx(node.handle, "LUABroadcastMessage", messageId, _Serializer.serialize(message), loopBack); + end; + end; +end; + +function ndb.newBroadcastListener(nodeObj, messageId, callback) + if nodeObj ~= nil then + local node = localNDB.getNodeObjectFromFacade(nodeObj); + + if node ~= nil then + local obj = objs.objectFromHandle(_obj_newObject("TLuaNDBBroadcastReceiver")); + obj.eves = obj.eves or {}; + obj.eves["onReceiveBroadcast"] = "sender, messageId, messageText"; + + _obj_invoke(obj.handle, "SetupReceiver", node.handle, messageId or ""); + + obj.onReceiveBroadcast = function(sender, returnedMessageId, messageText) + if callback ~= nil then + if _Serializer == nil then + _Serializer = require("utils.serializer.dlua"); + end; + + local success, message = pcall(_Serializer.deserialize, messageText); + + if not success then + message = messageText; + end; + + callback(sender, returnedMessageId, message); + end; + end; + return obj; + end; + end; +end; + +function ndb.onReady(nodeObj, callback, failCallback) + local function scheduleFailReturn() + if failCallback ~= nil then + setTimeout(failCallback, 1, nil); + end; + end; + + if nodeObj == nil then + scheduleFailReturn(); + return; + end; + + local state = ndb.getState(nodeObj); + + if state == "open" then + -- Already loaded + + if callback ~= nil then + setTimeout(callback, 1, nodeObj); + end; + + return; + end; + + -- Not loaded yet, letz monitor + local nodeInternObj = localNDB.getNodeObjectFromFacade(nodeObj); + local ndbObj = localNDB.ndbFromHandle(_ndb_getNDBHandleOfNode(nodeInternObj.handle)); + local jaNotificou = false; + local listenerProvider = nil; + local listenerLoaded = nil; + + local function checkState() + if not jaNotificou then + state = ndb.getState(nodeObj); + + if state == "open" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, nodeObj); + end; + elseif state == "closed" then + jaNotificou = true; + scheduleFailReturn(); + end; + + if jaNotificou then + ndbObj:removeEventListener(listenerProvider); + ndbObj:removeEventListener(listenerLoaded); + end; + end; + end; + + listenerProvider = ndbObj:addEventListener("OnProviderStateChange", checkState); + listenerLoaded = ndbObj:addEventListener("OnLoaded", checkState); + + checkState(); +end; + +-- OVERRIDE de funções nativas para funcionar com o NDB + +local oldPairsFunc = pairs; +local oldIPairsFunc = ipairs; + +local function _prepareNodeFacadePairsState(nodeFacade) + local node = nodeFacade.__node; + local state = node:getAllAttributes(); + + local childs = node:getAllChilds(); + + for _, v in oldPairsFunc(childs) do + local name = v:getName(); + local nodeForName = node:findChild(name); + + if nodeForName ~= nil then + state[name] = nodeForName; + end; + end; + + return state; +end; + +function pairs(obj) + if (obj ~= nil) and rawget(obj, "__nodeFacadeFlag") then + -- Node Façade + local state = _prepareNodeFacadePairsState(obj); + return oldPairsFunc(state); + else + return oldPairsFunc(obj); + end; +end; + +function ipairs(obj) + if (obj ~= nil) and rawget(obj, "__nodeFacadeFlag") then + -- Node Façade + local state = _prepareNodeFacadePairsState(obj); + return oldIPairsFunc(state); + else + return oldIPairsFunc(obj); + end; +end; + +return ndb; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_observer.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_observer.dlua new file mode 100644 index 00000000..e7a80b54 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_observer.dlua @@ -0,0 +1,51 @@ +local objs = require("rrpgObjs.lua"); +local nO = {}; + +local _observerProps = {}; +local _observerEves = {}; + +_observerProps["enabled"] = {setter = "setEnabled", getter = "getEnabled", tipo="bool"}; + +_observerEves["onChildAdded"] = "node"; +_observerEves["onChildRemoved"] = "node"; +_observerEves["onDeepChildAdded"] = "node"; +_observerEves["onDeepChildRemoved"] = "node"; +_observerEves["onDeleted"] = "node"; +_observerEves["onChanged"] = "node, attribute, oldValue"; +_observerEves["onDeepChanged"] = "node, attribute, oldValue"; +_observerEves["onUserChanged"] = "node, attribute, oldValue"; +_observerEves["onDeepUserChanged"] = "node, attribute, oldValue"; +_observerEves["onPersistedChanged"] = "node, attribute, oldValue"; +_observerEves["onDeepPersistedChanged"] = "node, attribute, oldValue"; +_observerEves["onPermissionListChanged"] = "node"; +_observerEves["onDeepPermissionListChanged"] = "node"; +_observerEves["onFinalPermissionsCouldBeChanged"] = "node"; +_observerEves["onStateChanged"] = "node"; + +local function _observerFromHandle(handle) + local obj = objs.tryFindFromHandle(handle); + + if obj ~= nil then + return obj; + end; + + obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + + function obj:getEnabled() return _obj_getProp(self.handle, "Enabled"); end; + function obj:setEnabled(v) _obj_setProp(self.handle, "Enabled", v); end; + + + obj.props = _observerProps; + obj.eves = _observerEves; + return obj; +end; + +function nO.newObserver(nodeHandle, nodeObj) + local observer = _observerFromHandle(_obj_newObject("TLuaNodeObserver")); + _obj_invokeEx(observer.handle, "SetNodeHandle", nodeHandle); + rawset(observer, "node", nodeObj); + return observer; +end; + +return nO; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_transaction.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_transaction.dlua new file mode 100644 index 00000000..6ea1b512 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/ndb_transaction.dlua @@ -0,0 +1,53 @@ +local objs = require("rrpgObjs.lua"); +local nO = {}; + +local _transactionProps = {}; +local _transactionEves = {}; +local _transactionMethods = {}; + +function _transactionMethods.commit(tr) + _obj_invoke(tr.handle, "Commit"); +end; + +function _transactionMethods.rollback(tr) + _obj_invoke(tr.handle, "Rollback"); +end; + +function _transactionMethods.createUndoData(tr) + local handle = _obj_invoke(tr.handle, "CreateUndoData"); + local obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + return obj; +end; + +function _transactionMethods.applyUndoData(tr, undoData) + _obj_invoke(tr.handle, "ApplyUndoData", undoData.handle); +end; + +local function _transactionFromHandle(handle) + local obj = objs.tryFindFromHandle(handle); + + if obj ~= nil then + return obj; + end; + + obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + + for k, v in pairs(_transactionMethods) do + rawset(obj, k, v); + end; + + obj.props = _transactionProps; + obj.eves = _transactionEves; + return obj; +end; + +function nO.newTransaction(nodeHandle, nodeObj) + local transaction = _transactionFromHandle(_obj_newObject("TLuaNodeTransaction")); + _obj_invokeEx(transaction.handle, "InitializeFromNodeHandle", nodeHandle); + rawset(transaction, "node", nodeObj); + return transaction; +end; + +return nO; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/plugins.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/plugins.lua new file mode 100644 index 00000000..6c014411 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/plugins.lua @@ -0,0 +1,6 @@ +local rrpg = require("rrpg.lua"); +local plugins = require("delayedLoad.dlua").new("pluginsCore.dlua"); + +rrpg.plugins = plugins; +rrpg.Plugins = plugins; +return plugins; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/pluginsCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/pluginsCore.dlua new file mode 100644 index 00000000..520efd1e --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/pluginsCore.dlua @@ -0,0 +1,243 @@ +require("rrpgObjs.lua"); +require("utils.lua"); +require("rrpg.lua"); +local plugins = {}; +local serializer = nil; + +function plugins.getInstalledDataTypes() + local retorno = _rrpg_plugins_getInstalledDataTypes(); + + if type(retorno) == "table" then + return retorno; + else + return {}; + end; +end; + +function plugins.getInstalledPlugins() + local retorno = _rrpg_plugins_getInstalledPlugins(); + + if type(retorno) == "table" then + return retorno; + else + return {}; + end; +end; + +function plugins.getRPKDetails(stream) + if type(stream) == "table" then + return _rrpg_plugins_getPackageInfos(stream.handle); + else + return nil; + end; +end; + +function plugins.installPlugin(stream, ignoreIfOlder) + if type(stream) ~= "table" then + return false, "Invalid stream parameter"; + end; + + ignoreIfOlder = not (not ignoreIfOlder); + return _rrpg_plugins_installPluginPackage(stream.handle, ignoreIfOlder); +end; + +function plugins.uninstallPlugin(moduleId) + return _rrpg_plugins_uninstallPluginPackage(moduleId); +end; + +local pmListenersByName = {}; +local pmGeneratorId = 0; +local pmPrefixID = _rrpg_generateUniqueStrID() .. "_"; +local pmSent = {}; + +local function __convertIncomingPMData(data) + if serializer == nil then + serializer = require("utils.serializer.dlua"); + end; + + return serializer.deserialize(data); +end; + +local function __convertOutgoingPMData(data) + if serializer == nil then + serializer = require("utils.serializer.dlua"); + end; + + return serializer.serialize(data); +end; + +function plugins.sendPM(moduleId, pmName, data, returnCallback, failureCallback) + pmGeneratorId = pmGeneratorId + 1; + local esteId = pmPrefixID .. tostring(pmGeneratorId); + local pmObject = {}; + pmObject.returnCallback = returnCallback; + pmObject.failureCallback = failureCallback; + + --[[if type(data) ~= "table" then + data = {data=data}; + end;]] + + data = __convertOutgoingPMData(data); + pmSent[esteId] = pmObject; + + local ret, msg = _rrpg_plugins_sendPM(esteId, moduleId, pmName, data); + + if not ret then + pmSent[esteId] = nil; + + if failureCallback ~= nil then + failureCallback(msg); + end; + end; +end; + +function plugins.replyPM(message, data) + if not message.__replied then + message.__replied = true; + _rrpg_plugins_sendPMReply(message.__msgId, message.moduleId, true, __convertOutgoingPMData(data)); + end; +end; + +function plugins.replyPMFailure(message, failureData) + if not message.__replied then + message.__replied = true; + _rrpg_plugins_sendPMReply(message.__msgId, message.moduleId, false, __convertOutgoingPMData(failureData)); + end; +end; + +function plugins.setLatePMReply(message) + message.__isLateReply = true; +end; + +function plugins.listenPM(pmName, callback) + local listener = pmListenersByName[pmName]; + + if listener ~= nil then + listener.callback = callback; + return pmName; + end; + + listener = {}; + listener.callback = callback; + listener.pmName = pmName; + pmListenersByName[pmName] = listener; + return pmName; +end; + +function plugins.unlistenPM(listenerId) + local listener = pmListenersByName[listenerId]; -- listenerId é o pmName + + if listener ~= nil then + pmListenersByName[listenerId] = nil; + listener.callback = nil; + end; +end; + +function plugins.requirePlugin(moduleId) + return _rrpg_plugins_requirePlugin(moduleId); +end; + +function __export_plugins_handlePMResponse(msgId, success, data) + local pmObject = pmSent[msgId]; + + if pmObject ~= nil then + pmSent[msgId] = nil; + data = __convertIncomingPMData(data); + + if success then + if pmObject.returnCallback ~= nil then + pmObject.returnCallback(data); + end; + else + if pmObject.failureCallback ~= nil then + pmObject.failureCallback(data); + end; + end; + end; +end; + +function __export_plugins_handlePMResponse(msgId, success, data) + local pmObject = pmSent[msgId]; + + if pmObject ~= nil then + pmSent[msgId] = nil; + data = __convertIncomingPMData(data); + + if success then + if pmObject.returnCallback ~= nil then + pmObject.returnCallback(data); + end; + else + if pmObject.failureCallback ~= nil then + pmObject.failureCallback(data); + end; + end; + + return true; + else + return false; + end; +end + +function __export_plugins_handleIncomingPM(fromModuleId, msgId, pmName, data) + local listener = pmListenersByName[pmName]; + + if listener ~= nil and listener.callback ~= nil then + local message = {}; + data = __convertIncomingPMData(data); + + if type(data) ~= "table" then + data = {data=data}; + end; + + for k, v in pairs(data) do + message[k] = v; + end; + + message.moduleId = fromModuleId; + message.__msgId = msgId; + + setTimeout( + function() + local r, ret = pcall(listener.callback, message); + + if r then + if not message.__isLateReply and not message.__replied then + plugins.replyPM(message, ret); + end; + else + plugins.replyPMFailure(message, ret); + end; + end, 0); + + return true; + else + return false; + end; +end + +function plugins.getInstalledTablesDock() + return _rrpg_plugins_getInstalledTablesDock(); +end; + +function plugins.activateTablesDock(mesa, moduleId, name, storedInfo) + return _rrpg_plugins_activateTablesDock(mesa.objectID, moduleId, name, storedInfo or ""); +end; + +function plugins.deactivateTablesDock(mesa, moduleId, name) + return _rrpg_plugins_deactivateTablesDock(mesa.objectID, moduleId, name); +end; + +function plugins.getIsTablesDockActive(mesa, moduleId, name) + return _rrpg_plugins_getIsTablesDockActive(mesa.objectID, moduleId, name); +end; + +function plugins.getActiveTablesDockStoredInfo(mesa, moduleId, name) + return _rrpg_plugins_getActiveTablesDockStoredInfo(mesa.objectID, moduleId, name); +end; + +function plugins.getListOfActiveTablesDockOnMesa(mesa) + return _rrpg_plugins_getListOfActiveTablesDockOnMesa(mesa.objectID); +end; + +return plugins; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpg.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpg.lua new file mode 100644 index 00000000..0e7300c4 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpg.lua @@ -0,0 +1,442 @@ +require("rrpgEvents.lua"); +local ndb = require("ndb.lua"); +local objs = require("rrpgObjs.lua"); +local rrpgWrappers = require("rrpgWrappers.lua"); +local Async = require("async.lua") + +--[[ API do RRPG ]]-- + +rrpg = objs.objectFromHandle(_obj_newObject("TRRPGMainWrapper")); +RRPG = rrpg; +Firecast = rrpg; + +local localRRPG = rrpg; +objs.registerHandle(rrpg.handle); + +rawset(rrpg, "listeners", {generator = 0}); +rawset(rrpg, "dataTypes", {}); +rawset(rrpg, "forms", {}); +rawset(rrpg, "props", {}); + +function rrpg:getMesas() + local hs = _rrpg_GetMesasIDs(); + local mesas = {}; + local idx = 1; + + for i = 1, #hs, 1 do + local mesaObj = localRRPG.contextObjectFromID(hs[i]); + + if (mesaObj ~= nil) then + mesas[idx] = mesaObj; + idx = idx + 1; + end; + end + + return mesas; +end; + +local propsRolagem = { + possuiAlgumDado = {getter="getPossuiAlgumDado", tipo="bool"}, + isRolado = {getter="getIsRolado", tipo="bool"}, + resultado = {getter="getResultado", tipo="int"}, + asString = {getter="getAsString", tipo="string"}, + tipo = {getter="getTipo", tipo="enum", + values={"direta", "storyteller"}} +}; + +local function newRolagemObject() + local rolObj = objs.objectFromHandle(_obj_newObject("TRRPGLuaRolagem")); + + function rolObj:getTipo() return _obj_getProp(self.handle, "TipoRolagem"); end; + + function rolObj:_readOps() + local nOps = {}; + local idxAtual = 1; + local rolado = _obj_getProp(self.handle, "IsRolado"); + + _obj_invoke(self.handle, "NavigatorBegin"); + + while (not _obj_getProp(self.handle, "IsNavigatorEOF")) do + local sOp = {}; + sOp.tipo = string.lower(_obj_getProp(self.handle, "NavigatorTipoOperacao")); + + if sOp.tipo == "dado" then + sOp.quantidade = _obj_getProp(self.handle, "NavigatorDadosQuantidade"); + local faceStr = _obj_getProp(self.handle, "NavigatorDadosFace"); + local faceAsNumber = tonumber(faceStr); + + if faceAsNumber ~= nil then + sOp.face = faceAsNumber; + else + sOp.face = faceStr; + end; + + if rolado then + sOp.resultados = _obj_getProp(self.handle, "NavigatorGetResultadoDados"); + else + sOp.resultados = {}; + end; + elseif sOp.tipo == "comparacao" then + sOp.comparacao = _obj_getProp(self.handle, "NavigatorComparacao"); + elseif sOp.tipo == "imediato" then + sOp.valor = _obj_getProp(self.handle, "NavigatorGetImediatoValue"); + end; + + nOps[idxAtual] = sOp; + idxAtual = idxAtual + 1; + + _obj_invoke(self.handle, "NavigatorNext"); + end + + rawset(self, "ops", nOps); + end; + + function rolObj:interpretarString(str) local ret = _obj_invoke(self.handle, "InterpretarString", str or ""); self:_readOps(); return ret; end; + + function rolObj:getPossuiAlgumDado() + local lOps = rawget(self, "ops"); + + if lOps ~= nil then + for i, k in pairs(lOps) do + if k.tipo == "dado" then + return true; + end; + end; + end; + + return false; + end; + + function rolObj:getIsRolado() return _obj_getProp(self.handle, "IsRolado"); end; + function rolObj:getResultado() return _obj_getProp(self.handle, "Resultado"); end; + function rolObj:getAsString() return _obj_getProp(self.handle, "RolagemAsStr"); end; + + function rolObj:concatenar(rolDir) + local rolDirObj; + + if type(rolDir) == "string" then + rolDirObj = localRRPG.interpretarRolagem(rolDir); + elseif type(rolDir) == "table" then + rolDirObj = rolDir; + elseif type(rolDir) == "number" then + rolDirObj = localRRPG.interpretarRolagem(tostring(rolDir)); + else + error("Cant concatenate rolls with the type " .. type(rolDir)); + end; + + local ret = _obj_invoke(self.handle, "Concatenar", rolDirObj.handle); + + if ret then + self:_readOps(); + end; + + return self; + end; + + function rolObj:rolarLocalmente() _obj_invoke(self.handle, "RolarLocalmente"); self:_readOps(); end; + function rolObj:loadFromBase64EncodedString(str) _obj_invoke(self.handle, "LoadFromBase64EncodedString", str); self:_readOps(); end; + + rolObj.props = propsRolagem; + objs.registerHandle(rolObj.handle, rolObj); + return rolObj; +end; + +function rrpg.interpretarRolagem(stringDaRolagem) + local rolObj = newRolagemObject(); + rolObj:interpretarString(stringDaRolagem); + return rolObj; +end; + +function rrpg.loadRolagemFromBase64EncodedString(encodedString) + local rolObj = newRolagemObject(); + rolObj:loadFromBase64EncodedString(encodedString); + return rolObj; +end + +function rrpg.contextObjectFromID(objectID) + return rrpgWrappers.contextObjectFromID(objectID); +end; + +function rrpg.objectFromID(objectID) + return localRRPG.contextObjectFromID(objectID); +end; + +function rrpg.getMesaFromNodeDataBase() +end; + +function rrpg.getMesaFromSheet(sheet) + return rrpg.getMesaFromNodeDataBase(sheet); +end; + +function rrpg.findMesa(codigoInterno) + local mesas = rrpg.getMesas(); + + for i = 1, #mesas, 1 do + local mesa = mesas[i]; + + if mesa.codigoInterno == codigoInterno then + return mesa; + end; + end; + + return nil; +end; + +function rrpg.getMesaDe(object) + if type(object) == "number" then + return rrpg.findMesa(object); + end; + + if (type(object) ~= "table") then + return nil; + end; + + local handle = rawget(object, "handle"); + local mesaObjectID; + + if handle == nil then + if ndb.isNodeObject(object) then + handle = ndb.getNodeHandle(object); + end; + end; + + if handle ~= nil then + mesaObjectID = _rrpg_tryGetMesaObjectIDRelatedToHandle(handle); + + if (mesaObjectID ~= nil) then + mesaObjectID = tonumber(mesaObjectID); + end; + + if mesaObjectID ~= nil then + return rrpg.objectFromID(mesaObjectID); + end; + end; + + return nil; +end; + +function rrpg.getBibliotecaItemDe(object) + if (type(object) ~= "table") then + return nil; + end; + + local handle = rawget(object, "handle"); + local bibObjectID; + + if handle == nil then + if ndb.isNodeObject(object) then + handle = ndb.getNodeHandle(object); + end; + end; + + if handle ~= nil then + bibObjectID = _rrpg_tryGetBibItemObjectIDRelatedToHandle(handle); + + if (bibObjectID ~= nil) then + bibObjectID = tonumber(bibObjectID); + end; + + if bibObjectID ~= nil then + return rrpg.objectFromID(bibObjectID); + end; + end; + + return nil; +end; + +function rrpg.getPersonagemDe(object) + local ctxObj = localRRPG.getBibliotecaItemDe(object); + + if (ctxObj ~= nil) and (ctxObj:isType("personagem")) then + return ctxObj; + else + return nil; + end; +end; + +function rrpg.getCurrentUser() + return _rrpg_getCurrentUser(); +end; + +function rrpg.ouvir(eventos) + if (eventos == nil) then + return; + end + + for k, v in pairs(eventos) do + if (type(v == "function")) then + local t = localRRPG.listeners[k]; + + if (t == nil) then + t = {}; + localRRPG.listeners[k] = t; + end; + + localRRPG.listeners.generator = localRRPG.listeners.generator + 1; + t[localRRPG.listeners.generator] = v; + + _rrpg_KnownEvent(k); + end + end; +end + +function rrpg.on(eventName, callbackFunction) + local tabela = {}; + tabela[eventName] = callbackFunction; + rrpg.ouvir(tabela); +end; + +function on(eventName, callbackFunction) + rrpg.on(eventName, callbackFunction); +end; + +function rrpg.dispatch(eventName, ...) + local t = localRRPG.listeners[eventName]; + + if (t == nil) then + return; + end; + + for k,v in pairs(t) do + v(...); + end; +end + +function rrpg.registrarDataType(dt) + if type(dt) == 'table' then + if ((dt.dataType ~= nil) and (dt.dataType ~= "")) then + localRRPG.dataTypes[dt.dataType] = dt; + _rrpg_DataTypes_Registrar(dt); + end; + end; +end; + +function rrpg.registrarForm(frm) + if type(frm) == 'table' then + if (frm.name ~= nil) then + localRRPG.forms[frm.name] = frm; + _rrpg_Forms_RegisterForm(frm); + end; + end; +end; + +function rrpg.registrarSpecialForm(frm) + if (type(frm) == 'table') and (frm.name ~= nil) then + _rrpg_Forms_RegistrarSpecial(frm); + end; +end; + +local __registeredToolButtons = nil; + +function rrpg.registerChatToolButton(params) + if type(params) ~= "table" then + error("registerChatToolButton: params must be a table"); + end; + + local regClass = objs.objectFromHandle(_obj_newObject("TRRPGLuaRegisteredChatToolButton")); + objs.registerHandle(regClass.handle); + + regClass.eves = {}; + regClass.eves["onCallback"] = ""; + + + if params.hint ~= nil then + _obj_setProp(regClass.handle, "Hint", params.hint); + end; + + _obj_setProp(regClass.handle, "IconURL", params.icon); + + local p = tonumber(params.priority); + + if p ~= nil then + _obj_setProp(regClass.handle, "Priority", math.floor(p)); + end; + + local group = tostring(params.group) or ""; + + if group ~= "" then + _obj_setProp(regClass.handle, "Group", tostring(params.group) or ""); + + p = tonumber(params.groupPriority); + + if p ~= nil then + _obj_setProp(regClass.handle, "GroupPriority", math.floor(p)); + end; + end; + + + if params.callback ~= nil then + regClass.onCallback = params.callback; + end; + + _obj_invoke(regClass.handle, "Activate"); + + if __registeredToolButtons == nil then + __registeredToolButtons = {}; + end; + + __registeredToolButtons[regClass.handle] = regClass; -- strong reference + return regClass.handle; +end; + +function rrpg.unregisterChatToolButton(toolButtonId) + if __registeredToolButtons ~= nil then + local regClass = __registeredToolButtons[toolButtonId]; + + if regClass ~= nil then + __registeredToolButtons[toolButtonId] = nil; + _obj_invoke(regClass.handle, "Deactivate"); + end; + end; +end; + +function rrpg.asyncOpenUserNDB(name, options) + if not Async.haveNativeBackendSupport() or not System.checkAPIVersion(87, 3) then + return Async.Promise.withError("No API Support"); + end; + + return rrpgWrappers.__serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_rrpg_Session_asyncOpenUserNDB(name, options)); + end); +end; + +function rrpg.parseTalemark(text, talemarkOptions) + if System.checkAPIVersion(87, 4) then + return _obj_invokeEx(localRRPG.handle, 'ParseTalemark', text, talemarkOptions); + else + return {type="root"}; + end; +end; + +rrpg.messaging = require("rrpgEventMessages.lua"); + +rrpg.props["mesas"] = {getter="getMesas", tipo="table"}; + +-- Alias functions +rrpg.listen = rrpg.messaging.listen; +rrpg.listenOnce = rrpg.messaging.listenOnce; +rrpg.unlisten = rrpg.messaging.unlisten; +rrpg.groupOnceListeners = rrpg.messaging.groupOnceListeners; +rrpg.Messaging = rrpg.messaging; +rrpg.parseRoll = rrpg.interpretarRolagem; +rrpg.findRoom = rrpg.findMesa; +rrpg.getRoomOf = rrpg.getMesaDe; +rrpg.getRooms = rrpg.getMesas; +rrpg.getLibraryItemOf = rrpg.getBibliotecaItemDe; +rrpg.getCharacterOf = rrpg.getPersonagemDe; + +-- Alias properties +rrpg.props["rooms"] = rrpg.props["mesas"]; + +RRPG = rrpg; + + +-- Exported API to the Firecast Executable + +function __rrpg_loadRolagemFromBase64EncodedString(encodedString) + return rrpg.loadRolagemFromBase64EncodedString(encodedString); +end; + +require("rrpgEventMessagesAdapters.lua"); +return rrpg; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgDialogs.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgDialogs.lua new file mode 100644 index 00000000..9ea447c5 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgDialogs.lua @@ -0,0 +1,519 @@ +local objs = require("rrpgObjs.lua"); +local Async = require("async.lua"); + +local lDialogs = objs.objectFromHandle(_obj_newObject("TLuaDialogsServices")); + +local function newDialogObject(className) + return objs.objectFromHandle(_obj_newObject(className)); +end; + +lDialogs.DT_INFORMATION = "information"; +lDialogs.DT_ERROR = "error"; +lDialogs.DT_WARNING = "warning"; +lDialogs.DT_CONFIRMATION = "confirmation"; + +lDialogs.DB_YES = "yes"; +lDialogs.DB_NO = "no"; +lDialogs.DB_OK = "ok"; +lDialogs.DB_CANCEL = "cancel"; +lDialogs.DB_ABORT = "abort"; +lDialogs.DB_ALL = "all"; +lDialogs.DB_RETRY = "retry"; +lDialogs.DB_IGNORE = "ignore"; +lDialogs.DB_CLOSE = "close"; + +function lDialogs.newMessageDialog() + local dlg = newDialogObject('messageDialog'); + + function dlg:show(message, dialogType, dialogButtons, funcCallback) + _obj_setProp(dlg.handle, "DialogType", dialogType); + _obj_setProp(dlg.handle, "DialogButtons", dialogButtons); + + if funcCallback ~= nil then + dlg:addEventListener('OnResult', funcCallback); + end; + + _obj_invoke(dlg.handle, 'Executar', tostring(message)); + end; + + return dlg; +end; + +local runningMessageDialogs = {}; + +function lDialogs.showMessageDlg(message, dialogType, dialogButtons, funcCallback) + local dlg = lDialogs.newMessageDialog(); + runningMessageDialogs[dlg] = true; -- apenas manter uma referência forte ate o fim do dialogo + + dlg:show(message, dialogType, dialogButtons, + function (...) + runningMessageDialogs[dlg] = nil; + dlg = nil + + if type(funcCallback) == "function" then + funcCallback(...); + end; + end); +end; + +function lDialogs.confirmYesNo(question, callback) + lDialogs.showMessageDlg(question, lDialogs.DT_CONFIRMATION, {lDialogs.DB_YES, lDialogs.DB_NO}, + function(modalResult) + if type(callback) == "function" then + if modalResult == lDialogs.DB_YES then + callback(true); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.confirmOkCancel(question, callback) + lDialogs.showMessageDlg(question, lDialogs.DT_CONFIRMATION, {lDialogs.DB_OK, lDialogs.DB_CANCEL}, + function(modalResult) + if type(callback) == "function" then + if modalResult == lDialogs.DB_OK then + callback(true); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.showMessage(msg, callback) + lDialogs.showMessageDlg(msg, lDialogs.DT_INFORMATION, {lDialogs.DB_OK}, + function(modalResult) + if type(callback) == "function" then + callback(); + end; + end); +end; + +function lDialogs.showErrorMessage(msg, callback) + lDialogs.showMessageDlg(msg, lDialogs.DT_ERROR, {lDialogs.DB_OK}, + function(modalResult) + if type(callback) == "function" then + callback(); + end; + end); +end; + +function lDialogs.alert(msg, callback) + lDialogs.showMessageDlg(msg, lDialogs.DT_WARNING, {lDialogs.DB_OK}, + function(modalResult) + if type(callback) == "function" then + callback(); + end; + end); +end; + +function lDialogs.newInputQueryDialog() + local dlg = objs.objectFromHandle(_obj_newObject("TLuaInputQueryDialog")); + + function dlg:show(caption, prompt, initialValue, confirmCallback, cancelCallback, allowEmptyString) + if (confirmCallback ~= nil) then + dlg:addEventListener("OnConfirm", confirmCallback); + end; + + if (cancelCallback ~= nil) then + dlg:addEventListener("OnCancel", cancelCallback); + end; + + _obj_invoke(dlg.handle, "Executar", caption or "", prompt or "", initialValue or "", allowEmptyString == true); + end; + + objs.registerHandle(dlg.handle, dlg); + return dlg; +end; + +local runningQueryDialogs = {}; + +function lDialogs.inputQuery(caption, prompt, initialValue, confirmCallback, cancelCallback, allowEmptyString) + local dlg = lDialogs.newInputQueryDialog(); + runningQueryDialogs[dlg] = true; -- apenas manter uma referência forte até o fim do input query + + dlg:show(caption, prompt, initialValue, + function(...) + runningQueryDialogs[dlg] = nil; + dlg = nil; + + if confirmCallback ~= nil then + confirmCallback(...); + end; + end, + + function (...) + runningQueryDialogs[dlg] = nil; + dlg = nil; + + if cancelCallback ~= nil then + cancelCallback(...); + end; + end, allowEmptyString); +end; + +function alert(msg, callback) + lDialogs.alert(msg, callback); +end; + +function showMessage(msg, callback) + lDialogs.showMessage(msg, callback); +end; + +local runningFileQuerys = {}; + +function _newFileQueryObject() + local obj = objs.objectFromHandle(_obj_newObject('TLuaFileQueryDialog')); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["onResult"] = "data"; + obj.eves["onCancel"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +function lDialogs.openFile(prompt, accept, multiple, callback, cancelCallback) + local query = _newFileQueryObject(); + + query.onResult = function(files) + runningFileQuerys[query] = nil; + local utils = require("utils.lua"); + + for i = 1, #files, 1 do + files[i].stream = utils.streamFromHandle(files[i].streamHandle); + files[i].stream.position = 0; + files[i].streamHandle = nil; + end; + + if callback ~= nil then + callback(files or {}); + end; + end; + + query.onCancel = function() + runningFileQuerys[query] = nil; + + if cancelCallback ~= nil then + cancelCallback(); + end; + end; + + _obj_setProp(query.handle, "Accept", tostring(accept or "") or ""); + _obj_setProp(query.handle, "Multiple", not (not multiple)); + _obj_setProp(query.handle, "Prompt", tostring(prompt or "") or ""); + + runningFileQuerys[query] = true; + _obj_invoke(query.handle, "Execute"); +end; + +function lDialogs.asyncOpenFile(prompt, accept, multiple) + local promise, resolution = Async.Promise.pending(); + + lDialogs.openFile(prompt, accept, multiple, + function(data) + resolution:setSuccess(data); + end, + + function() + resolution:setUserAborted(); + end); + + return promise; +end; + +local function _newFileSaveObject() + local obj = objs.objectFromHandle(_obj_newObject('TLuaFileSaveDialog')); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["OnCallback"] = ""; + obj.eves["OnCancelCallback"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +local runningFileSaveDialogs = {}; + +function lDialogs.saveFile(prompt, stream, suggestedFileName, mimeType, callback, cancelCallback) + if (type(stream) ~= "table") or (stream.handle == nil) then + error("Dialogs.saveFile - 'stream' parameter is not a valid object"); + end; + + local query = _newFileSaveObject(); + rawset(query, "__tempStream", stream); -- keep reference while running the save dialog + + query.OnCallback = function() + runningFileSaveDialogs[query] = nil; + + if callback ~= nil then + callback(); + end; + end; + + query.OnCancelCallback = function() + runningFileSaveDialogs[query] = nil; + + if cancelCallback ~= nil then + cancelCallback(); + end; + end; + + _obj_setProp(query.handle, "Prompt", tostring(prompt or "") or ""); + _obj_setProp(query.handle, "SuggestedFileName", tostring(suggestedFileName or "") or ""); + _obj_setProp(query.handle, "MimeType", tostring(mimeType or "") or ""); + + _obj_invokeEx(query.handle, "SetStream", stream.handle); + + runningFileSaveDialogs[query] = true; + _obj_invoke(query.handle, "Execute"); +end + +function lDialogs.o(prompt, multiple, callback, cancelCallback) + return lDialogs.openFile(prompt, "image/*", multiple, callback, cancelCallback); +end; + +local function _newSelectImageURLObject() + local obj = objs.objectFromHandle(_obj_newObject('TLuaSelectImageURLQuery')); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["OnCallback"] = ""; + obj.eves["OnCancelCallback"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +local runningSelectImageURLDialogs = {}; + +function lDialogs.selectImageURL(defaultURL, callback, cancelCallback) + local query = _newSelectImageURLObject(); + + query.OnCallback = function() + runningSelectImageURLDialogs[query] = nil; + + if callback ~= nil then + callback(_obj_getProp(query.handle, "SelectedURL")); + end; + end; + + query.OnCancelCallback = function() + runningSelectImageURLDialogs[query] = nil; + + if cancelCallback ~= nil then + cancelCallback(); + end; + end; + + _obj_setProp(query.handle, "DefaultURL", tostring(defaultURL or "") or ""); + + runningSelectImageURLDialogs[query] = true; + _obj_invoke(query.handle, "Execute"); +end + +local function _newChoiceDialogPopup(className) + local GUI = require("gui.lua"); + local obj = GUI.controlFromHandle(_obj_newObject(className or 'TLuaChoiceDialogPopup')); + + if obj.eves == nil then + obj.eves = {}; + end; + + function obj:addSelectionOption(option) + _obj_invoke(obj.handle, "AddSelectionOption", tostring(option) or ""); + end; + + function obj:setDefaultIndex(defaultIndex) + _obj_setProp(obj.handle, "DefaultIndex", defaultIndex); + end; + + function obj:setTitle(title) + _obj_setProp(obj.handle, "DialogTitle", tostring(title) or ""); + end; + + function obj:buildPanel() + _obj_invoke(obj.handle, "BuildPanel"); + end; + + function obj:executeAsync() + _obj_invoke(obj.handle, "ExecuteAsync"); + end; + + function obj:acquireFocus() + _obj_invoke(obj.handle, "AcquireFocus"); + end; + + function obj:getSelectedIndex() + return _obj_getProp(obj.handle, "LuaSelectedIndex"); + end; + + obj.eves["onChoiceSelected"] = ""; + obj.eves["onChoiceCanceled"] = ""; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +local function _newMultipleChoiceDialogPopup() + local obj = _newChoiceDialogPopup("TLuaMultipleChoiceDialogPopup"); + + function obj:getSelectedIndexes() + return _obj_invokeEx(obj.handle, "ReturnLuaArrayOfSelected"); + end; + + return obj; +end; + +local function _executeChoicePanel(panel, callback) + local GUI = require("gui.lua"); + require("utils.lua"); + + local frm = GUI.newPopupForm(); + frm.drawContainer = true; + frm.cancelable = false; + frm.resizable = true; + local haveNotified = false; + + local cancelProc = function() + frm:close(); + + if not haveNotified then + haveNotified = true; + + setTimeout( + function() + callback(false); + end, 1); + end; + end; + + frm.onCancelRequest = cancelProc; + panel.onChoiceCanceled = cancelProc; + frm.onHide = cancelProc; + + panel.onChoiceSelected = + function() + local mustNotify = not haveNotified; + haveNotified = true; + + frm:close(); + + if mustNotify then + setTimeout(function() + callback(true); + end, 1); + end; + end; + + panel.parent = frm; + panel.align = "client"; + panel.visible = true; + frm.width = 300; + frm.height = 300; + frm.theme = "dark"; + panel:executeAsync(); + frm:show(); + panel:acquireFocus(); +end; + +function lDialogs.choose(prompt, options, callback, defaultIndex, shortCircuit) + if (type(options) ~= "table") or (#options < 1) then + if callback ~= nil then + callback(false); + end; + + return; + end; + + require("gui.lua"); + local choosePanel = _newChoiceDialogPopup(); + + if type(options) == "table" then + for i = 1, #options, 1 do + choosePanel:addSelectionOption(options[i]); + end; + + if shortCircuit and (#options == 1) then + setTimeout( + function() + if callback ~= nil then + callback(true, 1, options[1]); + end; + end, 1); + + return; + end; + end; + + if defaultIndex ~= nil then + choosePanel:setDefaultIndex(defaultIndex - 1); + end; + + choosePanel:setTitle(prompt or ""); + choosePanel:buildPanel(); + + _executeChoicePanel(choosePanel, + function (confirmed) + if callback ~= nil then + if confirmed then + local idx = choosePanel:getSelectedIndex() + 1; + callback(true, idx, options[idx]); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.chooseMultiple(prompt, options, callback) + require("gui.lua"); + local choosePanel = _newMultipleChoiceDialogPopup(); + + if type(options) == "table" then + for i = 1, #options, 1 do + choosePanel:addSelectionOption(options[i]); + end; + end; + + choosePanel:setTitle(prompt or ""); + choosePanel:buildPanel(); + + _executeChoicePanel(choosePanel, + function (confirmed) + if callback ~= nil then + if confirmed then + local indexes = choosePanel:getSelectedIndexes(); + local values = {}; + + for i = 1, #indexes, 1 do + indexes[i] = indexes[i] + 1; + values[i] = options[indexes[i]]; + end; + + callback(true, indexes, values); + else + callback(false); + end; + end; + end); +end; + +function lDialogs.asyncSelectTalemarkColor(initialColor) + local promiseHandle = _obj_invokeEx(lDialogs.handle, "AsyncSelectTalemarkColor", initialColor); + return Async.Promise.wrap(promiseHandle); +end; + +dialogs = lDialogs; +Dialogs = dialogs; +return dialogs; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessages.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessages.lua new file mode 100644 index 00000000..d32bb018 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessages.lua @@ -0,0 +1,236 @@ +local rrpgObjs = require("rrpgObjs.lua"); +local messaging = {}; + +local CANCEL_RECEIVER = false; +messaging.CANCEL = CANCEL_RECEIVER; + +local _messageAdapters = {}; + +function messaging.createReceiver(messageName, callback, filters) + if (type(callback) ~= "function") or (type(messageName) ~= "string") or (messageName == "") then + return nil; + end; + + if type(filters) ~= "table" then + filters = nil; + end; + + local obj = rrpgObjs.objectFromHandle(_obj_newObject("TRRPGEventMessageReceiver")); + rrpgObjs.registerHandle(obj.handle, obj); + + local msgAdapter = _messageAdapters[string.upper(messageName)]; + + if (msgAdapter ~= nil) and (msgAdapter.prepareFilters ~= nil) and (filters ~= nil) then + msgAdapter.prepareFilters(filters); + end; + + if filters ~= nil then + for k, v in pairs(filters) do + _obj_invokeEx(obj.handle, "AddFilter", k, v); + end; + end; + + _obj_setProp(obj.handle, "EventName", messageName); + + obj.__callbackEventListenerId = obj:addEventListener("OnMessage", + function (message) + if callback ~= nil then + if (msgAdapter ~= nil) and (msgAdapter.prepareMessage ~= nil) then + msgAdapter.prepareMessage(message); + end; + + local retorno = callback(message); + + if retorno == CANCEL_RECEIVER then + messaging.disableReceiver(obj); + end; + + local response = message.response; + + if (response ~= nil) and (type(response) == "table") then + if (msgAdapter ~= nil) and (msgAdapter.prepareResponse ~= nil) then + msgAdapter.prepareResponse(response); + end; + + _obj_invokeEx(obj.handle, "AddResponse", response); + end; + end; + end); + + function obj:disable() + callback = nil; + local evtId = obj.__callbackEventListenerId; + + if evtId ~= nil then + _obj_setProp(obj.handle, "EventName", ""); + obj:removeEventListener(evtId); + obj.__callbackEventListenerId = nil; + end; + end; + + return obj; +end; + +messaging.newReceiver = messaging.createReceiver; + +function messaging.disableReceiver(receiverObj) + if (type(receiverObj) == "table") and (receiverObj.disable ~= nil) then + receiverObj:disable(); + end; +end; + +local __settedListeners = {}; +local __listenersGeneratorId = 1; +local __listenersByName = {}; + +function messaging.listen(messageName, callback, filters) + if (type(callback) ~= "function") or (type(messageName) ~= "string") or (messageName == "") then + return nil; + end; + + __listenersGeneratorId = __listenersGeneratorId + 1; + local esteListenerId = __listenersGeneratorId; + + local obj = messaging.createReceiver(messageName, + function(message) + local retorno; + + if callback ~= nil then + retorno = callback(message); + else + retorno = nil; + end; + + if retorno == CANCEL_RECEIVER then + messaging.unlisten(esteListenerId); + callback = nil; + end; + + return retorno; + end, filters); + + if obj == nil then + return nil; + end; + + __settedListeners[esteListenerId] = obj; + + local preparedMessageName = _util_genCollateWinPtBrString(messageName); + local lbn = __listenersByName[preparedMessageName]; + + if lbn == nil then + lbn = {}; + __listenersByName[preparedMessageName] = lbn; + end; + + obj.preparedMessageName = preparedMessageName; + lbn[esteListenerId] = obj; + return esteListenerId; +end; + +function messaging.unlisten(listenerId) + if listenerId == nil then + return; + end; + + local listenerObj = __settedListeners[listenerId]; + + if listenerObj ~= nil then + __settedListeners[listenerId] = nil; + + local lbn = __listenersByName[listenerObj.preparedMessageName]; + + if lbn ~= nil then + lbn[listenerId] = nil; + + if next(lbn, nil) == nil then -- Tabela vazia + __listenersByName[listenerObj.preparedMessageName] = nil; + end; + end; + + if listenerObj.disable ~= nil then + listenerObj:disable(); + end; + end; +end; + +function messaging.listenOnce(messageName, callback, filters) + local listenerId = messaging.listen(messageName, + function(message) + callback(message); + return CANCEL_RECEIVER; + end, filters); + + return listenerId; +end; + +function messaging.groupOnceListeners(...) + local parametros = table.pack(...); + local listenersObjs = {}; + local listenersId = {}; + + for i = 1, #parametros, 1 do + local obj = __settedListeners[parametros[i]]; + + if (obj ~= nil) then + listenersId[#listenersId + 1] = parametros[i]; + listenersObjs[#listenersObjs + 1] = obj; + end; + end; + + if #listenersObjs == 0 then + return; + end; + + local eventListenersId = {}; + + for i = 1, #listenersObjs, 1 do + local obj = listenersObjs[i]; + eventListenersId[#eventListenersId + 1] = obj:addEventListener('OnAfterMessage', + function() + -- um dos listeners disparou, vamos cancelar os outros. + + for j = 1, #listenersObjs, 1 do + local otherObj = listenersObjs[j]; + otherObj:removeEventListener(eventListenersId[j]); + messaging.unlisten(listenersId[j]); + otherObj:disable(); + end; + end); + end; +end; + +function messaging.addMessageAdapter(messageName, adapter) + _messageAdapters[string.upper(messageName)] = adapter; +end; + +function messaging.dispatchLocalMessage(messageName, message) + local lbn = __listenersByName[_util_genCollateWinPtBrString(messageName)]; + + if lbn == nil then + return; + end; + + if type(message) ~= "table" then + local nm = {}; + nm.data = message; + message = nm; + end; + + local copyOfLbn = {}; + + -- Copiar, pois lbn pode mudar ao longo do processo + for k, v in pairs(lbn) do + copyOfLbn[k] = v; + end; + + for k, v in pairs(copyOfLbn) do + _obj_invokeEx(v.handle, "TryDispatchLocalMessage", message); + end +end; + +function __export__dispatchLocalMessage(messageName, message) + return messaging.dispatchLocalMessage(messageName, message); +end; + +return messaging; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessagesAdapters.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessagesAdapters.lua new file mode 100644 index 00000000..50331dbb --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEventMessagesAdapters.lua @@ -0,0 +1,308 @@ +local messaging = require("rrpgEventMessages.lua"); +local rrpgWrappers = require("rrpgWrappers.lua"); + +-- Não faça require em rrpg.lua + +local _basicChatCommandAdapter = {prepareFilters = + function(filters) + + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + + if filters.chat ~= nil then + filters.chatObjectID = filters.chat.objectID; + filters.chat = nil; + else + filters.chatObjectID = nil; + end; + + if filters.player ~= nil then + filters.jogadorObjectID = filters.player.objectID; + filters.player = nil; + filters.jogador = nil; + else + if filters.jogador ~= nil then + filters.jogadorObjectID = filters.jogador.objectID; + filters.jogador = nil; + else + filters.jogadorObjectID = nil; + end; + end; + end, + + prepareMessage = + function(message) + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + + message.chat = rrpgWrappers.contextObjectFromID(message.chatObjectID); + + message.jogador = rrpgWrappers.contextObjectFromID(message.jogadorObjectID); + message.player = message.jogador; + end, + }; + +local _basicChatMessageAdapter = {prepareFilters = + function(filters) + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + + if filters.chat ~= nil then + filters.chatObjectID = filters.chat.objectID; + filters.chat = nil; + else + filters.chatObjectID = nil; + end; + + if filters.player ~= nil then + filters.jogadorObjectID = filters.player.objectID; + filters.player = nil; + filters.jogador = nil; + else + if filters.jogador ~= nil then + filters.jogadorObjectID = filters.jogador.objectID; + filters.jogador = nil; + else + filters.jogadorObjectID = nil; + end; + end; + + if filters.pvtPlayer ~= nil then + filters.jogadorPVTObjectID = filters.pvtPlayer.objectID; + filters.pvtPlayer = nil; + filters.jogadorPVT = nil; + else + if filters.jogadorPVT ~= nil then + filters.jogadorPVTObjectID = filters.jogadorPVT.objectID; + filters.jogadorPVT = nil; + else + filters.jogadorPVTObjectID = nil; + end; + end; + + filters.rolagem = nil; + filters.roll = nil; + end, + + prepareMessage = + function(message) + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + + message.chat = rrpgWrappers.contextObjectFromID(message.chatObjectID); + + message.jogador = rrpgWrappers.contextObjectFromID(message.jogadorObjectID); + message.player = message.jogador; + + message.jogadorPVT = rrpgWrappers.contextObjectFromID(message.jogadorPVTObjectID); + message.pvtPlayer = message.jogadorPVT; + + if message.rolagem64 ~= nil then + message.rolagem = rrpg.loadRolagemFromBase64EncodedString(message.rolagem64); + message.roll = message.rolagem; + message.rolagem64 = nil; + end; + end, + }; + +local __listChatCommandsAdapter = { + prepareFilters = function(filters) + _basicChatMessageAdapter.prepareFilters(filters); + end, + + prepareMessage = + function(message) + _basicChatMessageAdapter.prepareMessage(message); + end, + + prepareResponse = function(response) + local r = {}; + + for k, v in pairs(response) do + if type(v) == "table" then + r[k] = v; + end; + + response[k] = nil; + end; + + local id = _rrpg_generateUniqueStrID(); + local qt = 0; + + for k, v in pairs(r) do + qt = qt + 1; + local str = ""; + local comando = v.command or v.comando; + local tComando = type(comando); + local comandoIdx = 1; + + if tComando == "string" then + str = str .. "comando" .. comandoIdx .. "=" .. _util_encodeStringToHexUTF8(comando) .. "&"; + --comandoIdx = comandoIdx + 1; + elseif tComando == "table" then + for i = 1, #comando, 1 do + str = str .. "comando" .. comandoIdx .. "=" .. _util_encodeStringToHexUTF8(comando[i]) .. "&"; + comandoIdx = comandoIdx + 1; + end; + end; + + str = str .. "descricao=" .. _util_encodeStringToHexUTF8(v.description or v.descricao); + response[id .. qt] = str; + end; + end; +}; + +local _mesaJoinPartAdapter = {prepareFilters = + function(filters) + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + + if filters.player ~= nil then + filters.jogadorObjectID = filters.player.objectID; + filters.player = nil; + filters.jogador = nil; + else + if filters.jogador ~= nil then + filters.jogadorObjectID = filters.jogador.objectID; + filters.jogador = nil; + else + filters.jogadorObjectID = nil; + end; + end; + + if filters.me ~= nil then + filters.eu = filters.me; + filters.me = nil; + end; + + if filters.isKick ~= nil then + filters.ehKick = filters.isKick; + filters.isKick = nil; + end; + + if filters.text ~= nil then + filters.mensagem = filters.text; + filters.text = nil; + end; + + if filters.responsible ~= nil then + filters.responsavelObjectID = filters.responsible.objectID; + filters.responsible = nil; + filters.responsavel = nil; + else + if filters.responsavel ~= nil then + filters.responsavelObjectID = filters.responsavel.objectID; + filters.responsavel = nil; + end; + end; + end, + + prepareMessage = + function(message) + message.me = message.eu; + message.isKick = message.ehKick; + message.text = message.mensagem; + + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + + message.jogador = rrpgWrappers.contextObjectFromID(message.jogadorObjectID); + message.player = message.jogador; + + if message.responsavelObjectID ~= nil then + message.responsavel = rrpgWrappers.contextObjectFromID(message.responsavelObjectID); + message.responsible = message.responsavel; + end; + end, + }; + +local _mesaMsgAdapter = {prepareFilters = + function(filters) + if filters.room ~= nil then + filters.mesaObjectID = filters.room.objectID; + filters.room = nil; + filters.mesa = nil; + else + if filters.mesa ~= nil then + filters.mesaObjectID = filters.mesa.objectID; + filters.mesa = nil; + else + filters.mesaObjectID = nil; + end; + end; + end, + + prepareMessage = + function(message) + message.mesa = rrpgWrappers.contextObjectFromID(message.mesaObjectID); + message.room = message.mesa; + end, + }; + +messaging.addMessageAdapter("ChatMessage", _basicChatMessageAdapter); +messaging.addMessageAdapter("HandleChatTextInput", _basicChatMessageAdapter); +messaging.addMessageAdapter("HandleChatCommand", _basicChatCommandAdapter); +messaging.addMessageAdapter("ListChatCommands", __listChatCommandsAdapter); +messaging.addMessageAdapter("MesaJoined", _mesaJoinPartAdapter); +messaging.addMessageAdapter("MesaParted", _mesaJoinPartAdapter); +messaging.addMessageAdapter("TablesDockClosedByUser", _mesaMsgAdapter); +messaging.addMessageAdapter("TablesDockPosChanged", _mesaMsgAdapter); + +-- Mensagens do Scene 3 + +local _SceneWrappers = nil; + +local _sceneMsgAdapter = {prepareFilters = + function(filters) + if filters.scene ~= nil then + filters.sceneObjectID = filters.scene.objectID; + filters.scene = nil; + else + filters.sceneObjectID = nil; + end; + end, + + prepareMessage = + function(message) + if _SceneWrappers == nil then + _SceneWrappers = require("sceneWrappers.dlua"); + end; + + message.scene = _SceneWrappers.objectFromID(message.sceneObjectID); + end, + }; + + +messaging.addMessageAdapter("SC3SceneLoaded", _sceneMsgAdapter); +messaging.addMessageAdapter("SC3SceneUnloaded", _sceneMsgAdapter); + \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEvents.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEvents.lua new file mode 100644 index 00000000..209c0115 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgEvents.lua @@ -0,0 +1,133 @@ +local ndb = require("ndb.lua"); +local objs = require("rrpgObjs.lua"); + + + +function _eve_MESA_PVT_ReceberMensagem(mesaID, senderID, msg) + rrpg.dispatch("MESA_PVT_ReceberMensagem", rrpg.objectFromID(mesaID), rrpg.objectFromID(senderID), msg); +end + + +--[[ Coisas relacionadas ao Sistema de Forms ]]-- + +local _LuaForms = {}; + +--[ Lista de forms que não estao sendo utilizados, e podem ser reusados (antes que o garbage colector faca sua parte) ]-- +local _CachedFreeForms = {}; + +function _eve_Forms_CriarForm(formName) + local dtObj = rrpg.forms[formName]; + + if dtObj ~= nil then + local frm = dtObj.newEditor(); + rawset(frm, "__formName", formName); + + _LuaForms[frm.handle] = frm; + return frm.handle; + else + return nil; + end; +end; + +function eve_Forms_ExisteFormName(formName) + return rrpg.forms[formName] ~= nil; +end; + +function _eve_Forms_DestruirForm(formHandle) + local frm = _LuaForms[formHandle]; + + if frm ~= nil then + _LuaForms[formHandle] = nil; + frm:destroy(); + end; +end; + +function _eve_Forms_AssignNodeDatabase(formHandle, nodeHandle) + local nodeDataBase = ndb.openNodeFacade(nodeHandle); + local formObj = _LuaForms[formHandle]; + + if (formObj ~= nil) then + if formObj.setNodeDatabase ~= nil then + formObj:setNodeDatabase(nodeDataBase); + end; + end; +end; + +local _tmrDestroyCachedForms = objs.newTimer(45000); +_tmrDestroyCachedForms:setEnabled(false); + +function _eve_Forms_Cached_CriarForm(formName) + local cache = _CachedFreeForms[formName]; + + if type(cache) == "table" then + local objetoEncontrado = nil; + + for k, v in pairs(cache) do + if (type(k) == "table") and (v ~= nil) then + objetoEncontrado = k; + break; + end; + end; + + if objetoEncontrado ~= nil then + _LuaForms[objetoEncontrado.handle] = objetoEncontrado; + cache[objetoEncontrado] = nil; + return objetoEncontrado.handle; + end; + end; + + -- se chegou até aqui, é porque nao conseguiu usar algum do cache + return _eve_Forms_CriarForm(formName); +end; + +function _eve_Forms_Cached_DestruirForm(formHandle) + local formObject = _LuaForms[formHandle]; + + if formObject ~= nil then + local formName = rawget(formObject, "__formName"); + + if formName ~= nil then + local cache = _CachedFreeForms[formName]; + + if cache == nil then + cache = {}; + _CachedFreeForms[formName] = cache; + end; + + cache[formObject] = true; -- adicionar ao cache + _LuaForms[formObject.handle] = nil; + + if formObject.setNodeDatabase ~= nil then + formObject:setNodeDatabase(nil); + end; + + formObject:setParent(nil); + + _tmrDestroyCachedForms:setEnabled(true); -- ativar o timer de coleta de cache + return; + end; + end; + + -- se chegou até aqui, é porque nao conseguiu colocar o form no cache + return _eve_Forms_DestruirForm(formHandle); +end; + +function timedCheckAndDestroyCachedForms() + _tmrDestroyCachedForms:setEnabled(false); + + local oldCachedFreeForms = _CachedFreeForms; + _CachedFreeForms = {}; + + for formName, cache in pairs(oldCachedFreeForms) do + + if cache ~= nil then + for formObj, v in pairs(cache) do + if (formObj ~= nil) and (formObj.destroy ~= nil) then + formObj:destroy(); + end; + end; + end; + end; +end; + +_tmrDestroyCachedForms:addEventListener("onTimer", timedCheckAndDestroyCachedForms); \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI.lua new file mode 100644 index 00000000..5d1855bf --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI.lua @@ -0,0 +1,2060 @@ +local objs = require("rrpgObjs.lua"); +local ndb = require("ndb.lua"); +local System = require("system.lua"); +local Async = require("async.lua"); +local Utils = require("utils.lua"); + +local __delayedGridLib = nil; + +gui = objs.objectFromHandle(_obj_newObject("TLuaGUIServices")); +GUI = gui; + +gui.DEFAULT_FORM_CACHE_TIMEOUT = 60000; + +local guiLoaders = {}; +local guiClasses = {}; + +gui.guiLoaders = guiLoaders; +gui.guiClasses = guiClasses; + +local function registerTag(class, tagName) + assert(guiClasses[tagName] == nil, tagName); + assert(rawget(class, "tagName") == nil, tagName); + + guiLoaders[tagName] = class.fromHandle; + guiClasses[tagName] = class; + + rawset(class, "tagName", tagName); + + rawset(class, "new", + function() + return class.fromHandle(_obj_newObject(tagName)); + end); + + local constructorName = "new" .. tagName:gsub("^%l", string.upper); + + gui[constructorName] = + function() + return class.new(); + end; +end; + +--[[ Objeto Control ]]-- + +gui.Control = objs.HierarchyObject.inherit(); + +function gui.Control:initialize() + if self.props == nil then + self.props = {}; + end; + + if self.eves == nil then + self.eves = {}; + end; + + self:setParent(self:getParent()); +end; + +function gui.Control:setFocus() _obj_invoke(self.handle, "SetFocus"); end; +function gui.Control:beginUpdate() _obj_invoke(self.handle, "BeginUpdate"); end; +function gui.Control:endUpdate() _obj_invoke(self.handle, "EndUpdate"); end; +function gui.Control:needRepaint() _obj_invoke(self.handle, "Repaint"); end; + +function gui.Control:getVisible() return _obj_getProp(self.handle, "Visible"); end; + +function gui.Control:setVisible(visible) + _obj_setProp(self.handle, "Visible", visible == true); + + if visible then + local grid = self:tryGetGrid(); + + if grid ~= nil then + grid:invalidate(); + end; + end; +end; + +function gui.Control:getAlign() return _obj_getProp(self.handle, "Align"); end; +function gui.Control:setAlign(align) _obj_setProp(self.handle, "Align", align); end; + +function gui.Control:getEnabled()return _obj_getProp(self.handle, "Enabled"); end; +function gui.Control:setEnabled(enabled) _obj_setProp(self.handle, "Enabled", enabled == true) end; + +function gui.Control:getLeft() return _obj_getProp(self.handle, "Position.X"); end; +function gui.Control:setLeft(left) _obj_setProp(self.handle, "Position.X", left) end; + +function gui.Control:getTop() return _obj_getProp(self.handle, "Position.Y"); end; +function gui.Control:setTop(top) _obj_setProp(self.handle, "Position.Y", top) end; + +function gui.Control:getBottom() return self:getTop() + self:getHeight(); end; +function gui.Control:setBottom(bottom) self:setTop(bottom - self:getHeight()); end; + +function gui.Control:getRight() return self:getLeft() + self:getWidth(); end; +function gui.Control:setRight(right) self:setLeft(right - self:getWidth()); end; + +function gui.Control:getWidth() return _obj_getProp(self.handle, "Width"); end; +function gui.Control:setWidth(width) _obj_setProp(self.handle, "Width", width) end; + +function gui.Control:getHeight() return _gui_getHeight(self.handle); end; +function gui.Control:setHeight(height) _gui_setHeight(self.handle, height) end; + +function gui.Control:getHitTest() return _obj_getProp(self.handle, "HitTest"); end; +function gui.Control:setHitTest(hittest) _obj_setProp(self.handle, "HitTest", hittest == true) end; + +function gui.Control:getTabOrder() return _obj_getProp(self.handle, "TabOrder"); end; +function gui.Control:setTabOrder(tabOrder) _obj_setProp(self.handle, "TabOrder", tabOrder); end; + +function gui.Control:getOpacity() return _obj_getProp(self.handle, "Opacity"); end; +function gui.Control:setOpacity(opacity) _obj_setProp(self.handle, "Opacity", opacity); end; + +function gui.Control:getMargins() return _obj_getProp(self.handle, "Margins"); end; +function gui.Control:setMargins(margins) _gui_setMargins(self.handle, margins); end; + +function gui.Control:getPadding() return _obj_getProp(self.handle, "Padding"); end; +function gui.Control:setPadding(padding) _gui_setPadding(self.handle, padding); end; + +function gui.Control:getAnchors() return _obj_getProp(self.handle, "Anchors"); end; +function gui.Control:setAnchors(anchors) _obj_setProp(self.handle, "Anchors", anchors); end; + +function gui.Control:getCanFocus() return _obj_getProp(self.handle, "CanFocus"); end; +function gui.Control:setCanFocus(canFocus) _obj_setProp(self.handle, "CanFocus", canFocus); end; + +function gui.Control:getRotationAngle() return _obj_getProp(self.handle, "RotationAngle"); end; +function gui.Control:setRotationAngle(angle) _obj_setProp(self.handle, "RotationAngle", angle); end; + +function gui.Control:getRotationCenterX() return _obj_getProp(self.handle, "RotationCenter.X"); end; +function gui.Control:setRotationCenterX(x) _obj_setProp(self.handle, "RotationCenter.X", x); end; + +function gui.Control:getRotationCenterY() return _obj_getProp(self.handle, "RotationCenter.Y"); end; +function gui.Control:setRotationCenterY(y) _obj_setProp(self.handle, "RotationCenter.Y", y); end; + +function gui.Control:getScaleX() return _obj_getProp(self.handle, "Scale.X"); end; +function gui.Control:setScaleX(sX) _obj_setProp(self.handle, "Scale.X", sX); end; + +function gui.Control:getScaleY() return _obj_getProp(self.handle, "Scale.Y"); end; +function gui.Control:setScaleY(sY) _obj_setProp(self.handle, "Scale.Y", sY); end; + +function gui.Control:getScale() return self:getScaleX(); end; +function gui.Control:setScale(ss) self:beginUpdate(); self:setScaleX(ss); self:setScaleY(ss); self:endUpdate(); end; + +function gui.Control:isChildFocused() return _obj_getProp(self.handle, "IsChildFocused"); end; +function gui.Control:isFocused() return _obj_getProp(self.handle, "IsFocused"); end; +function gui.Control:isMouseOver() return _obj_getProp(self.handle, "IsMouseOver"); end; +function gui.Control:isVisible() return self:getVisible(); end; + +function gui.Control:getCursor() return _obj_getProp(self.handle, "MouseCursor"); end; +function gui.Control:setCursor(v) _obj_setProp(self.handle, "MouseCursor", v); end; + +function gui.Control:getHint() return _obj_getProp(self.handle, "Hint"); end; +function gui.Control:setHint(v) _gui_setHint(self.handle, v); end; + +function gui.Control:getEffect() return _obj_getProp(self.handle, "CompEffect"); end; +function gui.Control:setEffect(effect) _obj_setProp(self.handle, "CompEffect", effect); end; + +function gui.Control:getEffectTriggers() return _obj_getProp(self.handle, "CompEffectTriggers"); end; +function gui.Control:setEffectTriggers(triggers) _obj_setProp(self.handle, "CompEffectTriggers", triggers); end; + +function gui.Control:getEffectParam() return _obj_getProp(self.handle, "CompEffectParam"); end; +function gui.Control:setEffectParam(param) _obj_setProp(self.handle, "CompEffectParam", param); end; + +function gui.Control:getEffectParam2() return _obj_getProp(self.handle, "CompEffectParam2"); end; +function gui.Control:setEffectParam2(param) _obj_setProp(self.handle, "CompEffectParam2", param); end; + +function gui.Control:getEffectParam3() return _obj_getProp(self.handle, "CompEffectParam3"); end; +function gui.Control:setEffectParam3(param) _obj_setProp(self.handle, "CompEffectParam3", param); end; + +function gui.Control:getEffectParam4() return _obj_getProp(self.handle, "CompEffectParam4"); end; +function gui.Control:setEffectParam4(param) _obj_setProp(self.handle, "CompEffectParam4", param); end; + +function gui.Control:findControlByName(controlName) return gui.findControlByName(controlName, self); end; + +function gui.Control:getGrid() + local cachedGrid = rawget(self, "__cachedGrid"); + + if cachedGrid == nil then + if __delayedGridLib == nil then + __delayedGridLib = require("rrpgGUI_grid.dlua"); + assert(__delayedGridLib ~= nil); + end; + + cachedGrid = __delayedGridLib.new(self); + rawset(self, "__cachedGrid", cachedGrid); + end; + + return cachedGrid; +end; + +function gui.Control:tryGetGrid() + return rawget(self, "__cachedGrid"); +end; + +function gui.Control:__objindex(key) + if type(key) == "string" then + if key == "g" then + return true, self.grid.role; + end; + + local gridPropName = string.match(key, "^g%-(.+)$"); + + if gridPropName ~= nil then + return true, self.grid[gridPropName]; + end; + end; + + return false; +end; + +function gui.Control:__objnewindex(key, value) + if type(key) == "string" then + if key == "g" then + self.grid.role = value; + return true; + end; + + local gridPropName = string.match(key, "^g%-(.+)$"); + + if gridPropName ~= nil then + self.grid[gridPropName] = value; + return true; + end; + end; + + return false; +end; + +gui.Control.props["visible"] = {setter = "setVisible", getter = "getVisible", tipo = "bool"}; +gui.Control.props["align"] = {setter = "setAlign", getter = "getAlign", tipo = "enum", + values = {"none", "top", "left", "right", + "bottom", "client", "contents", "scale"}} + +gui.Control.props["enabled"] = {setter = "setEnabled", getter = "getEnabled", tipo = "bool"}; +gui.Control.props["left"] = {setter = "setLeft", getter = "getLeft", tipo = "double"}; +gui.Control.props["top"] = {setter = "setTop", getter = "getTop", tipo = "double"}; +gui.Control.props["right"] = {setter = "setRight", getter = "getRight", tipo = "double"}; +gui.Control.props["bottom"] = {setter = "setBottom", getter = "getBottom", tipo = "double"}; +gui.Control.props["width"] = {setter = "setWidth", getter = "getWidth", tipo = "double"}; +gui.Control.props["height"] = {setter = "setHeight", getter = "getHeight", tipo = "double"}; +gui.Control.props["hitTest"] = {setter = "setHitTest", getter = "getHitTest", tipo = "bool"}; +gui.Control.props["tabOrder"] = {setter = "setTabOrder", getter = "getTabOrder", tipo = "int"}; +gui.Control.props["opacity"] = {setter = "setOpacity", getter = "getOpacity", tipo = "double"}; +gui.Control.props["margins"] = {setter = "setMargins", getter = "getMargins", tipo = "bounds"}; +gui.Control.props["padding"] = {setter = "setPadding", getter = "getPadding", tipo = "bounds"}; +gui.Control.props["anchors"] = {setter = "setAnchors", getter = "getAnchors", tipo = "set", + values = {"left", "top", "right", "bottom"}}; + +gui.Control.props["canFocus"] = {setter = "setCanFocus", getter = "getCanFocus", tipo="bool"}; +gui.Control.props["rotationAngle"] = {setter = "setRotationAngle", getter = "getRotationAngle", tipo="double"}; +gui.Control.props["rotationCenterX"] = {setter = "setRotationCenterX", getter = "getRotationCenterX", tipo="double"}; +gui.Control.props["rotationCenterY"] = {setter = "setRotationCenterY", getter = "getRotationCenterY", tipo="double"}; +gui.Control.props["scaleX"] = {setter = "setScaleX", getter = "getScaleX", tipo="double"}; +gui.Control.props["scaleY"] = {setter = "setScaleY", getter = "getScaleY", tipo="double"}; +gui.Control.props["scale"] = {setter = "setScale", getter = "getScale", tipo="double"}; +gui.Control.props["parent"] = {setter = "setParent", getter = "getParent", tipo="table"}; + +gui.Control.props["cursor"] = {setter = "setCursor", getter = "getCursor", tipo="enum", + values={'default', 'arrow', 'handPoint', 'hourGlass', + 'IBeam', 'size', 'sizeNESW', 'sizeNS', + 'sizeNWSE', 'sizeWE', 'upArrow', + 'drag', 'noDrop', 'hSplit', 'vSplit', + 'multiDrag', 'sqlWait', 'no', 'appStart', + 'help', 'cross'}}; + +gui.Control.props["hint"] = {setter = "setHint", getter = "getHint", tipo="string"}; +gui.Control.props["grid"] = {getter = "getGrid", tipo="table"}; + +gui.Control.props["cacheMode"] = {readProp = "CacheMode", writeProp = "CacheMode", tipo = "enum", + values = {"none", "time"}}; + +gui.Control.eves["onResize"] = ""; +gui.Control.eves["onClick"] = "event"; +gui.Control.eves["onDblClick"] = "event"; +gui.Control.eves["onMouseDown"] = "event"; +gui.Control.eves["onMouseMove"] = "event"; +gui.Control.eves["onMouseUp"] = "event"; +gui.Control.eves["onMouseEnter"] = ""; +gui.Control.eves["onMouseLeave"] = ""; +gui.Control.eves["onEnter"] = ""; +gui.Control.eves["onExit"] = ""; +gui.Control.eves["onKeyDown"] = "event"; +gui.Control.eves["onKeyUp"] = "event"; +gui.Control.eves["onMenu"] = 'x, y, event'; +gui.Control.eves["onStartDrag"] = 'drag, x, y, event'; +gui.Control.eves["onStartDrop"] = 'drop, x, y, drag, event'; + +local function controlFromHandle(handle) + return gui.Control.fromHandle(handle); +end + +gui.controlFromHandle = controlFromHandle; + +--[[ Objeto Layout ]]-- + +gui.Layout = gui.Control.inherit(); +registerTag(gui.Layout, 'layout'); + +function gui.Layout:getFrameStyle() return _obj_getProp(self.handle, "FrameStyle"); end; +function gui.Layout:setFrameStyle(frameStyle) _obj_setProp(self.handle, "FrameStyle", frameStyle) end; + +function gui.Layout:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.Layout:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +gui.Layout.props["frameStyle"] = {setter = "setFrameStyle", getter = "getFrameStyle", tipo = "url"}; +gui.Layout.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; + + +--[[ Objeto Row ]]-- + +gui.Row = gui.Layout.inherit(); +registerTag(gui.Row, 'row'); + +--[[ Objeto Col ]]-- + +gui.Col = gui.Layout.inherit(); +registerTag(gui.Col, 'col'); + +--[[ Objeto Container ]]-- + +gui.Container = gui.Layout.inherit(); +registerTag(gui.Container, 'container'); + +--[[ Objeto Form Layout ]]-- + +local function __atualizarLockPopupWithTopStack(lockPopup) + local topStack = lockPopup.__topStackStatus; + + if topStack ~= nil then + lockPopup.__label.text = topStack.msg; + lockPopup.__label.visible = topStack.msg ~= ""; + end; +end; + +local function __lockFormWithActivity(form, msg) + local thePopup = rawget(form, "__lockWithActivityPopup"); + + if thePopup == nil then + -- criar o popup de lock + thePopup = gui.newPopup(); + thePopup.width = 280; + thePopup.height = 50; + thePopup.cancelable = false; + thePopup.drawContainer = false; + thePopup.autoScopeNode = false; + + thePopup.__indicator = gui.newActivityIndicator(); + thePopup.__indicator.align = "client"; + thePopup.__indicator.parent = thePopup; + + thePopup.__label = gui.newLabel(); + thePopup.__label.vertTextAlign = "leading"; + thePopup.__label.horzTextAlign = "center"; + thePopup.__label.autoSize = true; + thePopup.__label.wordWrap = true; + thePopup.__label.align = "bottom"; + thePopup.__label.parent = thePopup; + thePopup.__label.fontSize = 15; + + thePopup.parent = form; + rawset(form, "__lockWithActivityPopup", thePopup); + end; + + local stackStatus = {}; + stackStatus.msg = msg or ""; + stackStatus.anterior = thePopup.__topStackStatus; + thePopup.__topStackStatus = stackStatus; + + __atualizarLockPopupWithTopStack(thePopup); + + if not stackStatus.anterior then + -- Primeira chamada + thePopup.__indicator.enabled = true; + thePopup:show("center", form); + end; +end; + +local function __reallyCloseLockPopup(form, lockPopup) + lockPopup.__indicator.enabled = false; + lockPopup:close(); + rawset(form, "__lockWithActivityPopup", nil); -- Permitir o garbage collector coletar + + setTimeout(function() + lockPopup.parent = nil; + lockPopup.__label.parent = nil; + lockPopup.__indicator.parent = nil; + end, 3000); +end; + +local function __unlockFormWithActivity(form) + local thePopup = rawget(form, "__lockWithActivityPopup"); + + if thePopup == nil then + return true; + end; + + local topStack = thePopup.__topStackStatus; + + if topStack ~= nil then + topStack = topStack.anterior; + thePopup.__topStackStatus = topStack; + end; + + if topStack ~= nil then + __atualizarLockPopupWithTopStack(thePopup); + return false; + else + __reallyCloseLockPopup(form, thePopup); + return true; + end; +end; + +gui.Form = gui.Layout.inherit(); +registerTag(gui.Form, 'form'); + +function gui.Form:initialize() + rawset(self, "__isFormFlag", true); +end; + +function gui.Form:getWidth() return _obj_getProp(self.handle, "FormWidth"); end; +function gui.Form:setWidth(v) _obj_setProp(self.handle, "FormWidth", v); end; + +function gui.Form:getHeight() return _obj_getProp(self.handle, "FormHeight"); end; +function gui.Form:setHeight(v) _obj_setProp(self.handle, "FormHeight", v); end; + +function gui.Form:getLeft() return _obj_getProp(self.handle, "FormLeft"); end; +function gui.Form:setLeft(v) _obj_setProp(self.handle, "FormLeft", v); end; + +function gui.Form:getTop() return _obj_getProp(self.handle, "FormTop"); end; +function gui.Form:setTop(v) _obj_setProp(self.handle, "FormTop", v); end; + +function gui.Form:getTitle() return _obj_getProp(self.handle, "Title"); end; +function gui.Form:setTitle(title) _obj_setProp(self.handle, "Title", title) end; + +function gui.Form:getDescription() return _obj_getProp(self.handle, "Description"); end; +function gui.Form:setDescription(desc) _obj_setProp(self.handle, "Description", desc) end; + +function gui.Form:getDataType() return _obj_getProp(self.handle, "DataType"); end; +function gui.Form:setDataType(dataType) _obj_setProp(self.handle, "DataType", dataType) end; + +function gui.Form:getFormType() return _obj_getProp(self.handle, "FormType"); end; +function gui.Form:setFormType(formType) _obj_setProp(self.handle, "FormType", formType) end; + +function gui.Form:getTheme() return _obj_getProp(self.handle, "Theme"); end; +function gui.Form:setTheme(theme) _obj_setProp(self.handle, "Theme", theme) end; + +function gui.Form:getLockWhileNodeIsLoading() return _obj_getProp(self.handle, "LockWhileNodeIsLoading"); end; +function gui.Form:setLockWhileNodeIsLoading(v) _obj_setProp(self.handle, "LockWhileNodeIsLoading", v) end; + +function gui.Form:getMinWidth() return _obj_getProp(self.handle, "MinWidth"); end; +function gui.Form:setMinWidth(v) _obj_setProp(self.handle, "MinWidth", v) end; + +function gui.Form:getMaxWidth() return _obj_getProp(self.handle, "MaxWidth"); end; +function gui.Form:setMaxWidth(v) _obj_setProp(self.handle, "MaxWidth", v) end; + +function gui.Form:setNodeObject(nodeObject) + rawset(self, "nodeObject", nodeObject); + _gui_assignNodeObject(self.handle, ndb.getNodeHandle(nodeObject)); +end; + +function gui.Form:getNodeObject() return rawget(self, "nodeObject") end; +function gui.Form:getNode() return self:getNodeObject(); end; +function gui.Form:setNode(node) self:setNodeObject(node); end; +function gui.Form:getScopeNode() return self:getNodeObject(); end; +function gui.Form:setScopeNode(node) self:setNodeObject(node); end; + +function gui.Form:lockWithActivity(msg) return __lockFormWithActivity(self, msg); end; +function gui.Form:unlockWithActivity() return __unlockFormWithActivity(self); end; + +gui.Form.props["title"] = {setter = "setTitle", getter = "getTitle", tipo = "string"}; +gui.Form.props["description"] = {setter = "setDescription", getter = "getDescription", tipo = "string"}; +gui.Form.props["dataType"] = {setter = "setDataType", getter = "getDataType", tipo = "string"}; +gui.Form.props["formType"] = {setter = "setFormType", getter = "getDataType", tipo = "enum", + values = {"undefined", "sheetTemplate", "tablesDock"}}; +gui.Form.props["theme"] = {setter = "setTheme", getter = "getTheme", tipo = "enum", + values = {"default", "light", "dark", "firecast"}}; +gui.Form.props["lockWhileNodeIsLoading"] = {setter = "setLockWhileNodeIsLoading", getter = "getLockWhileNodeIsLoading", tipo = "bool"}; +gui.Form.props["scopeNode"] = {setter = "setScopeNode", getter = "getScopeNode", tipo = "table"}; +gui.Form.props["minWidth"] = {setter = "setMinWidth", getter = "getMinWidth", tipo = "double"}; +gui.Form.props["maxWidth"] = {setter = "setMaxWidth", getter = "getMaxWidth", tipo = "double"}; +gui.Form.props["isShowing"] = {readProp = "IsShowing", tipo = "bool"}; + +gui.Form.eves["onScopeNodeChanged"] = ""; +gui.Form.eves["onShow"] = ""; +gui.Form.eves["onHide"] = ""; +gui.Form.eves["onNodeReady"] = ""; +gui.Form.eves["onNodeUnready"] = ""; +gui.Form.eves["onNodeChanged"] = ""; + +--[[ Objeto Popup Form ]]-- + +gui.PopupForm = gui.Form.inherit(); +registerTag(gui.PopupForm, 'popupForm'); + +function gui.PopupForm:getDrawContainer() return _obj_getProp(self.handle, "DrawContainer"); end; +function gui.PopupForm:setDrawContainer(v) _obj_setProp(self.handle, "DrawContainer", v); end; + +function gui.PopupForm:getCancelable() return _obj_getProp(self.handle, "Cancelable"); end; +function gui.PopupForm:setCancelable(v) _obj_setProp(self.handle, "Cancelable", v); end; + +function gui.PopupForm:getPlacement() return _obj_getProp(self.handle, "Placement"); end; +function gui.PopupForm:setPlacement(v) _obj_setProp(self.handle, "Placement", v); end; + +function gui.PopupForm:getResizable() return _obj_getProp(self.handle, "Resizable"); end; +function gui.PopupForm:setResizable(v) _obj_setProp(self.handle, "Resizable", v); end; + +function gui.PopupForm:show() return gui.showPopup(self); end; +function gui.PopupForm:close() return gui.closePopup(self); end; + +gui.PopupForm.props["drawContainer"] = {setter = "setDrawContainer", getter = "getDrawContainer", tipo = "bool"}; +gui.PopupForm.props["cancelable"] = {setter = "setCancelable", getter = "getCancelable", tipo = "bool"}; +gui.PopupForm.props["resizable"] = {setter = "setResizable", getter = "getResizable", tipo = "bool"}; +gui.PopupForm.props["movable"] = {readProp = "Movable", writeProp = "Movable", tipo = "bool"}; + +gui.PopupForm.props["placement"] = {setter = "setPlacement", getter = "getPlacement", tipo = "enum", + values = {"center", "bottom", "top", "left", "right", + "topLeft", "topRight", "bottomLeft", "bottomRight", "mouse", "mouseCenter"}}; + +gui.PopupForm.eves["onCancelRequest"] = ""; + +--[[ Objeto Flow Part ]]-- + +gui.FlowPart = gui.Layout.inherit(); +registerTag(gui.FlowPart, 'flowPart'); + +function gui.FlowPart:getMinWidth() return _obj_getProp(self.handle, "MinWidth"); end; +function gui.FlowPart:setMinWidth(value) _obj_setProp(self.handle, "MinWidth", value) end; + +function gui.FlowPart:getMinScaledWidth() return _obj_getProp(self.handle, "MinScaledWidth"); end; +function gui.FlowPart:setMinScaledWidth(value) _obj_setProp(self.handle, "MinScaledWidth", value) end; + +function gui.FlowPart:getMaxWidth() return _obj_getProp(self.handle, "MaxWidth"); end; +function gui.FlowPart:setMaxWidth(value) _obj_setProp(self.handle, "MaxWidth", value) end; + +function gui.FlowPart:getMaxScaledWidth() return _obj_getProp(self.handle, "MaxScaledWidth"); end; +function gui.FlowPart:setMaxScaledWidth(value) _obj_setProp(self.handle, "MaxScaledWidth", value) end; + +function gui.FlowPart:getAvoidScale() return _obj_getProp(self.handle, "AvoidScale"); end; +function gui.FlowPart:setAvoidScale(value) _obj_setProp(self.handle, "AvoidScale", value) end; + +function gui.FlowPart:getVertAlign() return _obj_getProp(self.handle, "VerticalAlign"); end; +function gui.FlowPart:setVertAlign(value) _obj_setProp(self.handle, "VerticalAlign", value) end; + +function gui.FlowPart:getStepSizes() return _obj_getProp(self.handle, "StepSizes"); end; +function gui.FlowPart:setStepSizes(value) _obj_setProp(self.handle, "StepSizes", value) end; + +function gui.FlowPart:getAdjustHeightToLine() return _obj_getProp(self.handle, "AdjustHeightToLine"); end; +function gui.FlowPart:setAdjustHeightToLine(value) _obj_setProp(self.handle, "AdjustHeightToLine", value) end; + +gui.FlowPart.props["minWidth"] = {setter = "setMinWidth", getter = "getMinWidth", tipo = "double"}; +gui.FlowPart.props["minScaledWidth"] = {setter = "setMinScaledWidth", getter = "getMinScaledWidth", tipo = "double"}; +gui.FlowPart.props["maxWidth"] = {setter = "setMaxWidth", getter = "getMaxWidth", tipo = "double"}; +gui.FlowPart.props["maxScaledWidth"] = {setter = "setMaxScaledWidth", getter = "getMaxScaledWidth", tipo = "double"}; +gui.FlowPart.props["avoidScale"] = {setter = "setAvoidScale", getter = "getAvoidScale", tipo = "bool"}; + +gui.FlowPart.props["vertAlign"] = {setter = "setVertAlign", getter = "getVertAlign", tipo = "enum", + values={"leading", "center", "trailing"}}; + +gui.FlowPart.props["stepSizes"] = {setter = "setStepSizes", getter = "getStepSizes", tipo = "table"}; +gui.FlowPart.props["adjustHeightToLine"] = {setter = "setAdjustHeightToLine", getter = "getAdjustHeightToLine", tipo = "bool"}; + +--[[ Objeto Flow Layout ]]-- + +gui.FlowLayout = gui.FlowPart.inherit(); +registerTag(gui.FlowLayout, 'flowLayout'); + +function gui.FlowLayout:getAutoHeight() return _obj_getProp(self.handle, "AutoHeight"); end; +function gui.FlowLayout:setAutoHeight(value) _obj_setProp(self.handle, "AutoHeight", value) end; + +function gui.FlowLayout:getHorzAlign() return _obj_getProp(self.handle, "HorzAlign"); end; +function gui.FlowLayout:setHorzAlign(value) _obj_setProp(self.handle, "HorzAlign", value) end; + +function gui.FlowLayout:getMaxControlsPerLine() return _obj_getProp(self.handle, "MaxControlsPerLine"); end; +function gui.FlowLayout:setMaxControlsPerLine(value) _obj_setProp(self.handle, "MaxControlsPerLine", value) end; + +function gui.FlowLayout:getLineSpacing() return _obj_getProp(self.handle, "LineSpacing"); end; +function gui.FlowLayout:setLineSpacing(value) _obj_setProp(self.handle, "LineSpacing", value) end; + +function gui.FlowLayout:getOrientation() return _obj_getProp(self.handle, "Orientation"); end; +function gui.FlowLayout:setOrientation(value) _obj_setProp(self.handle, "Orientation", value) end; + +function gui.FlowLayout:getMaxColumns() return _obj_getProp(self.handle, "MaxColumns"); end; +function gui.FlowLayout:setMaxColumns(value) _obj_setProp(self.handle, "MaxColumns", value) end; + +function gui.FlowLayout:needRealign() _obj_invoke(self.handle, "NeedRealign"); end; + +gui.FlowLayout.props["autoHeight"] = {setter = "setAutoHeight", getter = "getAutoHeight", tipo = "bool"}; +gui.FlowLayout.props["horzAlign"] = {setter = "setHorzAlign", getter = "getHorzAlign", tipo = "enum", + values={"leading", "center", "trailing", "justify"}}; + +gui.FlowLayout.props["maxControlsPerLine"] = {setter = "setMaxControlsPerLine", getter = "getMaxControlsPerLine", tipo = "int"}; +gui.FlowLayout.props["lineSpacing"] = {setter = "setLineSpacing", getter = "getLineSpacing", tipo = "double"}; +gui.FlowLayout.props["orientation"] = {setter = "setOrientation", getter = "getOrientation", tipo = "enum", + values={"horizontal", "vertical"}}; +gui.FlowLayout.props["maxColumns"] = {setter = "setMaxColumns", getter = "getMaxColumns", tipo = "int"}; +gui.FlowLayout.props["contentWidth"] = {readProp = "ContentWidth", tipo = "double"}; +gui.FlowLayout.props["contentHeight"] = {readProp = "ContentHeight", tipo = "double"}; + +gui.FlowLayout.eves["onBeforeLayoutCalc"] = ""; +gui.FlowLayout.eves["onAfterLayoutCalc"] = ""; + +--[[ Objeto Flow Line Break ]]-- + +gui.FlowLineBreak = gui.Control.inherit(); +registerTag(gui.FlowLineBreak, 'flowLineBreak'); + +function gui.FlowLineBreak:getHorzAlign() return _obj_getProp(self.handle, "HorzAlign"); end; +function gui.FlowLineBreak:setHorzAlign(value) _obj_setProp(self.handle, "HorzAlign", value) end; + +function gui.FlowLineBreak:getLineSpacing() return _obj_getProp(self.handle, "LineSpacing"); end; +function gui.FlowLineBreak:setLineSpacing(value) _obj_setProp(self.handle, "LineSpacing", value) end; + +gui.FlowLineBreak.props["horzAlign"] = {setter = "setHorzAlign", getter = "getHorzAlign", tipo = "enum", + values={"leading", "center", "trailing", "justify"}}; + +gui.FlowLineBreak.props["lineSpacing"] = {setter = "setLineSpacing", getter = "getLineSpacing", tipo = "double"}; + +--[[ Text Controls]]-- + +local function _addFontPropertiesToObject(ctrl) + function ctrl:getFontColor() return _obj_getProp(self.handle, "FontColor"); end; + function ctrl:setFontColor(color) _gui_prepareForFontColorChange(self.handle); _obj_setProp(self.handle, "FontColor", color); end; + + function ctrl:getFontFamily() return _obj_getProp(self.handle, "Font.Family"); end; + function ctrl:setFontFamily(family) _gui_prepareForFontFamilyChange(self.handle); _obj_setProp(self.handle, "Font.Family", family); end; + + function ctrl:getFontSize() return _obj_getProp(self.handle, "Font.Size"); end; + function ctrl:setFontSize(fontSize) _gui_prepareForFontSizeChange(self.handle); _obj_setProp(self.handle, "Font.Size", fontSize); end; + + function ctrl:getFontStyle() return _obj_getProp(self.handle, "Font.Style"); end; + function ctrl:setFontStyle(fontStyle) _gui_prepareForFontStyleChange(self.handle); _obj_setProp(self.handle, "Font.Style", fontStyle); end; + + function ctrl:getFontHeight() return _gui_getFontHeight(self.handle); end; + + ctrl.props["fontColor"] = {setter = "setFontColor", getter = "getFontColor", tipo = "color"}; + ctrl.props["fontFamily"] = {setter = "setFontFamily", getter = "getFontFamily", tipo = "string"}; + ctrl.props["fontSize"] = {setter = "setFontSize", getter = "getFontSize", tipo = "double"}; + ctrl.props["fontStyle"] = {setter = "setFontStyle", getter = "getFontStyle", tipo = "set", + values = {"bold", "italic", "underline", "strikeout"}}; + + return ctrl; +end; + +local function _addTextStylePropsToObject(ctrl) + function ctrl:getHorzTextAlign() return _obj_getProp(self.handle, "TextAlign"); end; + function ctrl:setHorzTextAlign(textAlign) return _obj_setProp(self.handle, "TextAlign", textAlign); end; + + function ctrl:getVertTextAlign() return _obj_getProp(self.handle, "VertTextAlign"); end; + function ctrl:setVertTextAlign(textAlign) return _obj_setProp(self.handle, "VertTextAlign", textAlign); end; + + function ctrl:getWordWrap() return _obj_getProp(self.handle, "WordWrap"); end; + function ctrl:setWordWrap(wrap) return _obj_setProp(self.handle, "WordWrap", wrap == true); end; + + function ctrl:getTextTrimming() return _obj_getProp(self.handle, "Trimming"); end; + function ctrl:setTextTrimming(trimming) return _obj_setProp(self.handle, "Trimming", trimming); end; + + ctrl.props["horzTextAlign"] = {setter = "setHorzTextAlign", getter="getHorzTextAlign", tipo="enum", + values = {"center", "leading", "trailing"}}; + + ctrl.props["vertTextAlign"] = {setter = "setVertTextAlign", getter="getVertTextAlign", tipo="enum", + values = {"center", "leading", "trailing"}}; + + ctrl.props["wordWrap"] = {setter = "setWordWrap", getter="getWordWrap", tipo="bool"}; + + ctrl.props["textTrimming"] = {setter = "setTextTrimming", getter="getTextTrimming", tipo="enum", + values = {"none", "character", "word"}} + + return ctrl; +end; + +local function _addEditablePropsToObject(ctrl) + function ctrl:getReadOnly() return _obj_getProp(self.handle, "ReadOnly"); end; + function ctrl:setReadOnly(readonly) return _obj_setProp(self.handle, "ReadOnly", readonly); end; + + ctrl.props["readOnly"] = {setter="setReadOnly", getter="getReadOnly", tipo="bool"}; + ctrl.eves["onChange"] = ""; + + return ctrl; +end + +gui.TextControl = gui.Control.inherit(); +_addFontPropertiesToObject(gui.TextControl); +_addTextStylePropsToObject(gui.TextControl); + +function gui.TextControl:getText() return _obj_getProp(self.handle, "Text"); end; +function gui.TextControl:setText(text) return _obj_setProp(self.handle, "Text", text); end; + +function gui.TextControl:getStyledSettings() return _obj_getProp(self.handle, "StyledSettings"); end; +function gui.TextControl:setStyledSettings(settings) return _obj_setProp(self.handle, "StyledSettings", settings); end; + +gui.TextControl.props["text"] = {setter = "setText", getter = "getText", tipo = "string"}; +gui.TextControl.props["styledSettings"] = {setter = "setStyledSettings", getter = "getStyledSettings", tipo="set", + values = {"family", "size", "style", "fontcolor", "other"}}; + +--[[ Objeto Button ]]-- + +gui.Button = gui.TextControl.inherit(); +registerTag(gui.Button, 'button'); + +--[[ Objeto Label ]]-- + +gui.Label = gui.TextControl.inherit(); +registerTag(gui.Label, 'label'); + +function gui.Label:getAutoSize() return _obj_getProp(self.handle, "AutoSize"); end; +function gui.Label:setAutoSize(v) _obj_setProp(self.handle, "AutoSize", v); end; + +function gui.Label:getField() return _gui_getFieldName(self.handle); end; +function gui.Label:setField(v) _gui_setFieldName(self.handle, v); end; + +function gui.Label:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.Label:setFrameRegion(v) _obj_setProp(self.handle, "FrameRegion", v); end; + +gui.Label.props["autoSize"] = {setter = "setAutoSize", getter = "getAutoSize", tipo = "bool"}; +gui.Label.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.Label.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; +gui.Label.props["format"] = {writeProp = "StringFormat", readProp = "StringFormat", tipo = "string"}; +gui.Label.props["formatFloat"] = {writeProp = "StringFormatFloat", readProp = "StringFormatFloat", tipo = "string"}; + +--[[ Objeto CheckBox ]]-- + +gui.CheckBox = gui.TextControl.inherit(); +registerTag(gui.CheckBox, 'checkBox'); + +function gui.CheckBox:getChecked() return _obj_getProp(self.handle, "IsChecked"); end; +function gui.CheckBox:setChecked(v) return _obj_setProp(self.handle, "IsChecked", v); end; + +function gui.CheckBox:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.CheckBox:setField(v) return _obj_setProp(self.handle, "FieldName", v); end; + +gui.CheckBox.props["checked"] = {setter = "setChecked", getter = "getChecked", tipo = "bool"}; +gui.CheckBox.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; + +gui.CheckBox.eves["onChange"] = ""; + +--[[ Objeto RadioButton ]]-- + +gui.RadioButton = gui.TextControl.inherit(); +registerTag(gui.RadioButton, 'radioButton'); + +function gui.RadioButton:getChecked() return _obj_getProp(self.handle, "IsChecked"); end; +function gui.RadioButton:setChecked(v) return _obj_setProp(self.handle, "IsChecked", v); end; + +function gui.RadioButton:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.RadioButton:setField(v) return _obj_setProp(self.handle, "FieldName", v); end; + +function gui.RadioButton:getFieldValue() return _obj_getProp(self.handle, "FieldValue"); end; +function gui.RadioButton:setFieldValue(v) return _obj_setProp(self.handle, "FieldValue", v); end; + +function gui.RadioButton:getGroupName() return _obj_getProp(self.handle, "GroupName"); end; +function gui.RadioButton:setGroupName(v) return _obj_setProp(self.handle, "GroupName", v); end; + +gui.RadioButton.props["checked"] = {setter = "setChecked", getter = "getChecked", tipo = "bool"}; +gui.RadioButton.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.RadioButton.props["fieldValue"] = {setter = "setFieldValue", getter = "getFieldValue", tipo = "string"}; +gui.RadioButton.props["groupName"] = {setter = "setGroupName", getter = "getGroupName", tipo = "string"}; + +gui.RadioButton.eves["onChange"] = ""; + +--[[ Objeto ImageCheckBox ]]-- + +gui.ImageCheckBox = gui.Control.inherit(); +registerTag(gui.ImageCheckBox, 'imageCheckBox'); + +function gui.ImageCheckBox:getChecked() return _obj_getProp(self.handle, "IsChecked"); end; +function gui.ImageCheckBox:setChecked(v) _obj_setProp(self.handle, "IsChecked", v); end; + +function gui.ImageCheckBox:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.ImageCheckBox:setField(v) _obj_setProp(self.handle, "FieldName", v); end; + +function gui.ImageCheckBox:getImageChecked() return _obj_getProp(self.handle, "ImageChecked"); end; +function gui.ImageCheckBox:setImageChecked(v) _obj_setProp(self.handle, "ImageChecked", v); end; + +function gui.ImageCheckBox:getImageUnchecked() return _obj_getProp(self.handle, "ImageUnchecked"); end; +function gui.ImageCheckBox:setImageUnchecked(v) _obj_setProp(self.handle, "ImageUnchecked", v); end; + +function gui.ImageCheckBox:getOptimize() return _obj_getProp(self.handle, "Optimize"); end; +function gui.ImageCheckBox:setOptimize(opt) return _obj_setProp(self.handle, "Optimize", opt); end; + +function gui.ImageCheckBox:getAutoChange() return _obj_getProp(self.handle, "AutoChange"); end; +function gui.ImageCheckBox:setAutoChange(v) return _obj_setProp(self.handle, "AutoChange", v); end; + +gui.ImageCheckBox.props["checked"] = {setter = "setChecked", getter = "getChecked", tipo = "bool"}; +gui.ImageCheckBox.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.ImageCheckBox.props["imageChecked"] = {setter = "setImageChecked", getter = "getImageChecked", tipo = "url"}; +gui.ImageCheckBox.props["checkedImage"] = {setter = "setImageChecked", getter = "getImageChecked", tipo = "url"}; +gui.ImageCheckBox.props["imageUnchecked"] = {setter = "setImageUnchecked", getter = "getImageUnchecked", tipo = "url"}; +gui.ImageCheckBox.props["uncheckedImage"] = {setter = "setImageUnchecked", getter = "getImageUnchecked", tipo = "url"}; +gui.ImageCheckBox.props["optimize"] = {setter = "setOptimize", getter = "getOptimize", tipo = "bool"}; +gui.ImageCheckBox.props["autoChange"] = {setter = "setAutoChange", getter = "getAutoChange", tipo = "bool"}; + +gui.ImageCheckBox.eves["onChange"] = ""; + +--[[ Objeto Image ]]-- + +gui.Image = gui.Control.inherit(); +registerTag(gui.Image, 'image'); + +function gui.Image:getImageURL() return _obj_getProp(self.handle, "URLImagem"); end; +function gui.Image:setImageURL(url) return _obj_setProp(self.handle, "URLImagem", url); end; + +function gui.Image:getURL() return _obj_getProp(self.handle, "URLImagem"); end; +function gui.Image:setURL(url) return _obj_setProp(self.handle, "URLImagem", url); end; + +function gui.Image:getSRC() return _obj_getProp(self.handle, "URLImagem"); end; +function gui.Image:setSRC(src) return _obj_setProp(self.handle, "URLImagem", src); end; + +function gui.Image:getShowStyle() return _obj_getProp(self.handle, "ShowStyle"); end; +function gui.Image:setShowStyle(showStyle) return _obj_setProp(self.handle, "ShowStyle", showStyle); end; + +function gui.Image:getStyle() return _obj_getProp(self.handle, "ShowStyle"); end; +function gui.Image:setStyle(style) return _obj_setProp(self.handle, "ShowStyle", style); end; + +function gui.Image:getCenter() return _obj_getProp(self.handle, "Center"); end; +function gui.Image:setCenter(center) return _obj_setProp(self.handle, "Center", center); end; + +function gui.Image:getOptimizeQuality() return _obj_getProp(self.handle, "OtimizarDesenho"); end; +function gui.Image:setOptimizeQuality(opt) return _obj_setProp(self.handle, "OtimizarDesenho", opt); end; +function gui.Image:getOptimize() return _obj_getProp(self.handle, "OtimizarDesenho"); end; +function gui.Image:setOptimize(opt) return _obj_setProp(self.handle, "OtimizarDesenho", opt); end; + +function gui.Image:getShowProgress() return _obj_getProp(self.handle, "ExibirProgresso"); end; +function gui.Image:setShowProgress(showProgress) return _obj_setProp(self.handle, "ExibirProgresso", showProgress); end; + +function gui.Image:getURLWhileLoading() return _obj_getProp(self.handle, "NoImageURL"); end; +function gui.Image:setURLWhileLoading(url) return _obj_setProp(self.handle, "NoImageURL", url); end; + +function gui.Image:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.Image:setField(v) _obj_setProp(self.handle, "FieldName", v); end; + +function gui.Image:getEditable() return _obj_getProp(self.handle, "Editable"); end; +function gui.Image:setEditable(v) _obj_setProp(self.handle, "Editable", v); end; + +function gui.Image:getNaturalWidth() return _obj_getProp(self.handle, "NaturalWidth"); end; +function gui.Image:getNaturalHeight() return _obj_getProp(self.handle, "NaturalHeight"); end; + +gui.Image.props["imageURL"] = {setter = "setImageURL", getter="getImageURL", tipo="url"}; +gui.Image.props["url"] = {setter = "setURL", getter="getURL", tipo="url"}; +gui.Image.props["src"] = {setter = "setSRC", getter="getSRC", tipo="url"}; +gui.Image.props["URLWhileLoading"] = {setter = "setURLWhileLoading", getter="getURLWhileLoading", tipo="url"}; + +gui.Image.props["showStyle"] = {setter = "setShowStyle", getter="getShowStyle", tipo="enum", + values = {"proportional", "autoFit", "originalSize", "stretch"}}; +gui.Image.props["style"] = {setter = "setStyle", getter="getStyle", tipo="enum", + values = {"proportional", "autoFit", "originalSize", "stretch"}}; + +gui.Image.props["center"] = {setter = "setCenter", getter="getCenter", tipo="bool"}; +gui.Image.props["optimizeQuality"] = {setter = "setOptimizeQuality", getter="getOptimizeQuality", tipo="bool"}; +gui.Image.props["optimize"] = {setter = "setOptimize", getter="getOptimize", tipo="bool"}; +gui.Image.props["showProgress"] = {setter = "setShowProgress", getter="getShowProgress", tipo="bool"}; +gui.Image.props["field"] = {setter = "setField", getter="getField", tipo="string"}; +gui.Image.props["editable"] = {setter = "setEditable", getter="getEditable", tipo="bool"}; +gui.Image.props["naturalAnimated"] = {readProp="NaturalAnimated", tipo="bool"}; +gui.Image.props["naturalWidth"] = {getter="getNaturalWidth", tipo="double"}; +gui.Image.props["naturalHeight"] = {getter="getNaturalHeight", tipo="double"}; +gui.Image.props["animate"] = {readProp="Animate", writeProp="Animate", tipo="bool"}; + +gui.Image.eves["onPictureLoadedChange"] = ""; +gui.Image.eves["onLoad"] = ""; + +--[[ Objeto Edit ]]-- + +gui.Edit = gui.TextControl.inherit(); +registerTag(gui.Edit, 'edit'); + +_addEditablePropsToObject(gui.Edit); + +function gui.Edit:getTextPrompt() return _obj_getProp(self.handle, "TextPrompt"); end; +function gui.Edit:setTextPrompt(text) _obj_setProp(self.handle, "TextPrompt", text); end; + +function gui.Edit:getTransparent() _obj_getProp(self.handle, "Transparent"); end; +function gui.Edit:setTransparent(transparent) _obj_setProp(self.handle, "Transparent", transparent); end; + +function gui.Edit:getIsPasswordEdit() return _obj_getProp(self.handle, "Password"); end; +function gui.Edit:setIsPasswordEdit(isPasswordEdit) _obj_setProp(self.handle, "Password", isPasswordEdit); end; + +function gui.Edit:getKeyboardType() return _obj_getProp(self.handle, "KeyboardType"); end; +function gui.Edit:setKeyboardType(kbtype) _obj_setProp(self.handle, "KeyboardType", kbtype); end; + +function gui.Edit:getEnterKeyType() return _obj_getProp(self.handle, "ReturnKeyType"); end; +function gui.Edit:setEnterKeyType(enterType) _obj_setProp(self.handle, "ReturnKeyType", enterType); end; + +function gui.Edit:getField() return _gui_getFieldName(self.handle); end; +function gui.Edit:setField(field) _gui_setFieldName(self.handle, field); end; + +function gui.Edit:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.Edit:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +function gui.Edit:getType() return _obj_getProp(self.handle, "EditType"); end; +function gui.Edit:setType(v) _obj_setProp(self.handle, "EditType", v) end; + +function gui.Edit:getMin() return _obj_getProp(self.handle, "MinValue"); end; +function gui.Edit:setMin(v) _obj_setProp(self.handle, "MinValue", v) end; + +function gui.Edit:getMax() return _obj_getProp(self.handle, "MaxValue"); end; +function gui.Edit:setMax(v) _obj_setProp(self.handle, "MaxValue", v) end; + +function gui.Edit:getDecimalPlaces() return _obj_getProp(self.handle, "DecimalPlaces"); end; +function gui.Edit:setDecimalPlaces(v) _obj_setProp(self.handle, "DecimalPlaces", v) end; + +function gui.Edit:getAsNumber() return _obj_getProp(self.handle, "AsNumber"); end; +function gui.Edit:setAsNumber(v) _obj_setProp(self.handle, "AsNumber", v) end; + +gui.Edit.props["textPrompt"] = {setter="setTextPrompt", getter="getTextPrompt", tipo="string"}; +gui.Edit.props["transparent"] = {setter="setTransparent", getter="getTransparent", tipo="bool"}; +gui.Edit.props["isPasswordEdit"] = {setter="setIsPasswordEdit", getter="getIsPasswordEdit", tipo="bool"}; + +gui.Edit.props["keyboardType"] = {setter="setKeyboardType", getter="getKeyboardType", tipo="enum", + values = {"default", "numbersAndPunctuation", "numberPad", + "phonePad", "alphabet", "url", "email"}}; + +gui.Edit.props["enterKeyType"] = {setter="setEnterKeyType", getter="getEnterKeyType", tipo="enum", + values = {"default", "done", "go", "next", "search", "send"}}; + +gui.Edit.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.Edit.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; +gui.Edit.props["type"] = {setter = "setType", getter = "getType", tipo = "enum", values = {"text", "number", "float"}}; +gui.Edit.props["min"] = {setter = "setMin", getter = "getMin", tipo = "double"}; +gui.Edit.props["max"] = {setter = "setMax", getter = "getMax", tipo = "double"}; +gui.Edit.props["decimalPlaces"] = {setter = "setDecimalPlaces", getter = "getDecimalPlaces", tipo = "int"}; +gui.Edit.props["asNumber"] = {setter = "setAsNumber", getter = "getAsNumber", tipo = "double"}; + +gui.Edit.eves["onUserChange"] = ""; + +--[[ Objeto ComboBox ]]-- + +gui.ComboBox = gui.Control.inherit(); +registerTag(gui.ComboBox, 'comboBox'); + +_addFontPropertiesToObject(gui.ComboBox); +_addTextStylePropsToObject(gui.ComboBox); + +function gui.ComboBox:getTransparent() _obj_getProp(self.handle, "Transparent"); end; +function gui.ComboBox:setTransparent(transparent) _obj_setProp(self.handle, "Transparent", transparent); end; + +function gui.ComboBox:getField() return _gui_getFieldName(self.handle); end; +function gui.ComboBox:setField(field) _gui_setFieldName(self.handle, field); end; + +function gui.ComboBox:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.ComboBox:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +function gui.ComboBox:getText() return _obj_getProp(self.handle, "Text"); end; +function gui.ComboBox:setText(v) _obj_setProp(self.handle, "Text", v) end; + +function gui.ComboBox:getValue() return _obj_getProp(self.handle, "Value"); end; +function gui.ComboBox:setValue(v) _obj_setProp(self.handle, "Value", v) end; + +function gui.ComboBox:getItems() return _obj_getProp(self.handle, "ItemsI18N"); end; +function gui.ComboBox:setItems(v) _obj_setProp(self.handle, "ItemsI18N", v) end; + +function gui.ComboBox:getValues() return _obj_getProp(self.handle, "Values"); end; +function gui.ComboBox:setValues(v) _obj_setProp(self.handle, "Values", v) end; + +function gui.ComboBox:dropDown() _obj_invoke(self.handle, "InvokeDropDown"); end; + +gui.ComboBox.props["transparent"] = {setter="setTransparent", getter="getTransparent", tipo="bool"}; +gui.ComboBox.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.ComboBox.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; +gui.ComboBox.props["items"] = {setter = "setItems", getter = "getItems", tipo = "table"}; +gui.ComboBox.props["values"] = {setter = "setValues", getter = "getValues", tipo = "table"}; +gui.ComboBox.props["text"] = {setter = "setText", getter = "getText", tipo = "string"}; +gui.ComboBox.props["value"] = {setter = "setValue", getter = "getValue", tipo = "string"}; + +gui.ComboBox.eves["onChange"] = ""; + +--[[ Objeto ColorComboBox ]]-- + +gui.ColorComboBox = gui.Control.inherit(); +registerTag(gui.ColorComboBox, 'colorComboBox'); + +function gui.ColorComboBox:getColor() return _obj_getProp(self.handle, "Color"); end; +function gui.ColorComboBox:setColor(v) _obj_setProp(self.handle, "Color", v); end; + +function gui.ColorComboBox:getUseAlpha() return _obj_getProp(self.handle, "UseAlpha"); end; +function gui.ColorComboBox:setUseAlpha(v) _obj_setProp(self.handle, "UseAlpha", v); end; + +function gui.ColorComboBox:getField() return _gui_getFieldName(self.handle); end; +function gui.ColorComboBox:setField(field) _gui_setFieldName(self.handle, field); end; + +function gui.ColorComboBox:getFrameRegion() return _obj_getProp(self.handle, "FrameRegion"); end; +function gui.ColorComboBox:setFrameRegion(frameRegion) _obj_setProp(self.handle, "FrameRegion", frameRegion) end; + +function gui.ColorComboBox:dropDown() _obj_invoke(self.handle, "InvokeDropDown"); end; + +gui.ColorComboBox.props["color"] = {setter="setColor", getter="getColor", tipo="color"}; +gui.ColorComboBox.props["useAlpha"] = {setter = "setUseAlpha", getter = "getUseAlpha", tipo = "bool"}; +gui.ColorComboBox.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.ColorComboBox.props["frameRegion"] = {setter = "setFrameRegion", getter = "getFrameRegion", tipo = "string"}; + +gui.ColorComboBox.eves["onChange"] = ""; +gui.ColorComboBox.eves["onUserChange"] = ""; + +--[[ Objeto TextEditor ]]-- + +gui.TextEditor = gui.TextControl.inherit(); +registerTag(gui.TextEditor, 'textEditor'); + +_addEditablePropsToObject(gui.TextEditor); + +function gui.TextEditor:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.TextEditor:setField(v) _obj_setProp(self.handle, "FieldName", v); end; + +function gui.TextEditor:getTransparent() return _obj_getProp(self.handle, "Transparent"); end; +function gui.TextEditor:setTransparent(v) _obj_setProp(self.handle, "Transparent", v); end; + +gui.TextEditor.props["field"] = {setter="setField", getter="getField", tipo="string"}; +gui.TextEditor.props["transparent"] = {setter="setTransparent", getter="getTransparent", tipo="bool"}; + +--[[ Objeto TabControl ]]-- + +gui.TabControl = gui.Control.inherit(); +registerTag(gui.TabControl, 'tabControl'); + +function gui.TabControl:getTabIndex() return _obj_getProp(self.handle, "TabIndex"); end; +function gui.TabControl :setTabIndex(idx) _obj_setProp(self.handle, "TabIndex", idx); end; + +gui.TabControl .props["tabIndex"] = {setter="setTabIndex", getter="getTabIndex", tipo="int"}; + +--[[ Objeto Tab / TabItem ]]-- + +gui.TabItem = gui.Control.inherit(); +registerTag(gui.TabItem, 'tab'); + +function gui.TabItem:getText() return _obj_getProp(self.handle, "Title"); end; +function gui.TabItem:setText(text) _obj_setProp(self.handle, "Title", text); end; + +function gui.TabItem:getTitle() return _obj_getProp(self.handle, "Title"); end; +function gui.TabItem:setTitle(title) _obj_setProp(self.handle, "Title", title); end; +function gui.TabItem:activate() _obj_invoke(self.handle, "Activate"); end; + +gui.TabItem.props["text"] = {setter="setText", getter="getText", tipo="string"}; +gui.TabItem.props["title"] = {setter="setTitle", getter="getTitle", tipo="string"}; + +--[[ Objeto ScrollBox ]]-- + +gui.ScrollBox = gui.Control.inherit(); +registerTag(gui.ScrollBox, 'scrollBox'); + +--[[ Objeto Shape ]]-- + +gui.Shape = gui.Control.inherit(); + +function gui.Shape:getColor() return _obj_getProp(self.handle, "Fill.Color"); end; +function gui.Shape:setColor(color) _gui_shapeSetFillColor(self.handle, color); end; + +function gui.Shape:getStrokeColor() return _obj_getProp(self.handle, "Stroke.Color"); end; +function gui.Shape:setStrokeColor(color) _gui_shapeSetStrokeColor(self.handle, color); end; + +function gui.Shape:getStrokeSize() return _obj_getProp(self.handle, "Stroke.Thickness"); end; +function gui.Shape:setStrokeSize(size) _gui_shapeSetStrokeSize(self.handle, size); end; + +function gui.Shape:getStrokeCap() return _obj_getProp(self.handle, "Stroke.Cap"); end; +function gui.Shape:setStrokeCap(v) _gui_shapeSetStrokeCap(self.handle, v); end; + +function gui.Shape:getStrokeJoin() return _obj_getProp(self.handle, "Stroke.Join"); end; +function gui.Shape:setStrokeJoin(v) _gui_shapeSetStrokeCap(self.handle, v); end; + +function gui.Shape:getStrokeDash() return _obj_getProp(self.handle, "Stroke.Dash"); end; +function gui.Shape:setStrokeDash(v) _gui_shapeSetStrokeCap(self.handle, v); end; + +gui.Shape.props["color"] = {setter="setColor", getter="getColor", tipo="color"}; +gui.Shape.props["strokeColor"] = {setter="setStrokeColor", getter="getStrokeColor", tipo="color"}; +gui.Shape.props["strokeSize"] = {setter="setStrokeSize", getter="getStrokeSize", tipo="double"}; + +gui.Shape.props["strokeCap"] = {setter="setStrokeCap", getter="getStrokeCap", tipo="enum", + values={"flat", "round"}}; + +gui.Shape.props["strokeJoin"] = {setter="setStrokeJoin", getter="getStrokeJoin", tipo="enum", + values={"miter", "round", "bevel"}}; + +gui.Shape.props["strokeDash"] = {setter="setStrokeDash", getter="getStrokeDash", tipo="enum", + values={"solid", "dash", "dot", "dashDot", "dashDotDot"}}; + +--[[ Objeto Rectangle ]]-- + +gui.Rectangle = gui.Shape.inherit(); +registerTag(gui.Rectangle, 'rectangle'); + +function gui.Rectangle:getCorners() return _obj_getProp(self.handle, "Corners"); end; +function gui.Rectangle:setCorners(corners) _obj_setProp(self.handle, "Corners", corners); end; + +function gui.Rectangle:getCornerType() return _obj_getProp(self.handle, "CornerType"); end; +function gui.Rectangle:setCornerType(cornerType) _obj_setProp(self.handle, "CornerType", cornerType); end; + +function gui.Rectangle:getSides() return _obj_getProp(self.handle, "CornerType"); end; +function gui.Rectangle:setSides(sides) _obj_setProp(self.handle, "Sides", sides); end; + +function gui.Rectangle:getXradius() return _obj_getProp(self.handle, "XRadius"); end; +function gui.Rectangle:setXradius(xradius) _obj_setProp(self.handle, "XRadius", xradius); end; + +function gui.Rectangle:getYradius() return _obj_getProp(self.handle, "YRadius"); end; +function gui.Rectangle:setYradius(yradius) _obj_setProp(self.handle, "YRadius", yradius); end; + +gui.Rectangle.props["corners"] = {setter="setCorners", getter="getCorners", tipo="set", + values={"topLeft", "topRight", "bottomLeft", "bottomRight"}}; + +gui.Rectangle.props["cornerType"] = {setter="setCornerType", getter="getCornerType", tipo="enum", + values={"round", "bevel", "innerRound", "innerLine"}}; + +gui.Rectangle.props["sides"] = {setter="setSides", getter="getSides", tipo="set", + values={"top", "left", "bottom", "right"}}; + +gui.Rectangle.props["xradius"] = {setter="setXradius", getter="getXradius", tipo="double"}; +gui.Rectangle.props["yradius"] = {setter="setYradius", getter="getYradius", tipo="double"}; + +--[[ Objeto Path ]]-- + +gui.Path = gui.Shape.inherit(); +registerTag(gui.Path, 'path'); + +function gui.Path:getPathData() return _obj_getProp(self.handle, "PathData"); end; +function gui.Path:setPathData(v) _obj_setProp(self.handle, "PathData", v); end; + +function gui.Path:getMode() return _obj_getProp(self.handle, "WrapMode"); end; +function gui.Path:setMode(v) _obj_setProp(self.handle, "WrapMode", v); end; + +function gui.Path:getRoundToPixel() return _obj_getProp(self.handle, "RoundToPixels"); end; +function gui.Path:setRoundToPixel(v) _obj_setProp(self.handle, "RoundToPixels", v); end; + +gui.Path.props["data"] = {setter="setPathData", getter="getPathData", tipo="string"}; +gui.Path.props["pathData"] = gui.Path.props["data"] + +gui.Path.props["mode"] = {setter="setMode", getter="getMode", tipo="enum", + values={"original", "fit", "stretch", "tile"}}; + +gui.Path.props["wrapMode"] = gui.Path.props["mode"] +gui.Path.props["roundToPixel"] = {setter="setRoundToPixel", getter="getRoundToPixel", tipo="bool"}; + +--[[ Objeto HorzLine ]]-- + +gui.HorzLine = gui.Shape.inherit(); +registerTag(gui.HorzLine, 'horzLine'); + +--[[ Objeto Frame ]]-- + +gui.Frame = gui.Layout.inherit(); +registerTag(gui.Frame, 'frame'); + +function gui.Frame:getURL() return _obj_getProp(self.handle, "FrameURL"); end; +function gui.Frame:setURL(url) _obj_setProp(self.handle, "FrameURL", url); end; + +function gui.Frame:getFrameStyle() return _obj_getProp(self.handle, "FrameURL"); end; +function gui.Frame:setFrameStyle(frameStyle) _obj_setProp(self.handle, "FrameURL", frameStyle); end; + +function gui.Frame:getSrc() return _obj_getProp(self.handle, "FrameURL"); end; +function gui.Frame:setSrc(url) _obj_setProp(self.handle, "FrameURL", url); end; + +gui.Frame.props["url"] = {setter="setURL", getter="getURL", tipo="url"}; +gui.Frame.props["frameStyle"] = {setter="setFrameStyle", getter="getFrameStyle", tipo="url"}; +gui.Frame.props["src"] = {setter="setSrc", getter="getSrc", tipo="url"}; + + +--[[ Objeto DataLink ]]-- + +gui.DataLink = objs.HierarchyObject.inherit(); +registerTag(gui.DataLink, 'dataLink'); + +function gui.DataLink:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.DataLink:setField(v) return _obj_setProp(self.handle, "FieldName", v); end; + +function gui.DataLink:getFields() return _obj_getProp(self.handle, "Fields"); end; +function gui.DataLink:setFields(v) return _obj_setProp(self.handle, "Fields", v); end; + +function gui.DataLink:getDefaultValue() return _obj_getProp(self.handle, "DefaultValue"); end; +function gui.DataLink:setDefaultValue(v) return _obj_setProp(self.handle, "DefaultValue", v); end; + +function gui.DataLink:getDefaultValues() return _obj_getProp(self.handle, "DefaultValues"); end; +function gui.DataLink:setDefaultValues(v) return _obj_setProp(self.handle, "DefaultValues", v); end; + +function gui.DataLink:beginUpdate() end; +function gui.DataLink:endUpdate() end; + +gui.DataLink.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.DataLink.props["fields"] = {setter = "setFields", getter = "getFields", tipo = "table"}; +gui.DataLink.props["defaultValue"] = {setter = "setDefaultValue", getter = "getDefaultValue", tipo = "string"}; +gui.DataLink.props["defaultValues"] = {setter = "setDefaultValues", getter = "getDefaultValues", tipo = "table"}; + +gui.DataLink.eves["onChange"] = "field, oldValue, newValue"; +gui.DataLink.eves["onPersistedChange"] = "field, oldValue, newValue"; +gui.DataLink.eves["onUserChange"] = "field, oldValue, newValue"; +gui.DataLink.eves["onChildAdded"] = "node"; +gui.DataLink.eves["onChildRemoved"] = "node"; + +--[[ Objeto Record List ]]-- + +gui.RecordList = gui.Layout.inherit(); +registerTag(gui.RecordList, 'recordList'); + +function gui.RecordList:getField() return _obj_getProp(self.handle, "FieldName"); end; +function gui.RecordList:setField(v) _obj_setProp(self.handle, "FieldName", v) end; + +function gui.RecordList:getItemHeight() return _obj_getProp(self.handle, "ItemHeight"); end; +function gui.RecordList:setItemHeight(v) _obj_setProp(self.handle, "ItemHeight", v) end; + +function gui.RecordList:getMinHeight() return _obj_getProp(self.handle, "MinHeight"); end; +function gui.RecordList:setMinHeight(v) _obj_setProp(self.handle, "MinHeight", v) end; + +function gui.RecordList:getMinQt() return _obj_getProp(self.handle, "MinQt"); end; +function gui.RecordList:setMinQt(v) _obj_setProp(self.handle, "MinQt", v) end; + +function gui.RecordList:getAutoHeight() return _obj_getProp(self.handle, "AutoHeight"); end; +function gui.RecordList:setAutoHeight(v) _obj_setProp(self.handle, "AutoHeight", v) end; + +function gui.RecordList:getTemplateForm() return _obj_getProp(self.handle, "TemplateForm"); end; +function gui.RecordList:setTemplateForm(v) _obj_setProp(self.handle, "TemplateForm", v); end; + +function gui.RecordList:getLayout() return _obj_getProp(self.handle, "RecordListLayout"); end; +function gui.RecordList:setLayout(v) _obj_setProp(self.handle, "RecordListLayout", v); end; + +function gui.RecordList:getSelectable() return _obj_getProp(self.handle, "SelectableList"); end; +function gui.RecordList:setSelectable(v) _obj_setProp(self.handle, "SelectableList", v); end; + +function gui.RecordList:append() return ndb.openNodeFacade(_obj_invokeEx(self.handle, "AppendItemEx")); end; + +function gui.RecordList:getSelectedNode() return ndb.openNodeFacade(_gui_recordListGetSelectedNodeHandle(self.handle)); end; +function gui.RecordList:setSelectedNode(node) _gui_recordListSetSelectedNodeHandle(self.handle, ndb.getNodeHandle(node)); end; + +function gui.RecordList:getSelectedForm() return objs.tryFindFromHandle(_gui_recordListGetSelectedFormHandle(self.handle)); end; + +function gui.RecordList:scrollToNode(node) _gui_recordListScrollToNodeHandle(self.handle, ndb.getNodeHandle(node)); end; +function gui.RecordList:sort() _obj_invoke(self.handle, "ReorganizarItens"); end; + +function gui.RecordList:getChildren() + local ret = {}; + local childCount = _obj_getProp(self.handle, "ChildFormCount"); + local child; + local childHandle; + local idxDest = 1; + + for i = 0, childCount - 1, 1 do + childHandle = _gui_rcl_getChild(self.handle, i); + + if (childHandle ~= nil) then + child = gui.fromHandle(childHandle); + + if (type(child) == "table") then + ret[idxDest] = child; + idxDest = idxDest + 1; + end + end; + end + + return ret; +end; + +gui.RecordList.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.RecordList.props["templateForm"] = {setter = "setTemplateForm", getter = "getTemplateForm", tipo = "string"}; +gui.RecordList.props["itemHeight"] = {setter = "setItemHeight", getter = "getItemHeight", tipo = "double"}; +gui.RecordList.props["minHeight"] = {setter = "setMinHeight", getter = "getMinHeight", tipo = "double"}; +gui.RecordList.props["autoHeight"] = {setter = "setAutoHeight", getter = "getAutoHeight", tipo = "bool"}; +gui.RecordList.props["minQt"] = {setter = "setMinQt", getter = "getMinQt", tipo = "int"}; +gui.RecordList.props["layout"] = {setter = "setLayout", getter = "getLayout", tipo = "enum", + values = {"vertical", "horizontal", "horizontalTiles", "verticalTiles"}}; +gui.RecordList.props["selectable"] = {setter = "setSelectable", getter = "getSelectable", tipo = "bool"}; + +gui.RecordList.props["selectedNode"] = {getter = "getSelectedNode", setter="setSelectedNode", tipo = "table"}; +gui.RecordList.props["selectedForm"] = {getter = "getSelectedForm", tipo = "table"}; + +gui.RecordList.eves["onSelect"] = ""; +gui.RecordList.eves["onBeginEnumeration"] = ""; +gui.RecordList.eves["onItemAdded"] = "node, form"; +gui.RecordList.eves["onItemRemoved"] = "node, form"; +gui.RecordList.eves["onEndEnumeration"] = ""; +gui.RecordList.eves["onCompare"] = "nodeA, nodeB"; + +--[[ Objeto GridRecordList ]]-- + +gui.GridRecordList = gui.Layout.inherit(); +registerTag(gui.GridRecordList, 'gridRecordList'); + +function gui.GridRecordList:append() return ndb.openNodeFacade(_obj_invokeEx(self.handle, "AppendItemEx")); end; +function gui.GridRecordList:reorganize() _obj_invoke(self.handle, "Reorganize"); end; +function gui.GridRecordList:getChildren() return _gui_getChildrenObj(self.handle); end; +function gui.GridRecordList:getSelectedNode() return _obj_invokeEx(self.handle, "GetSelectedNodeEx"); end; +function gui.GridRecordList:setSelectedNode(node) _obj_invokeEx(self.handle, "SetSelectedNodeEx", node); end; +function gui.GridRecordList:getSelectedForm() return _obj_invokeEx(self.handle, "GetSelectedFormEx"); end; +function gui.GridRecordList:scrollToNode(node) _obj_invokeEx(self.handle, "ScrollToNodeEx", node); end; + +gui.GridRecordList.props["field"] = {writeProp = "DataFieldName", readProp = "DataFieldName", tipo = "string"}; +gui.GridRecordList.props["templateForm"] = {writeProp = "TemplateForm", readProp = "TemplateForm", tipo = "string"}; +gui.GridRecordList.props["minQt"] = {writeProp = "MinQuantity", readProp = "MinQuantity", tipo = "int"}; +gui.GridRecordList.props["selectable"] = {writeProp = "IsSelectableList", readProp = "IsSelectableList", tipo = "bool"}; +gui.GridRecordList.props["selectedNode"] = {getter = "getSelectedNode", setter="setSelectedNode", tipo = "table"}; +gui.GridRecordList.props["paging"] = {writeProp = "IsPagingEnabled", readProp = "IsPagingEnabled", tipo = "bool"}; +gui.GridRecordList.props["pageSize"] = {writeProp = "PageSize", readProp = "PageSize", tipo = "int"}; +gui.GridRecordList.props["pageIndex"] = {writeProp = "PageIndex", readProp = "PageIndex", tipo = "int"}; +gui.GridRecordList.props["filterFields"] = {writeProp = "FilteringFields", readProp = "FilteringFields", tipo = "table"}; + +gui.GridRecordList.props["selectedForm"] = {getter = "getSelectedForm", tipo = "table"}; +gui.GridRecordList.props["pageCount"] = {readProp = "PageCount", tipo = "int"}; + +gui.GridRecordList.eves["onSelect"] = ""; +gui.GridRecordList.eves["onItemAdded"] = "node"; +gui.GridRecordList.eves["onItemRemoved"] = "node"; +gui.GridRecordList.eves["onItemFiltered"] = "node"; +gui.GridRecordList.eves["onItemUnfiltered"] = "node"; +gui.GridRecordList.eves["onItemShow"] = "node, form"; +gui.GridRecordList.eves["onItemHide"] = "node, form"; +gui.GridRecordList.eves["onCompare"] = "left, right"; +gui.GridRecordList.eves["onFilter"] = "node"; +gui.GridRecordList.eves["onGroupId"] = "node"; +gui.GridRecordList.eves["onGroupCompare"] = "left, right"; +gui.GridRecordList.eves["onGroupHeader"] = "id"; +gui.GridRecordList.eves["onGroupShow"] = "id, header"; +gui.GridRecordList.eves["onGroupHide"] = "id, header"; +gui.GridRecordList.eves["onEmptyState"] = ""; +gui.GridRecordList.eves["onPagingStateChange"] = ""; +gui.GridRecordList.eves["onBeginOrganization"] = ""; +gui.GridRecordList.eves["onEndOrganization"] = ""; + +--[[ Objeto GridRecordListPgCtrl ]]-- + +gui.GridRecordListPgNav = gui.Layout.inherit(); +registerTag(gui.GridRecordListPgNav, 'gridRecordListPgNav'); + +function gui.GridRecordListPgNav:setTarget(value) _obj_invokeEx(self.handle, 'SetGridRecordList', value); end; +function gui.GridRecordListPgNav:getTarget() return _obj_invokeEx(self.handle, 'GetGridRecordList'); end; + +gui.GridRecordListPgNav.props["target"] = {setter = "setTarget", getter = "getTarget", tipo = "obj", class=gui.GridRecordList}; + +--[[ Objeto DataScopeBox ]]-- + +gui.DataScopeBox = gui.Layout.inherit(); +registerTag(gui.DataScopeBox, 'dataScopeBox'); + +function gui.DataScopeBox:getNodeObject() return rawget(self, "__nodeObject"); end; + +function gui.DataScopeBox:setNodeObject(nodeObject) + rawset(self, "__nodeObject", nodeObject); + _gui_assignNodeObject(self.handle, ndb.getNodeHandle(nodeObject)); +end; + +gui.DataScopeBox.props["scopeNode"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.DataScopeBox.props["nodeObject"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.DataScopeBox.props["node"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; + +gui.DataScopeBox.eves["onNodeReady"] = ""; +gui.DataScopeBox.eves["onNodeUnready"] = ""; +gui.DataScopeBox.eves["onNodeChanged"] = ""; + +--[[ Objeto RichEdit ]]-- + +gui.RichEdit = gui.Control.inherit(); +registerTag(gui.RichEdit, 'richEdit'); + +function gui.RichEdit:getField() return _gui_getFieldName(self.handle); end; +function gui.RichEdit:setField(v) _gui_setFieldName(self.handle, v); end; + +function gui.RichEdit:beginEdit() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LBeginEdit") end; end; +function gui.RichEdit:endEdit() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEndEdit") end; end; + +function gui.RichEdit:selectAll() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LSelectAll") end; end; +function gui.RichEdit:unselect() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LUnselect") end; end; +function gui.RichEdit:getSelectionPosInChars() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionPosInChars"); else return 0, 0; end; end; +function gui.RichEdit:getSelectionPosInGlyphs() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionPosInGlyphs"); else return 0, 0; end; end; +function gui.RichEdit:getIsSelectionForward() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetIsSelectionForward"); else return true; end; end; +function gui.RichEdit:getSelectionText() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionText"); else return ""; end; end; +function gui.RichEdit:getSelectionURL() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionURL"); else return ""; end; end; +function gui.RichEdit:getSelectionFontColor() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontColor"); else return "Black"; end; end; +function gui.RichEdit:getSelectionFontBkgColor() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontBkgColor"); else return "White"; end; end; +function gui.RichEdit:getSelectionFontSize() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontSize"); else return 14; end; end; +function gui.RichEdit:getSelectionFontFamily() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontFamily"); else return "Roboto"; end; end; +function gui.RichEdit:getSelectionFontStyle() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFontStyle"); else return {}; end; end; +function gui.RichEdit:getSelectionFloat() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionFloat"); else return "none"; end; end; +function gui.RichEdit:getSelectionParaAlign() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetSelectionParaAlign"); else return "left"; end; end; + +function gui.RichEdit:gotoStart(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoStart", holdSelection); end; end; +function gui.RichEdit:gotoEnd(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoEnd", holdSelection); end; end; +function gui.RichEdit:gotoNext(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoNext", holdSelection); end; end; +function gui.RichEdit:gotoPrevious(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPrevious", holdSelection); end; end; +function gui.RichEdit:gotoStartOfLine(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoStartOfLine", holdSelection); end; end; +function gui.RichEdit:gotoEndOfLine(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoEndOfLine", holdSelection); end; end; +function gui.RichEdit:gotoNextWord(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoNextWord", holdSelection); end; end; +function gui.RichEdit:gotoPreviousWord(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPreviousWord", holdSelection); end; end; +function gui.RichEdit:gotoLineUp(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoLineUp", holdSelection); end; end; +function gui.RichEdit:gotoLineDown(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoLineDown", holdSelection); end; end; +function gui.RichEdit:gotoPageUp(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPageUp", holdSelection); end; end; +function gui.RichEdit:gotoPageDown(holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPageDown", holdSelection); end; end; +function gui.RichEdit:gotoPositionInGlyphs(pos, holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPositionInGlyphs", pos, holdSelection); end; end; +function gui.RichEdit:gotoPositionInChars(pos, holdSelection) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGotoPositionInChars", pos, holdSelection); end; end; + +function gui.RichEdit:copySelectionToClipboard() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LCopySelectionToClipboard"); end; end; + +function gui.RichEdit:deleteSelection() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_DeleteSelection"); end; end; +function gui.RichEdit:insertText(text) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_InsertText", text); end; end; +function gui.RichEdit:insertTalemark(talemarkText, talemarkOptions, talemarkSheetStyle) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_InsertTalemark", talemarkText, talemarkOptions, talemarkSheetStyle); end; end; +function gui.RichEdit:insertImage(params) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_InsertImage", params); end; end; +function gui.RichEdit:breakLine() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_BreakLine"); end; end; +function gui.RichEdit:breakParagraph() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_BreakParagraph"); end; end; +function gui.RichEdit:indent(qty) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_Indent", qty); end; end; +function gui.RichEdit:pasteFromClipboard() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_PasteFromClipboard"); end; end; +function gui.RichEdit:cutSelectionToClipboard() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_CutSelectionToClipboard"); end; end; +function gui.RichEdit:setSelectionURL(url) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionURL", url); end; end; +function gui.RichEdit:setSelectionFontColor(color) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontColor", color); end; end; +function gui.RichEdit:setSelectionFontBkgColor(color) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontBkgColor", color); end; end; +function gui.RichEdit:setSelectionFontSize(size) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontSize", size); end; end; +function gui.RichEdit:setSelectionFontFamily(family) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontFamily", family); end; end; +function gui.RichEdit:setSelectionFontStyle(style) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFontStyle", style); end; end; +function gui.RichEdit:setSelectionFloat(floatMode) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionFloat", floatMode); end; end; +function gui.RichEdit:setSelectionParaAlign(paraAlign) if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LEditOp_SetSelectionParaAlign", paraAlign); end; end; + +function gui.RichEdit:getLengthInChars() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetLengthInChars"); else return 0; end; end; +function gui.RichEdit:getLengthInGlyphs() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetLengthInGlyphs"); else return 0; end; end; +function gui.RichEdit:getText() if System.checkAPIVersion(87, 4) then return _obj_invokeEx(self.handle, "LGetText"); else return ""; end; end; + +gui.RichEdit.props["animateImages"] = {readProp = "CanAnimateImages", writeProp = "CanAnimateImages", tipo = "bool"}; +gui.RichEdit.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.RichEdit.props["backgroundColor"] = {readProp = "BackgroundColor", writeProp = "BackgroundColor", tipo = "color"}; +gui.RichEdit.props["defaultFontColor"] = {readProp = "DefaultFontColor", writeProp = "DefaultFontColor", tipo = "color"}; +gui.RichEdit.props["defaultFontSize"] = {readProp = "DefaultFontSize", writeProp = "DefaultFontSize", tipo = "double"}; +gui.RichEdit.props["showToolbar"] = {readProp = "ShowToolbar", writeProp = "ShowToolbar", tipo = "bool"}; +gui.RichEdit.props["readOnly"] = {readProp = "ReadOnly", writeProp = "ReadOnly", tipo = "bool"}; +gui.RichEdit.props["hideSelection"] = {readProp = "HideSelectionNoFocus", writeProp = "HideSelectionNoFocus", tipo = "bool"}; + +--[[ Objeto Popup ]]-- + +gui.Popup = gui.Layout.inherit(); +registerTag(gui.Popup, 'popup'); + +function gui.Popup:getCancelable() return _obj_getProp(self.handle, "Cancelavel"); end; +function gui.Popup:setCancelable(v) _obj_setProp(self.handle, "Cancelavel", v) end; + +function gui.Popup:getBackOpacity() return _obj_getProp(self.handle, "BackOpacity"); end; +function gui.Popup:setBackOpacity(v) _obj_setProp(self.handle, "BackOpacity", v) end; + +function gui.Popup:getDrawContainer() return _obj_getProp(self.handle, "DesenharPopupContainer"); end; +function gui.Popup:setDrawContainer(v) _obj_setProp(self.handle, "DesenharPopupContainer", v) end; + +function gui.Popup:setNodeObject(nodeObject) + rawset(self, "nodeObject", nodeObject); + _gui_assignNodeObject(self.handle, ndb.getNodeHandle(nodeObject)); +end; + +function gui.Popup:getNodeObject() return rawget(self, "nodeObject") end; + +function gui.Popup:showPopupEx(placement, control) + if type(placement) ~= "string" then + placement = "center"; + end; + + _obj_setProp(self.handle, "Placement", placement); + + if (type(control) == "table") and (control.handle ~= nil) then + _obj_setProp(self.handle, "TargetControlHandle", control.handle); + else + _obj_setProp(self.handle, "TargetControlHandle", 0); + end; + + _obj_invoke(self.handle, "ExibirPopup"); +end; + +gui.Popup.show = gui.Popup.showPopupEx; +gui.Popup.showPopup = gui.Popup.showPopupEx; + +function gui.Popup:closePopup(cancelar, forcar) _obj_invoke(self.handle, "FecharPopup", cancelar == true, forcar == true); end; +function gui.Popup:close(cancelar, forcar) _obj_invoke(self.handle, "FecharPopup", cancelar == true, forcar == true); end; + +gui.Popup.props["cancelable"] = {setter = "setCancelable", getter = "getCancelable", tipo = "bool"}; +gui.Popup.props["backOpacity"] = {setter = "setBackOpacity", getter = "getBackOpacity", tipo = "double"}; +gui.Popup.props["drawContainer"] = {setter = "setDrawContainer", getter = "getDrawContainer", tipo = "bool"}; +gui.Popup.props["scopeNode"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.Popup.props["nodeObject"] = {setter = "setNodeObject", getter = "getNodeObject", tipo = "table"}; +gui.Popup.props["node"] = gui.Popup.props["nodeObject"]; +gui.Popup.props["scopeNode"] = gui.Popup.props["nodeObject"]; +gui.Popup.props["autoScopeNode"] = {writeProp = "AutoScopeNode", readProp = "AutoScopeNode", tipo = "bool"}; + +gui.Popup.eves["onClose"] = "canceled"; +gui.Popup.eves["onCanClose"] = "canceled"; +gui.Popup.eves["onCalculateSize"] = "dueToResize, width, height"; + +gui.Popup.eves["onNodeReady"] = ""; +gui.Popup.eves["onNodeUnready"] = ""; +gui.Popup.eves["onNodeChanged"] = ""; + +--[[ Objeto Progress Bar ]]-- + +gui.ProgressBar = gui.Control.inherit(); +registerTag(gui.ProgressBar, 'progressBar'); + +function gui.ProgressBar:getColor() return _obj_getProp(self.handle, "Color"); end; +function gui.ProgressBar:setColor(v) _obj_setProp(self.handle, "Color", v) end; + +function gui.ProgressBar:getPosition() return _obj_getProp(self.handle, "Value"); end; +function gui.ProgressBar:setPosition(v) _obj_setProp(self.handle, "Value", v) end; + +function gui.ProgressBar:getMin() return _obj_getProp(self.handle, "Min"); end; +function gui.ProgressBar:setMin(v) _obj_setProp(self.handle, "Min", v) end; + +function gui.ProgressBar:getMax() return _obj_getProp(self.handle, "Max"); end; +function gui.ProgressBar:setMax(v) _obj_setProp(self.handle, "Max", v) end; + +function gui.ProgressBar:getField() return _obj_getProp(self.handle, "Field"); end; +function gui.ProgressBar:setField(v) _obj_setProp(self.handle, "Field", v); end; + +function gui.ProgressBar:getFieldMin() return _obj_getProp(self.handle, "FieldMin"); end; +function gui.ProgressBar:setFieldMin(v) _obj_setProp(self.handle, "FieldMin", v); end; + +function gui.ProgressBar:getFieldMax() return _obj_getProp(self.handle, "FieldMax"); end; +function gui.ProgressBar:setFieldMax(v) _obj_setProp(self.handle, "FieldMax", v); end; + +function gui.ProgressBar:getMouseGlow() return _obj_getProp(self.handle, "MouseGlow"); end; +function gui.ProgressBar:setMouseGlow(v) _obj_setProp(self.handle, "MouseGlow", v); end; + +function gui.ProgressBar:getColorMode() return _obj_getProp(self.handle, "ColorMode"); end; +function gui.ProgressBar:setColorMode(v) _obj_setProp(self.handle, "ColorMode", v); end; + +gui.ProgressBar.props["color"] = {setter = "setColor", getter = "getColor", tipo = "color"}; +gui.ProgressBar.props["position"] = {setter = "setPosition", getter = "getPosition", tipo = "double"}; +gui.ProgressBar.props["value"] = {setter = "setPosition", getter = "getPosition", tipo = "double"}; +gui.ProgressBar.props["min"] = {setter = "setMin", getter = "getMin", tipo = "double"}; +gui.ProgressBar.props["max"] = {setter = "setMax", getter = "getMax", tipo = "double"}; +gui.ProgressBar.props["field"] = {setter = "setField", getter = "getField", tipo = "string"}; +gui.ProgressBar.props["fieldMin"] = {setter = "setFieldMin", getter = "getFieldMin", tipo = "string"}; +gui.ProgressBar.props["fieldMax"] = {setter = "setFieldMax", getter = "getFieldMax", tipo = "string"}; +gui.ProgressBar.props["mouseGlow"] = {setter = "setMouseGlow", getter = "getMouseGlow", tipo = "bool"}; +gui.ProgressBar.props["colorMode"] = {setter = "setColorMode", getter = "getColorMode", tipo = "enum", values={"default", "hl"}}; + +--[[ Objeto Timer ]]-- + +gui.Timer = objs.Timer; +registerTag(gui.Timer, 'timer'); + + +--[[ Objeto ActivityIndicator ]]-- + +gui.ActivityIndicator = gui.Control.inherit(); +registerTag(gui.ActivityIndicator, 'activityIndicator'); + +--[[ Objeto InertialMovement ]]-- + +gui.InertialMovement = objs.newClass() +registerTag(gui.InertialMovement, 'TInertialMovement'); + +gui.newInertialMovement = gui.InertialMovement.new; + +function gui.InertialMovement:setPos(x, y) _obj_invoke(self.handle, "SetPosition", x, y); end; +function gui.InertialMovement:getPos() return _obj_invokeEx(self.handle, "ExGetPosition"); end; +function gui.InertialMovement:setBounds(minX, minY, maxX, maxY) _obj_invoke(self.handle, "SetBounds", minX, minY, maxX, maxY); end; +function gui.InertialMovement:pointerDown(x, y) _obj_invoke(self.handle, "PointerDown", x, y); end; +function gui.InertialMovement:pointerMove(x, y) _obj_invoke(self.handle, "PointerMove", x, y); end; +function gui.InertialMovement:pointerUp(x, y) _obj_invoke(self.handle, "PointerUp", x, y); end; +function gui.InertialMovement:pointerLeave() _obj_invoke(self.handle, "PointerLeave"); end; +function gui.InertialMovement:pointerWheel(deltaX, deltaY) _obj_invoke(self.handle, "PointerWheel", deltaX, deltaY); end; + +gui.InertialMovement.props["active"] = {tipo = "boolean", readProp = "Active", writeProp="Active"}; +gui.InertialMovement.props["animated"] = {tipo = "boolean", readProp = "Animated", writeProp="Animated"}; +gui.InertialMovement.props["decelerationRate"] = {tipo = "double", readProp = "DecelerationRate", writeProp="DecelerationRate"}; + +gui.InertialMovement.eves["onChange"] = ""; + +--[[ Objeto Drag n Drop ]]-- + +local Serializer = nil; + +local __DragDropDataProps = {dataCount = {tipo = "int", readProp = "DataCount"}}; + +local __DragDropDataMethods = + { + addData = function(d, dataType, dataValue) + _obj_invokeEx(d.handle, "AddData", dataType, Serializer.packData(dataValue)); + end, + + getData = function(d, dataType) + return Serializer.unpackData(_obj_invokeEx(d.handle, "GetData", dataType)); + end + }; + +local __DragProps = {actionCount = {tipo = "int", readProp = "ActionCount"}}; + +local __DragMethods = + { + addAction = function(d, dataType, callback) + if type(callback) == "function" then + _gui_addDragAction(d.handle, dataType, callback); + end; + end + }; + +local __DragEvents = {}; + +local __DropProps = {actionCount = {tipo = "int", readProp = "ActionCount"}}; + +local __DropMethods = + { + addAction = function(d, dataType, callback) + if type(callback) == "function" then + _gui_addDropAction(d.handle, dataType, callback); + end; + end + }; + +local __DropEvents = {}; + +local function dragDropDataObjectFromHandle(handle) + if Serializer == nil then + Serializer = require("utils.serializer.dlua"); + end; + + local obj = objs.objectFromHandle(handle); + + if obj.props == nil then + obj.props = {}; + end; + + for k, v in pairs(__DragDropDataProps) do + obj.props[k] = v; + end; + + for k, v in pairs(__DragDropDataMethods) do + rawset(obj, k, v); + end; + + return obj; +end; + +local function dragObjectFromHandle(handle) + local obj = dragDropDataObjectFromHandle(handle); + + for k, v in pairs(__DragProps) do + obj.props[k] = v; + end; + + for k, v in pairs(__DragMethods) do + rawset(obj, k, v); + end; + + obj.eves = __DragEvents; + return obj; +end + +function gui.newDrag() + return gui.fromHandle(_obj_newObject("TDragObject")); +end; + +guiLoaders["TDragObject"] = dragObjectFromHandle; + +local function dropObjectFromHandle(handle) + local obj = dragDropDataObjectFromHandle(handle); + + for k, v in pairs(__DropProps) do + obj.props[k] = v; + end; + + for k, v in pairs(__DropMethods) do + rawset(obj, k, v); + end; + + obj.eves = __DropEvents; + return obj; +end + +function gui.newDrop() + return gui.fromHandle(_obj_newObject("TDropObject")); +end; + +guiLoaders["TDropObject"] = dropObjectFromHandle; + +function __export__guiInitDropObject(dropUserData) + local d = gui.newDrop(); + _gui_initDragDropDataObject(d.handle, dropUserData); + return d; +end; + +function __export__guiInitDragObject(dragUserData) + local d = gui.newDrag(); + _gui_initDragDropDataObject(d.handle, dragUserData); + return d; +end; + +--[[ API gui ]]-- + +function gui.fromHandle(handle) + if (handle == nil) then + return nil; + end + + local ctrl = objs.tryFindFromHandle(handle); + + if (ctrl ~= nil) then + return ctrl; + end; + + local className = _obj_getClassName(handle); + + if (className == nil) then + return nil; + end; + + local loader = guiLoaders[className]; + + if (loader ~= nil) then + ctrl = loader(handle); + else + ctrl = controlFromHandle(handle); + end + + objs.registerHandleIfNeeded(handle, ctrl); + return ctrl; +end; + +function gui.findControlByName(controlName, referenceControl) + local parentMost; + local p; + + if (type(referenceControl) ~= "table") or (referenceControl.handle == nil) then + return nil; + end; + + local child; + + child = referenceControl:findChildByName(controlName, true); + + if child ~= nil then + return child; + end; + + -- Else, vamos ir ate a RAIZ procurar a partir dela o objeto sem fazer analise recursiva + + parentMost = nil; + p = referenceControl; + + while p ~= nil do + if (type(p) == "table") and (p.findChildByName ~= nil) then + parentMost = p; + child = parentMost:findChildByName(controlName, false, true); -- não fazer analise recursiva neste ponto ainda + + if child ~= nil then + return child; + end; + end; + + p = p:getParent(); + end; + + if parentMost == nil then + return nil; + elseif parentMost.name == controlName then + return parentMost; + end; + + return parentMost:findChildByName(controlName, true); +end; + +findControlByName = gui.findControlByName; + +function gui.newForm(formName) + if (formName == nil) then + return gui.Form.new(); + end; + + if (type(formName) == "string" and (rrpg ~= nil)) then + local formFactory = rrpg.forms[formName]; + + if formFactory ~= nil then + local frm = formFactory.newEditor(); + assert(frm ~= nil); + + return frm; + else + error("Form name not found: '" .. formName .. "'"); + end; + end; + + return nil; +end; + +function gui.newPopupForm(formName) + if (formName == nil) then + return gui.fromHandle(_obj_newObject("popupForm")); + end; + + if (type(formName) == "string" and (rrpg ~= nil)) then + local formFactory = rrpg.forms[formName]; + + if (formFactory ~= nil) and (formFactory.formComponentName == "popupForm") then + local frm = formFactory.newEditor(); + assert(frm ~= nil); + + return frm; + else + error("PopupForm name not found: '" .. formName .. "'"); + end; + end; + + return nil; +end; + +local function formParameterToObjectForm(form) + local retorno = nil; + + if (type(form) == "string") then + retorno = gui.newForm(form); + elseif (type(form) == "table") then + local handle = rawget(form, "handle"); + + if (handle ~= nil) and (rawget(form, "__isFormFlag")) then + retorno = form; + end; + end; + + return retorno; +end; + +local _popupFormShowers = {}; +setmetatable(_popupFormShowers, {__mode="k"}); -- popupFormShowers possui chaves weak-reference + +function gui.showPopup(form, options) + if (form == nil) then + error("invalid parameter - form is nil"); + return false; + end; + + if type(options) ~= "table" then + options = {}; + end; + + options.placement = options.placement or "center"; + form = formParameterToObjectForm(form); + + if (form == nil) then + return false; + end; + + local popupShower = _popupFormShowers[form]; + + if popupShower == nil then + popupShower = rrpgObjs.componentFromHandle(_obj_newObject('TLuaFiremonkeyPopupShower')); + rrpgObjs.registerHandleIfNeeded(popupShower.handle, popupShower); + _popupFormShowers[form] = popupShower; + + local frmHandle = form.handle; + _obj_invoke(popupShower.handle, "SetFormHandle", frmHandle); + + popupShower:addEventListener("OnPopupClose", + function() + local frmRef = objs.tryFindFromHandle(frmHandle); + + if frmRef ~= nil then + _popupFormShowers[frmRef] = nil; + end; + end); + end; + + local closeListenerId = rawget(popupShower, "__closeListenerID"); + + if closeListenerId ~= nil then + popupShower:removeEventListener(closeListenerId); + rawset(popupShower, "__closeListenerID", nil); + end; + + if type(options.onClose) == "function" then + closeListenerId = popupShower:addEventListener("OnPopupClose", options.onClose); + rawset(popupShower, "__closeListenerID", closeListenerId); + end; + + _obj_setProp(popupShower.handle, "PopupPlacement", options.placement); + return _obj_invoke(popupShower.handle, "Show"); +end; + +function gui.closePopup(form) + if type(form) == "table" then + for k, v in pairs(_popupFormShowers) do + if k == form then + return _obj_invoke(v.handle, "Close"); + end; + end; + elseif type(form) == "string" then + local fechouAlgum = false; + + for k, v in pairs(_popupFormShowers) do + if (type(k) == "table") and (k.name == form) then + fechouAlgum = fechouAlgum or _obj_invoke(v.handle, "Close"); + end; + end; + + return fechouAlgum; + else + return false; + end; +end; + +function gui.openInBrowser(url) + if type(url) == "string" then + local achado = url:find("https?://"); + + if achado ~= 1 then + url = "http://" .. url; + end; + + return _gui_openInBrowser(url); + end; +end; + +function gui.asyncOpenFirecastURI(uri, params) + local promiseHandle = _obj_invokeEx(gui.handle, "AsyncOpenFirecastURI", uri, params); + return Async.Promise.wrap(promiseHandle); +end; + +function gui.toast(message) + return _gui_toast(message); +end; + +function gui.getShiftState() + return _gui_getShiftState(); +end; + +-- [ Form cache control ]-- + +local __frmCachedByTime = {cacheName = {}, countByName = {}, genCacheId = 1}; + +function __frmCachedByTime:tryAcquireByName(name) + if (type(name) ~= "string") or (name == "") then + return nil; + end; + + local formsWithSameName = self.cacheName[name]; + + if formsWithSameName ~= nil then + local form = nil; + + for k, v in pairs(formsWithSameName) do + if (type(k) == "table") and (v ~= nil) then + form = k; + break; + end; + end; + + if form ~= nil then + formsWithSameName[form] = nil; + self.countByName[name] = (self.countByName[name] or 0) - 1; + + if self.countByName[name] <= 0 then + self.cacheName[name] = nil; + self.countByName[name] = nil; + end; + + rawset(form, '__timeCacheId', nil); + + local timeoutId = rawget(form, '__timeCacheTimeoutId'); + + if timeoutId ~= nil then + Utils.clearTimeout(timeoutId); + rawset(form, '__timeCacheTimeoutId', nil); + end; + + return form; + else + return nil; + end; + else + return nil; + end; +end; + +function __frmCachedByTime:createTimeoutCallback(name, form, cacheId) + return function() + local currentCacheId = rawget(form, "__timeCacheId"); + local formsWithSameName = self.cacheName[name]; + + if (formsWithSameName ~= nil) and (currentCacheId == cacheId) then + -- Remove from cache to let GC collect the form + + rawset(form, '__timeCacheId', nil); + rawset(form, '__timeCacheTimeoutId', nil); + + formsWithSameName[form] = nil; + self.countByName[name] = (self.countByName[name] or 0) - 1; + + if self.countByName[name] <= 0 then + self.cacheName[name] = nil; + self.countByName[name] = nil; + end; + end; + end; +end; + +function __frmCachedByTime:releaseByName(name, form) + assert(form ~= nil); + + if (type(name) ~= "string") or (name == "") then + return; + end; + + if form.setNodeDatabase ~= nil then + form:setNodeDatabase(nil); + end; + + form:setParent(nil); + + local formsWithSameName = self.cacheName[name]; + + if formsWithSameName == nil then + formsWithSameName = {}; + self.cacheName[name] = formsWithSameName; + self.countByName[name] = 0; + end; + + formsWithSameName[form] = true; + self.countByName[name] = (self.countByName[name] or 0) + 1; + + self.genCacheId = self.genCacheId + 1; + + local cacheId = self.genCacheId; + rawset(form, '__timeCacheId', cacheId); + + local timeoutId = Utils.setTimeout(self:createTimeoutCallback(name, form, cacheId), gui.DEFAULT_FORM_CACHE_TIMEOUT); + rawset(form, '__timeCacheTimeoutId', timeoutId); +end; + +-- [[ Exported functions ]] -- + +function _export_gui_fromHandle(handle) + return gui.fromHandle(handle); +end; + +function _export_gui_acquireForm(formName) + if Firecast == nil then + require('rrpg.lua'); + end; + + assert(Firecast ~= nil); + local frmClass = Firecast.forms[formName]; + + if frmClass ~= nil then + local frm = nil; + + if frmClass.cacheMode == "time" then + frm = __frmCachedByTime:tryAcquireByName(formName); + end; + + if frm ~= nil then + return frm; + end; + + frm = frmClass.newEditor(); + assert(frm ~= nil); + + rawset(frm, "__cachedFrmClass", frmClass); + return frm; + else + return nil; + end; +end; + +function _export_gui_releaseForm(form) + if form == nil then + return; + end; + + local cachedFrmClass = rawget(form, "__cachedFrmClass"); + local cacheMode; + + if cachedFrmClass ~= nil then + cacheMode = cachedFrmClass.cacheMode; + else + cacheMode = nil; + end; + + if cacheMode == "time" then + __frmCachedByTime:releaseByName(cachedFrmClass.name, form); + end; +end; + +return gui; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI_grid.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI_grid.dlua new file mode 100644 index 00000000..42ce9b30 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgGUI_grid.dlua @@ -0,0 +1,244 @@ +local Objs = require("rrpgObjs.lua"); + +local SCREEN_SIZES_ARRAY = {"xs", "sm", "md", "lg", "xl"}; +local VALID_SCREEN_SIZE_STR_DICT = {}; + +for i = 1, #SCREEN_SIZES_ARRAY, 1 do + VALID_SCREEN_SIZE_STR_DICT[SCREEN_SIZES_ARRAY[i]] = true; +end; + +-- Class Declaration + +local Grid = Objs.newClass(); + +function Grid.shouldUseScreenSizeStr(value) + return (value ~= nil) and (type(value) == "string") and VALID_SCREEN_SIZE_STR_DICT[value]; +end; + +function __registerScreenSizePropFor_specificScreenSize(screenSize, details, outerGetter, outerSetter) + local wrappedSetter = + function(instance, value) + return outerSetter(instance, screenSize, value); + end; + + local wrappedGetter = + function (instance) + return outerGetter(instance, screenSize); + end; + + local propDetais = {getter=wrappedGetter, setter=wrappedSetter, tipo=details.tipo, values=details.values}; + + if screenSize ~= nil then + if details.lfmName ~= nil then + Grid.props[details.lfmName .. "-" .. screenSize] = propDetais; + else + Grid.props[details.luaName .. "-" .. screenSize] = propDetais; + end; + else + if details.lfmName ~= nil then + Grid.props[details.lfmName] = propDetais; + else + Grid.props[details.luaName] = propDetais; + end; + end; +end; + +local function __registerScreenSizeProp(details) + local hostSetterMethodName = "Set" .. details.hostName; + local hostGetterMethodName = "Get" .. details.hostName; + local luaFirstLetterUpperCasePropName = details.luaName:gsub("^%l", string.upper); + + local setter = + function (instance, screenSizeOrValue, value) + if Grid.shouldUseScreenSizeStr(screenSizeOrValue) then + _obj_invokeEx(instance.handle, hostSetterMethodName, screenSizeOrValue, value); + elseif (screenSizeOrValue ~= nil) then + if value == nil then + _obj_invokeEx(instance.handle, hostSetterMethodName, nil, screenSizeOrValue); + else + error('Invalid ScreenSize: "' .. tostring(screenSizeOrValue) .. '"'); + end; + else + _obj_invokeEx(instance.handle, hostSetterMethodName, nil, value); + end; + + return instance; + end; + + local getter = + function (instance, screenSize) + if Grid.shouldUseScreenSizeStr(screenSize) then + return _obj_invokeEx(instance.handle, hostGetterMethodName, screenSize); + else + return _obj_invokeEx(instance.handle, hostGetterMethodName, nil); + end; + end; + + Grid["set" .. luaFirstLetterUpperCasePropName] = setter; + Grid["get" .. luaFirstLetterUpperCasePropName] = getter; + + __registerScreenSizePropFor_specificScreenSize(nil, details, getter, setter) + + for i = 1, #SCREEN_SIZES_ARRAY do + __registerScreenSizePropFor_specificScreenSize(SCREEN_SIZES_ARRAY[i], details, getter, setter); + end; +end; + +local function __registerNonScreenSizeProp(details) + local hostPropertyNamme = details.hostName; + local luaFirstLetterUpperCasePropName = details.luaName:gsub("^%l", string.upper); + local useDefaultValue = details.useDefaultValueOnSet; + local defaultValue = details.defaultValueOnSet; + + local setter = + function (instance, value) + if (value == nil) and useDefaultValue then + _obj_setProp(instance.handle, hostPropertyNamme, defaultValue); + else + _obj_setProp(instance.handle, hostPropertyNamme, value); + end; + + return instance; + end; + + local getter = + function (instance) + return _obj_getProp(instance.handle, hostPropertyNamme); + end; + + Grid["set" .. luaFirstLetterUpperCasePropName] = setter; + Grid["get" .. luaFirstLetterUpperCasePropName] = getter; + + local propDetais = {getter=getter, setter=setter, tipo=details.tipo, values=details.values}; + Grid.props[details.luaName] = propDetais; + + if details.lfmName ~= nil then + Grid.props[details.lfmName] = propDetais; + end; +end; + +local function __registerScreenSizeEvent_specificScreenSize(screenSize, details, setterWithScreenSizeArgument) + local eve = {arguments = details.arguments}; + + eve.setter = + function(instance, value) + setterWithScreenSizeArgument(instance, screenSize, value); + end; + + if screenSize == nil then + if details.lfmName ~= nil then + Grid.eves[details.lfmName] = eve; + else + Grid.eves[details.luaName] = eve; + end; + else + if details.lfmName ~= nil then + Grid.eves[details.lfmName .. "-" .. screenSize] = eve; + else + Grid.eves[details.luaName .. "-" .. screenSize] = eve; + end; + end; +end; + +local function __registerScreenSizeEvent(details) + local hostSetterMethodName = "Set" .. details.hostName; + + local setterWithScreenSizeArgument = + function(instance, screenSize, value) + _obj_invokeEx(instance.handle, hostSetterMethodName, screenSize, value); + return instance; + end; + + __registerScreenSizeEvent_specificScreenSize(nil, details, setterWithScreenSizeArgument) + + for i = 1, #SCREEN_SIZES_ARRAY do + __registerScreenSizeEvent_specificScreenSize(SCREEN_SIZES_ARRAY[i], details, setterWithScreenSizeArgument); + end; +end; + +function Grid:invalidate() + _obj_invokeEx(self.handle, "Invalidate"); + return self; +end; + +function Grid:reset() + _obj_invokeEx(self.handle, "Reset"); + return self; +end; + +function Grid:getTxtWidth() + return _obj_invokeEx(self.handle, "GetTxtWidth"); +end; + +local GRID_VERT_ALIGN_VALUES = {"top", "center", "middle", "bottom"}; +local GRID_HORZ_ALIGN_VALUES = {"start", "center", "end", "around", "between", "left", "right", "middle"}; +local GRID_CONTAINER_HORZ_ALIGN_VALUES = {"start", "center", "end", "left", "right", "middle"}; + +-- Grid Properties + +__registerNonScreenSizeProp({luaName="role", hostName="Role", tipo="enum", values={"none", "row", "col", "block", "container"}}); +__registerNonScreenSizeProp({luaName="root", hostName="Root", tipo="bool", useDefaultValueOnSet=true, defaultValueOnSet=true}); +__registerNonScreenSizeProp({luaName="screenSizeDet", lfmName="screen-size-det", hostName="ScreenSizeDeterminator", tipo="bool", useDefaultValueOnSet=true, defaultValueOnSet=true}); +__registerNonScreenSizeProp({luaName="autoHeight", lfmName="auto-height", hostName="AutoHeight", tipo="bool", useDefaultValueOnSet=true, defaultValueOnSet=true}); + +__registerScreenSizeProp({luaName="width", hostName="Width", tipo="int"}); +__registerScreenSizeProp({luaName="offset", lfmName="offset", hostName="Offset", tipo="int"}); +__registerScreenSizeProp({luaName="push", lfmName="push", hostName="Push", tipo="int"}); +__registerScreenSizeProp({luaName="pull", lfmName="pull", hostName="Pull", tipo="int"}); +__registerScreenSizeProp({luaName="cntVertAlign", lfmName="cnt-vert-align", hostName="CntVertAlign", tipo="enum", values=GRID_VERT_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="cntHorzAlign", lfmName="cnt-horz-align", hostName="CntHorzAlign", tipo="enum", values=GRID_HORZ_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="cntGutter", lfmName="cnt-gutter", hostName="CntGutter", tipo="double"}); +__registerScreenSizeProp({luaName="cntLineSpacing", lfmName="cnt-line-spacing", hostName="CntLineSpacing", tipo="double"}); +__registerScreenSizeProp({luaName="cntMinGridWidth", lfmName="cnt-min-grid-width", hostName="CntMinGridWidth", tipo="double"}); +__registerScreenSizeProp({luaName="cntMinGridWidthFt", lfmName="cnt-min-grid-width-ft", hostName="CntMinGridWidthFt", tipo="double"}); +__registerScreenSizeProp({luaName="invisibleReserved", lfmName="invisible-reserved", hostName="InvisibleReserved", tipo="bool"}); +__registerScreenSizeProp({luaName="vertAlign", lfmName="vert-align", hostName="SelfVertAlign", tipo="enum", values=GRID_VERT_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="gutter", lfmName="gutter", hostName="SelfGutter", tipo="double"}); +__registerScreenSizeProp({luaName="horzAlign", lfmName="horz-align", hostName="SelfHorzAlign", tipo="enum", values=GRID_CONTAINER_HORZ_ALIGN_VALUES}); +__registerScreenSizeProp({luaName="breakLineBefore", lfmName="break-line-before", hostName="BreakLineBefore", tipo="bool"}); +__registerScreenSizeProp({luaName="breakLineAfter", lfmName="break-line-after", hostName="BreakLineAfter", tipo="bool"}); +__registerScreenSizeProp({luaName="order", lfmName="order", hostName="Order", tipo="int"}); +__registerScreenSizeProp({luaName="group", lfmName="group", hostName="Group", tipo="int"}); +__registerScreenSizeProp({luaName="marginLeft", lfmName="margin-left", hostName="MarginLeft", tipo="double"}); +__registerScreenSizeProp({luaName="marginTop", lfmName="margin-top", hostName="MarginTop", tipo="double"}); +__registerScreenSizeProp({luaName="marginRight", lfmName="margin-right", hostName="MarginRight", tipo="double"}); +__registerScreenSizeProp({luaName="marginBottom", lfmName="margin-bottom", hostName="MarginBottom", tipo="double"}); +__registerScreenSizeProp({luaName="paddingLeft", lfmName="padding-left", hostName="PaddingLeft", tipo="double"}); +__registerScreenSizeProp({luaName="paddingTop", lfmName="padding-top", hostName="PaddingTop", tipo="double"}); +__registerScreenSizeProp({luaName="paddingRight", lfmName="padding-right", hostName="PaddingRight", tipo="double"}); +__registerScreenSizeProp({luaName="paddingBottom", lfmName="padding-bottom", hostName="PaddingBottom", tipo="double"}); +__registerScreenSizeProp({luaName="dynWidthTxt", lfmName="dyn-width-txt", hostName="DynWidthTxt", tipo="bool"}); +__registerScreenSizeProp({luaName="dynHeightTxt", lfmName="dyn-height-txt", hostName="DynHeightTxt", tipo="bool"}); +__registerScreenSizeProp({luaName="postDynWidthTxt", lfmName="post-dyn-width-txt", hostName="PostDynWidthTxt", tipo="bool"}); +__registerScreenSizeProp({luaName="finalOffsetX", lfmName="final-offset-x", hostName="FinalOffsetX", tipo="double"}); +__registerScreenSizeProp({luaName="finalOffsetY", lfmName="final-offset-y", hostName="FinalOffsetY", tipo="double"}); +__registerScreenSizeProp({luaName="vertTile", lfmName="vert-tile", hostName="VertTile", tipo="bool"}); +__registerScreenSizeProp({luaName="vertTileWeight", lfmName="vert-tile-weight", hostName="VertTileWeight", tipo="double"}); +__registerScreenSizeProp({luaName="horzTile", lfmName="horz-tile", hostName="HorzTile", tipo="bool"}); +__registerScreenSizeProp({luaName="minHeight", lfmName="min-height", hostName="MinHeight", tipo="double"}); +__registerScreenSizeProp({luaName="maxHeight", lfmName="max-height", hostName="MaxHeight", tipo="double"}); +__registerScreenSizeProp({luaName="minWidth", lfmName="min-width", hostName="MinWidth", tipo="double"}); +__registerScreenSizeProp({luaName="maxWidth", lfmName="max-width", hostName="MaxWidth", tipo="double"}); + +__registerScreenSizeProp({luaName="dynWidthSingleLine", lfmName="dyn-width-single-line", hostName="DynWidthSingleLine", tipo="bool"}); +__registerScreenSizeProp({luaName="dynWidthEachLine", lfmName="dyn-width-each-line", hostName="DynWidthEachLine", tipo="bool"}); +__registerScreenSizeProp({luaName="dynWidthMatchHeight", lfmName="dyn-width-match-height", hostName="DynWidthMatchHeight", tipo="bool"}); + + +-- Grid Events +__registerScreenSizeEvent({luaName="onPrepare", lfmName="on-prepare", hostName="OnPrepare", arguments="screenSize"}); +__registerScreenSizeEvent({luaName="onAligned", lfmName="on-aligned", hostName="OnAligned", arguments="screenSize, changedBounds, childChangedBounds"}); +__registerScreenSizeEvent({luaName="onGetWidth", lfmName="on-get-width", hostName="OnGetWidth", arguments="screenSize, width"}); +__registerScreenSizeEvent({luaName="onGetHeight", lfmName="on-get-height", hostName="OnGetHeight", arguments="screenSize, height"}); +__registerScreenSizeEvent({luaName="onGetVertMargins", lfmName="on-get-vert-margins", hostName="OnGetVertMargins", arguments="screenSize, height, top, bottom"}); + +-- Instance + +function Grid.new(ctrl) + assert(ctrl ~= nil); + + local g = Grid.fromHandle(_obj_newObject("TLuaGridControl", ctrl.handle)); + return g; +end; + +return Grid; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgLFM.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgLFM.lua new file mode 100644 index 00000000..1fc7525b --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgLFM.lua @@ -0,0 +1,428 @@ +require("rrpgUtil.lua"); +require("rrpgGUI.lua"); + +local serpent = nil; +local lfmObjectsStrongRef = {}; + +function lfm_getObject(ctrlOrHandle) + if ctrlOrHandle == nil then + return nil; + elseif isNumber(ctrlOrHandle) then + return lfmObjectsStrongRef[ctrlOrHandle]; + else + return ctrlOrHandle; + end; +end; + +function lfm_newObjectHandle(className) + local obj = gui.fromHandle(_obj_newObject(className)); + lfmObjectsStrongRef[obj.handle] = obj; + return obj.handle; +end; + +function lfm_destroyObject(ctrlOrHandle) + local obj = lfm_getObject(ctrlOrHandle); + + if obj ~= nil then + lfmObjectsStrongRef[obj.handle] = nil; + obj:destroy(); + end +end + +function lfm_enumEvents(ctrlOrHandle) + local obj = lfm_getObject(ctrlOrHandle); + + local eves = {}; + local qt = 0; + local alreadyListedEves = {}; + + local function processEvent(eventName, eventData) + if not alreadyListedEves[eventName] then + alreadyListedEves[eventName] = true; + + local eveRec = {name = eventName}; + + if type(eventData) == "table" then + eveRec.parameters = eventData.arguments or ""; + else + eveRec.parameters = eventData or ""; + end; + + qt = qt + 1; + eves[qt] = eveRec; + end; + end; + + -- Instance Defined Events + local definedEves = obj.eves; + + if definedEves ~= nil then + for k, v in pairs(obj.eves) do + processEvent(k, v); + end; + end; + + -- Class Defined Events + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + definedEves = currentClass.eves; + + if definedEves ~= nil then + for k, v in pairs(definedEves) do + processEvent(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return eves; +end; + +local function __copyPropTable(propName, prop) + local tbl = {name = propName, tipo = prop.tipo, values = prop.values, getter = prop.getter, setter = prop.setter}; + + if (prop.tipo == "obj") and (type(prop.class) == "table") then + tbl.refClassTagName = prop.class.tagName; + end; + + return tbl; +end; + +function lfm_enumProps(ctrlOrHandle) + local obj = lfm_getObject(ctrlOrHandle); + + local props = {}; + local qt = 0; + local alreadyListedProps = {}; + + local function processProp(propName, prop) + if not alreadyListedProps[propName] then + alreadyListedProps[propName] = true; + qt = qt + 1; + props[qt] = __copyPropTable(propName, prop); + end; + end; + + -- Instance Defined Props + local definedProps = obj.props; + + if definedProps ~= nil then + for k, v in pairs(definedProps) do + processProp(k, v); + end; + end; + + -- Class Defined Props + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + definedProps = currentClass.props; + + if definedProps ~= nil then + for k, v in pairs(definedProps) do + processProp(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return props; +end; + +function lfm_enumGridPropsForCompiler() + local gridClass = require("rrpgGUI_grid.dlua"); + + local props = {}; + local qt = 0; + local alreadyListedProps = {}; + + local function processProp(propName, prop) + if not alreadyListedProps[propName] then + alreadyListedProps[propName] = true; + qt = qt + 1; + props[qt] = __copyPropTable(propName, prop); + end; + end; + + -- Class Defined Props + local currentClass = gridClass; + + while currentClass ~= nil do + definedProps = currentClass.props; + + if definedProps ~= nil then + for k, v in pairs(definedProps) do + processProp(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return props; +end; + +function lfm_enumGridEventsForCompiler() + local gridClass = require("rrpgGUI_grid.dlua"); + + local eves = {}; + local qt = 0; + local alreadyListedEves = {}; + + local function processEvent(eventName, eventData) + if not alreadyListedEves[eventName] then + alreadyListedEves[eventName] = true; + + local eveRec = {name = eventName}; + + if type(eventData) == "table" then + eveRec.parameters = eventData.arguments or ""; + else + eveRec.parameters = eventData or ""; + end; + + qt = qt + 1; + eves[qt] = eveRec; + end; + end; + + -- Class Defined Events + local currentClass = gridClass; + + while currentClass ~= nil do + definedEves = currentClass.eves; + + if definedEves ~= nil then + for k, v in pairs(definedEves) do + processEvent(k, v); + end; + end; + + currentClass = currentClass.super; + end; + + return eves; +end; + +local function _getStrOfSetTable(value) + local ret = ""; + local qt = 0; + + for k, v in pairs(value) do + if qt == 0 then + ret = tostring(v); + else + ret = ret .. " " .. tostring(v); + end; + + qt = qt + 1; + end; + + return ret; +end; + +function lfm_valueToStr(value, tipo, valuesOfTipo) + tipo = lowercase(tipo); + + if tipo == "bool" then + if value then + return "true"; + else + return "false"; + end; + elseif (tipo == "int") then + return tostring(round(value)); + elseif tipo == "double" then + return tostring(value); + elseif tipo == "enum" then + return tostring(value); + elseif (tipo == "string") or (tipo == "color") or (tipo == 'url') then + return value; + elseif tipo == "set" then + return _getStrOfSetTable(value, valuesOfTipo); + elseif (tipo == "bounds") or (tipo == "table") then + + if serpent == nil then + serpent = require("serpent.dlua"); + end; + + return serpent.line(value, {comment = false}); + else + return ""; + end; +end; + +function lfm_strToValue(value, tipo, valuesOfTipo) + tipo = lowercase(tipo); + + if tipo == "bool" then + return value == "true"; + elseif (tipo == "int") or (tipo =="double") then + return tonumber(value); + elseif (tipo == "string") or (tipo == "color") or (tipo == "url") then + return value; + elseif tipo == "enum" then + if isStrInTable(value, valuesOfTipo) then + return value; + else + return ""; + end; + elseif tipo == "set" then + + local objSet = {}; + + if type(value) == "string" then + for k, v in pairs(valuesOfTipo) do + if string.find(value, v) then + objSet[#objSet + 1] = v; + end; + end; + elseif type(value) == "table" then + objSet = value; + end; + + return objSet; + elseif (tipo == "bounds") or (tipo == "table") then + f, e = load("return " .. value); + if e then error(e) end + return f(); + else + return nil; + end; +end; + +local function simplificarTable(t) + local ret = {}; + + for k, v in pairs(t) do + if isNumber(k) or (k == v) then + ret[#ret + 1] = v; + else + ret[k]=v; + end; + end; + + return ret; +end + +function lfm_valueToStrToUser(value, tipo, valuesOfTipo) + tipo = lowercase(tipo); + + if tipo == "set" then + if serpent == nil then + serpent = require("serpent.dlua"); + end; + + return serpent.line(simplificarTable(value), {comment = false}); + else + return lfm_valueToStr(value, tipo, valuesOfTipo); + end; +end; + +function lfm_getPropAsString(ctrlOrHandle, propName) + local obj = lfm_getObject(ctrlOrHandle); + local props = obj.props; + + if props == nil then + return nil; + end; + + local prop = props[propName]; + + if prop == nil then + return nil; + end; + + local getter = obj[prop.getter]; + local v = getter(obj); + + return lfm_valueToStr(v, prop.tipo, prop.values); +end; + +function lfm_setPropAsString(ctrlOrHandle, propName, vAsStr) + local obj = lfm_getObject(ctrlOrHandle); + local prop; + + if obj.findPropDef ~= nil then + prop = obj:findPropDef(propName); + end; + + if prop == nil then + local props = obj.props; + + if props ~= nil then + prop = props[propName]; + end; + end; + + if prop == nil then + return nil; + end; + + v = lfm_strToValue(vAsStr, prop.tipo, prop.values); + obj[propName] = v; +end; + +function lfm_getPropAsStringToUser(ctrlOrHandle, propName) + local obj = lfm_getObject(ctrlOrHandle); + local props = obj.props; + + if props == nil then + return nil; + end; + + local prop = props[propName]; + + if prop == nil then + return nil; + end; + + local getter = obj[prop.getter]; + local v = getter(obj); + + return lfm_valueToStrToUser(v, prop.tipo, prop.values); +end; + + +function lfm_setParent(ctrlOrHandleFilho, ctrlOrHandlePai) + local objFilho = lfm_getObject(ctrlOrHandleFilho); + local objPai = lfm_getObject(ctrlOrHandlePai); + objFilho:setParent(objPai); +end; + +local function walkHierarchyAndGetTagClassName(class) + local currentClass = class; + + while type(currentClass) == "table" do + local tagName = rawget(currentClass, "tagName"); + + if type(tagName) == "string" then + return tagName; + end; + + currentClass = currentClass.super; + end; + + return nil; +end; + +function lfm_enumerarClasses() + local ret = {}; + + for k, v in pairs(gui.guiClasses) do + local tagName = rawget(v, "tagName"); + + assert(k == tagName, string.format('k = %s, tagName = %s', k, tagName)); + assert(ret[tagName] == nil, tagName); + + local c = {name = tagName, + parentClassName = walkHierarchyAndGetTagClassName(v.super)}; + + ret[tagName] = c; + end; + + return ret; +end; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgObjs.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgObjs.lua new file mode 100644 index 00000000..463da9cc --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgObjs.lua @@ -0,0 +1,775 @@ +local Async = require("async.lua"); + +objs = {} +local localObjs = objs; + +rrpgObjs = objs; + +local weakHandlerMetatable = { + __mode = "v" +} + +objs.weakMetatable = weakHandlerMetatable; + +local objHandlers = {}; +setmetatable(objHandlers, weakHandlerMetatable); + +objs.events = {}; + +objs.events.eveIdToObject = {}; +setmetatable(objs.events.eveIdToObject, {__mode="v"}); + +objs.events.eventsOfObjects = {}; +setmetatable(objs.events.eventsOfObjects, {__mode="k"}); + +objs.events.idGenerator = 1; + +function objs.addEventListener(object, eventName, funcCallback) + local objectHandle; + + if type(object) == 'table' then + objectHandle = object.handle; + else + objectHandle = nil; + end; + + if type(funcCallback) ~= "function" then + error("Ops, a function is needed to listen an event"); + end; + + if (funcCallback == nil) or (objectHandle == nil) then + return 0; + end; + + local eveItem = {}; + + eveItem.funcCallback = function(...) + return Async.execute(funcCallback, ...):unwrap(); + end + + local evesOfObject = localObjs.events.eventsOfObjects[object]; + + if evesOfObject == nil then + evesOfObject = {}; + localObjs.events.eventsOfObjects[object] = evesOfObject; + end; + + localObjs.events.idGenerator = localObjs.events.idGenerator + 1; + local esteEventId = localObjs.events.idGenerator; + + evesOfObject[esteEventId] = eveItem; + localObjs.events.eveIdToObject[esteEventId] = object; + + local eveDefFinder = object.findEventDef; + local eveDef; + + if eveDefFinder ~= nil then + eveDef = eveDefFinder(object, eventName); + else + eveDef = nil; + end; + + if (eveDef ~= nil) and (type(eveDef) == "table") and (type(eveDef.setter) == "function") then + eveItem.haveCustomSetter = true; + eveItem.setter = eveDef.setter; + eveDef.setter(object, eveItem.funcCallback); + else + _obj_listenEvent(objectHandle, eventName, esteEventId); + end; + + return esteEventId; +end; + +function objs.removeEventListenerById(eventId) + local obj = localObjs.events.eveIdToObject[eventId]; + + if obj == nil then + return; + end; + + localObjs.events.eveIdToObject[eventId] = nil; + + local evesOfObject = localObjs.events.eventsOfObjects[obj]; + + if evesOfObject == nil then + return; + end; + + local eventItem = evesOfObject[eventId]; + + if eventItem == nil then + return; + end; + + evesOfObject[eventId] = nil; + + if eventItem.haveCustomSetter then + eventItem.setter(obj, nil); + else + _obj_stopListeningEvent(obj.handle, eventId); + end; +end; + +--[[ Objeto TObject ]]-- + +objs.class = { + _isClass = true, + + initialize = function(obj) + end, + + addEventListener = function (obj, eventName, funcCallback) + return localObjs.addEventListener(obj, eventName, funcCallback); + end, + + removeEventListener = function (obj, eventListenerId) + return localObjs.removeEventListenerById(eventListenerId); + end, + + removeAllEventListeners = function(obj) + if (obj.handle == nil) then + return; + end; + + local eventsOfThis = localObjs.events.eventsOfObjects[obj]; + + if (eventsOfThis ~= nil) then + local eventsIds = {}; + local idx = 1; + + for k, v in pairs(eventsOfThis) do + eventsIds[idx] = k; + idx = idx + 1; + end; + + for i = 1, idx - 1, 1 do + localObjs.removeEventListenerById(eventsIds[i]); + end; + + localObjs.events.eventsOfObjects[obj] = nil; + end; + end, + + destroy = function(obj) + if not obj._calledDestroy then + obj._calledDestroy = true; + + if obj.handle ~= nil then + if (obj.removeAllEventListeners ~= nil) then + obj:removeAllEventListeners(); + end; + + if objHandlers[obj.handle] == obj then + objHandlers[obj.handle] = nil; + end; + + _obj_destruir(obj.handle); + obj.handle = nil; + end; + end; + end, + + getClassName = function(obj) + if obj.handle ~= nil then + return _obj_getClassName(obj.handle); + else + return ""; + end; + end, + + findPropDef = function(obj, propName) + -- Instance property + local props = rawget(obj, "props"); + + if props ~= nil then + local propKey = props[propName]; + + if propKey ~= nil then + return propKey; + end; + end; + + -- Class property + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + props = rawget(currentClass, "props"); + + if props ~= nil then + local propKey = props[propName]; + + if propKey ~= nil then + return propKey; + end; + end; + + currentClass = rawget(currentClass, "super"); + end; + + return nil; + end, + + findEventDef = function(obj, eventName) + -- Instance event + local eves = rawget(obj, "eves"); + + if eves ~= nil then + local eveKey = eves[eventName]; + + if eveKey ~= nil then + return eveKey; + end; + end; + + -- Class event + local currentClass = rawget(obj, "class"); + + while currentClass ~= nil do + eves = rawget(currentClass, "eves"); + + if eves ~= nil then + local eveKey = eves[eventName]; + + if eveKey ~= nil then + return eveKey; + end; + end; + + currentClass = rawget(currentClass, "super"); + end; + + return nil; + end +}; + +objs.class.listen = objs.class.addEventListener; +objs.class.unlisten = objs.class.removeEventListener; + +local function __readPropertyValue(instance, propKey) + local fgetter; + + if type(propKey.getter) == "function" then + fgetter = propKey.getter; + else + fgetter = instance[propKey.getter]; + end; + + if fgetter ~= nil then + return fgetter(instance); + elseif propKey.readProp ~= nil then + return _obj_getProp(rawget(instance, 'handle'), propKey.readProp); + end; +end; + +local function __tryIndexObjWithDefinition(definition, instance, key) + -- Raw Value + local v = rawget(definition, key); + + if (v ~= nil) then + return true, v; + end; + + -- Property + local props = rawget(definition, "props"); + + if props ~= nil then + local propKey = props[key]; + + if propKey ~= nil then + return true, __readPropertyValue(instance, propKey); + end; + end; + + -- Event + local eves = rawget(definition, "eves"); + + if eves ~= nil then + local eveKey = eves[key]; + + if eveKey ~= nil then + -- Existe um evento com este nome.. Vamos retornar o evento principal associado, se existir. + local mainEves = rawget(instance, "__mainEves"); + + if mainEves ~= nil then + return true, mainEves[key]; + end; + end; + end; + + -- Custom object __objindex method + local objIndexMethod = rawget(definition, "__objindex"); + + if (objIndexMethod ~= nil) and (type(objIndexMethod) == "function") then + return objIndexMethod(instance, key); + else + return false; + end; +end; + +local function __tryNewIndexObjWithDefinition(definition, instance, key, value) + -- Tentar setar uma propriedade + local fsetter = nil; + local props = rawget(definition, "props"); + + if props ~= nil then + local propKey = props[key]; + + if propKey ~= nil then + if type(propKey.setter) == "function" then + fsetter = propKey.setter; + else + fsetter = instance[propKey.setter]; + end; + + if (fsetter == nil) and (propKey.writeProp ~= nil) then + _obj_setProp(rawget(instance, 'handle'), propKey.writeProp, value); + return true; + end; + end; + end; + + if fsetter ~= nil then + fsetter(instance, value); + return true; + end; + + -- Tentar setar um evento + local eves = rawget(definition, "eves"); + + if eves ~= nil then + local eveKey = eves[key]; + + if eveKey ~= nil then + -- Existe um evento com este nome.. Vamos setar o evento principal associado, se existir. + local mainEves = rawget(instance, "__mainEves"); + + if (mainEves == nil) then + mainEves = {}; + rawset(instance, "__mainEves", mainEves) + end; + + local oldListenerId = mainEves["id_" .. key]; + + if oldListenerId ~= nil then + objs.removeEventListenerById(oldListenerId); + mainEves["id_" .. key] = nil; + end; + + mainEves[key] = value; + + if value ~= nil then + mainEves[key] = value; + mainEves["id_" .. key] = objs.addEventListener(instance, key, value); + end; + + return true; + end; + end; + + -- Custom object __objnewindex method + local objNewIndexMethod = rawget(definition, "__objnewindex"); + + if (objNewIndexMethod ~= nil) and (type(objNewIndexMethod) == "function") then + return objNewIndexMethod(instance, key, value); + else + -- Could not newindex object with supplied definition + return false; + end; +end; + +local objectMetaTable = { + --[[ Comparação padrão entre objetos ]]-- + __eq = function(op1, op2) + if op1.handle ~= nil then + if op2.handle ~= nil then + return op1.handle == op2.handle; + else + return false; + end; + else + if op2.handle ~= nil then + return false; + else + return op1 == op2; + end; + end; + end, + + --[[ getter padrão de propriedades dos objetos. Chamado quando tentar gettar uma propriedade que não existe ]]-- + + __index = function(table, key) + local r, v; + + r, v = __tryIndexObjWithDefinition(table, table, key); + + if r then + return v; + end; + + -- Verificar classes + local currentClass = rawget(table, "class"); + + while currentClass ~= nil do + r, v = __tryIndexObjWithDefinition(currentClass, table, key); + + if r then + return v; + end; + + currentClass = rawget(currentClass, "super"); + end; + + -- Se chegou até aqui, é porque não localizou nenhum valor especial + return nil; + end, + + --[[ setter padrão de propriedades dos objetos. Chamado quando tentou settar uma propriedade que não existe ]]-- + + __newindex = function(table, key, value) + local r; + r = __tryNewIndexObjWithDefinition(table, table, key, value); + + if r then + return; + end; + + -- Verificar classes + local currentClass = rawget(table, "class"); + + while currentClass ~= nil do + r = __tryNewIndexObjWithDefinition(currentClass, table, key, value); + + if r then + return; + end; + + currentClass = rawget(currentClass, "super"); + end; + + -- Se chegou até aqui, é porque não conseguiu fazer nenhuma atribuição especial. + -- Vamos fazer uma atribuição padrão + rawset(table, key, value); + end, + + __gc = function(obj) + if obj.destroy ~= nil then + obj:destroy(); + end; + + if obj.handle ~= nil then + _obj_destruir(obj.handle); + obj.handle = nil; + end; + end +}; + +local classMetatable = { + __index = function(classTable, key) + if (key == "eves") or (key == "props") then + return rawget(classTable, key); + end; + + local currentClass = classTable; + + while currentClass ~= nil do + local v = rawget(currentClass, key); + + if v ~= nil then + return v; + end; + + currentClass = rawget(currentClass, "super"); + end; + + -- Se chegou até aqui, é porque não localizou nenhum valor especial + return nil; + end, + + __newindex = function(classTable, key, value) + rawset(classTable, key, value); + end; +}; + +function objs.objectFromHandle(handle) + local obj = {handle=handle, + class=objs.class}; + + setmetatable(obj, objectMetaTable); + objs.registerHandleIfNeeded(handle, obj); + return obj; +end + +function objs.newPureLuaObject() + return objs.objectFromHandle(nil); +end; + +function objs.__recursiveRunInitialize(obj, class) + local superClass = class.super; + + if superClass ~= nil then + objs.__recursiveRunInitialize(obj, superClass); + end; + + local initialize = rawget(class, "initialize"); + + if initialize ~= nil then + initialize(obj); + end; +end; + +function objs.__createSubclass(superClass) + assert(superClass ~= nil); + local class = {super = superClass, props = {}, eves = {}, _isClass = true}; + + class.new = function() + local obj = {class=class}; + setmetatable(obj, objectMetaTable); + objs.__recursiveRunInitialize(obj, class); + return obj; + end; + + class.fromHandle = function(handle) + local obj = {handle=handle, class=class}; + setmetatable(obj, objectMetaTable); + objs.registerHandleIfNeeded(handle, obj); + objs.__recursiveRunInitialize(obj, class); + return obj; + end; + + class.inherit = function() return objs.__createSubclass(class); end; + setmetatable(class, classMetatable); + return class; +end; + +function objs.newClass() + return objs.__createSubclass(objs.class); +end; + +objs.inherit = objs.newClass; + +-- ## Component Class + +objs.Component = objs.newClass(); + +function objs.Component:initialize() + rawset(self, "props", {}); + rawset(self, "eves", {}); +end; + +function objs.Component:getName() return _obj_getProp(self.handle, "Name"); end; +function objs.Component:setName(name) _obj_setProp(self.handle, "Name", name); end; + +objs.Component.props["name"] = {setter = "setName", getter = "getName", tipo = "string"}; + +function objs.componentFromHandle(handle) + local obj = objs.Component.fromHandle(handle); + return obj; +end; + +-- ## HierarchyObject Class + +objs.HierarchyObject = objs.Component.inherit(); + +function objs.HierarchyObject:initialize() + rawset(self, "_children", {}); +end; + +function objs.HierarchyObject.getChildren(instance) + local ret = {}; + local idxDest = 1; + + for k, v in pairs(instance._children) do + ret[idxDest] = v; + idxDest = idxDest + 1; + end; + + return ret; +end; + +function objs.HierarchyObject.findChildByName(instance, childName, recursive, superficialSearch) + recursive = recursive or true; + local child; + + child = instance[childName]; + + if type(child) == "table" and (child.handle ~= nil) and (child.getName ~= nil) and (child:getName() == childName) then + return child; + end; + + if superficialSearch then + return nil; + end; + + local childs = instance:getChildren(); + + for i = 1, #childs, 1 do + child = childs[i]; + + if child.getName ~= nil then + + if child:getName() == childName then + return child; + end; + end; + end; + + if recursive then + local retChild; + + for i = 1, #childs, 1 do + child = childs[i]; + retChild = child:findChildByName(childName, recursive); + + if retChild ~= nil then + return retChild; + end; + end; + end; + + return nil; +end; + +function objs.HierarchyObject.getParent(instance) + return GUI.fromHandle(_gui_getParent(instance.handle)) +end; + +function objs.HierarchyObject.setParent(instance, parent) + if (instance._parent == parent) then + return; + end; + + if (instance._parent ~= nil) then + instance._parent._children[instance.handle] = nil; + end + + instance._parent = parent; + + if (instance._parent ~= nil) then + _gui_setParent(instance.handle, parent.handle); + instance._parent._children[instance.handle] = instance; + else + _gui_setParent(instance.handle, nil); + end; +end; + +objs.HierarchyObject.__oldDestroyHierarchyObject = objs.HierarchyObject.destroy; + +function objs.HierarchyObject.destroy(instance) + instance:removeAllEventListeners(); + + if instance._children ~= nil then + for k, v in pairs(instance._children) do + if v ~= nil then + v:setParent(nil); + end; + end; + + instance._children = {}; + end; + + if (instance._parent ~= nil) then + + if (instance._parent._children ~= nil) and (instance.handle ~= nil) then + instance._parent._children[instance.handle] = nil; + end; + + instance._parent = nil; + end; + + objs.HierarchyObject.__oldDestroyHierarchyObject(instance); +end; + +function objs.hierarchyObjectFromHandle(handle) + local obj = objs.HierarchyObject.fromHandle(handle); + return obj; +end; + +-- ## Timer Class + +objs.Timer = objs.HierarchyObject.inherit(); + +function objs.Timer:getInterval() return _obj_getProp(self.handle, "Interval") end; +function objs.Timer:setInterval(v) _obj_setProp(self.handle, "Interval", v) end; +function objs.Timer:getEnabled() return _obj_getProp(self.handle, "Enabled") end; +function objs.Timer:setEnabled(v) _obj_setProp(self.handle, "Enabled", v) end; +function objs.Timer:beginUpdate() end; +function objs.Timer:endUpdate() end; + +objs.Timer.props["interval"] = {setter = "setInterval", getter = "getInterval", tipo = "int"}; +objs.Timer.props["enabled"] = {setter = "setEnabled", getter = "getEnabled", tipo = "bool"}; + +objs.Timer.eves["onTimer"] = ""; + +function objs.__timerFromHandle(handle) + local timer = objs.Timer.fromHandle(handle); + return timer; +end; + +function objs.newTimer(interval, callback) + local timer = objs.__timerFromHandle(_obj_newObject("timer")); + + interval = tonumber(interval); + + if (type(interval) ~= "number") or (interval < 1) then + interval = 1; + end; + + timer:setInterval(interval); + + if type(callback) == "function" then + timer:addEventListener("onTimer", callback); + end; + + timer:setEnabled(true); + return timer; +end; + +function objs.beginObjectsLoading() + _obj_beginObjectsLoading(); +end; + +function objs.endObjectsLoading() + _obj_endObjectsLoading(); +end; + +function objs.tryFindFromHandle(handle) + return objHandlers[handle]; +end; + +function objs.registerHandle(handle, object) + objHandlers[handle] = object; +end; + +function objs.registerHandleIfNeeded(handle, object) + if objHandlers[handle] == nil then + objHandlers[handle] = object; + end; +end + +function _rrpgObjs_events_receiver(eventId, ...) + local obj = localObjs.events.eveIdToObject[eventId]; + + if obj == nil then + return; + end; + + local evesOfObject = localObjs.events.eventsOfObjects[obj]; + + if evesOfObject == nil then + return; + end; + + local eventItem = evesOfObject[eventId]; + + if eventItem == nil then + return; + end; + + return eventItem.funcCallback(...); +end; + +function __EXPORT__objs_tryFindFromHandle(handle) + return objs.tryFindFromHandle(handle); +end; + +return localObjs; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgRequests.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgRequests.lua new file mode 100644 index 00000000..d01ba98a --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgRequests.lua @@ -0,0 +1,83 @@ +local rrpg = require("rrpg.lua"); +local rrpgObjs = require("rrpgObjs.lua"); +require("rrpgUtil"); +local messaging = rrpg.messaging; + +local requests = rrpgObjs.objectFromHandle(_obj_newObject("TRRPGLuaRequests")); +rrpgObjs.registerHandle(requests.handle, requests); + +local sessionLostMessage = "A conexão com o servidor foi perdida"; + +local function execCallback(callbackFunction, ...) + if type(callbackFunction) == "function" then + setTimeout( + function(...) + callbackFunction(...); + end, 50, ...); + end; +end; + +function requests.criarItensNaBiblioteca(mesa, itens, successCallback, failureCallback) + local pacote = itens; + + if mesa == nil then + error("Parâmetro mesa não informado"); + end; + + if #itens == 0 then + execCallback(failureCallback, "Não foi especificado itens para a criação"); + return; + end; + + for i = 1, #itens, 1 do + local it = itens[i]; + + if (type(it.itemPai) == "table") then + it.itemPai = it.itemPai.codigoInterno; + end; + + if type(it.dono) == "table" then + it.dono = it.dono.codigoInterno; + end; + end; + + if type(mesa) == "table" then + mesa = mesa.codigoInterno; + end; + + local r, r2 = _obj_invokeEx(requests.handle, "ExCriarItensNaBiblioteca", mesa, pacote); + + if r then + local l1 = messaging.listenOnce("ServerResponse_CriarItemBiblioteca", + function(msg) + if msg.r then + execCallback(successCallback); + else + execCallback(failureCallback, msg.msg); + end; + end, {requestId=r2}); + + local l2 = messaging.listenOnce("SessionLost", + function() + execCallback(failureCallback, sessionLostMessage); + end); + + messaging.groupOnceListeners(l1, l2); + else + execCallback(failureCallback, r2); + end; +end; + +function requests.criarPersonagem(itemPai, nome, dataType, visivelATodos, dono, successCallback, failureCallback) + + if itemPai == nil then + error("Parâmetro itemPai não informado"); + end; + + local itens = {{tipoItem="personagem", itemPai=itemPai, nome=nome, sistema=dataType, dono=dono, visivel=visivelATodos}}; + return requests.criarItensNaBiblioteca(itemPai.mesa, itens, successCallback, failureCallback); +end; + +rrpg.requests = requests; +rrpg.Requests = requests; +return requests; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgSharedObjects.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgSharedObjects.lua new file mode 100644 index 00000000..f6f6b1d0 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgSharedObjects.lua @@ -0,0 +1,149 @@ +local SharedObjects = {}; +local registeredUnpackers = {}; + +local __SHAREDOBJ_PREFIX = "##RRPGshObj("; +local __SHAREDOBJ_SUFIX = ")##"; +local __MATCH_SHARED_OBJ = "##RRPGshObj%((.+)%)##" +local __MATCH_SHARED_OBJ_NOCAPTURE = "##RRPGshObj%([^%(%)#]+%)##" + +local __SHAREDARRAYOBJ_PREFIX = "@@RRPGshObjArray("; +local __SHAREDARRAYOBJ_SUFIX = ")@@"; +local __SHAREDARRAYOBJ_SEP = ","; +local __MATCH_SHARED_ARRAYOBJ = "@@RRPGshObjArray%((.+)%)@@" + +local function sidToString(sid) + if type(sid) == "table" then + if sid.extra ~= nil then + return _internet_HTTPEncode(sid.objectType) .. "\\" .. + _internet_HTTPEncode(sid.objectID) .. "\\" .. + _internet_HTTPEncode(sid.extra); + else + return _internet_HTTPEncode(sid.objectType) .. "\\" .. + _internet_HTTPEncode(sid.objectID); + end; + else + return ""; + end; +end; + +local __strToSidOrder = {"objectType", "objectID", "extra"} + +local function stringToSid(str) + local sid = {}; + + if str ~= nil and type(str) == "string" then + local ordem = 1; + + for t in string.gmatch(str, "[^\\]+") do + local k = __strToSidOrder[ordem]; + + if k ~= nil then + sid[k] = _internet_HTTPDecode(t); + end; + + ordem = ordem + 1; + end; + end; + + sid.objectType = sid.objectType or ""; + sid.objectID = sid.objectID or ""; + return sid; +end; + +function SharedObjects.tryPack(tabela) + if type(tabela) ~= "table" then + return false; + end; + + local h = rawget(tabela, "handle"); + + if h ~= nil then + local so = nil; + local fnGetShareObjectID = rawget(tabela, "getShareID"); + + if (fnGetShareObjectID ~= nil) and (type(fnGetShareObjectID) == "function") then + local sid = fnGetShareObjectID(tabela); + so = __SHAREDOBJ_PREFIX .. sidToString(sid) .. __SHAREDOBJ_SUFIX; + end; + + return true, so; + else + local qtNaTabela = #tabela; + + if qtNaTabela > 0 then + -- Pode ser um array.... + local bStr = __SHAREDARRAYOBJ_PREFIX; + local qtPacked = 0; + + for i = 1, #tabela, 1 do + local xR, xStr = SharedObjects.tryPack(tabela[i]); + + if xR then + if qtPacked > 0 then + bStr = bStr .. __SHAREDARRAYOBJ_SEP; + end; + + bStr = bStr .. xStr; + qtPacked = qtPacked + 1; + end; + end; + + if qtPacked > 0 then + return true, bStr .. __SHAREDARRAYOBJ_SUFIX; + else + return false; + end + else + return false; + end + end; +end; + +function SharedObjects.tryUnpack(str) + if str == nil then + return false; + end; + + local arrayContent = string.match(str, __MATCH_SHARED_ARRAYOBJ); + + if arrayContent ~= nil then + -- Um array de objetos + local tabela = {}; + + for sObj in string.gmatch(arrayContent, __MATCH_SHARED_OBJ_NOCAPTURE) do + local xR, xObj = SharedObjects.tryUnpack(sObj); + + if xR then + tabela[#tabela + 1] = xObj; + end; + end; + + if #tabela > 0 then + return true, tabela; + else + return false; + end; + else + local strSid = string.match(str, __MATCH_SHARED_OBJ); + + if strSid ~= nil then + local sid = stringToSid(strSid); + local unpacker = registeredUnpackers[sid.objectType]; + + if unpacker ~= nil then + local so = unpacker(sid); + return true, so; + else + return false; + end; + else + return false; + end; + end; +end; + +function SharedObjects.registerUnpacker(objectType, unpackerCallback) + registeredUnpackers[objectType] = unpackerCallback; +end; + +return SharedObjects; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil.lua new file mode 100644 index 00000000..225c3835 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil.lua @@ -0,0 +1,485 @@ +local rrpgObjs = require("rrpgObjs.lua"); +utils = {}; +Utils = utils; + +function lowercase(s) + return string.lower(s); +end; + +function uppercase(s) + return string.upper(s); +end; + +function isNumber(v) + return type(v) == "number"; +end; + +function isnumber(v) + return type(v) == "number"; +end; + +function floor(v) + return math.floor(v); +end; + +function round(v) + return floor(v + 0.5); +end; + +function utils.tryFinally(tryCallback, finallyCallback) + return _util_tryFinally(tryCallback, finallyCallback); +end; + +tryFinally = utils.tryFinally; + +function isStrInTable(s, table) + for k, v in ipairs(table) do + if (k == s) or (v == s) then + return true; + end; + end; + + return false; +end; + +function removerAcentos(str) + return utils.removerAcentos(str); +end; + + +function strToTable(str) + return totable(str); +end; + +function tableToStr(tabela, pretty) + local serpent = require("serpent.dlua"); + + if pretty then + return serpent.block(tabela, {comment=false}); + else + return serpent.line(tabela, {comment=false}); + end; +end; + +utils.tableToStr = tableToStr; +utils.strToTable = strToTable; + +function utils.removerAcentos(str) + return _util_removerAcentos(str); +end; + +function utils.removerFmtChat(str, removerSmileys) + if removerSmileys == nil then + removerSmileys = false; + end; + + return _util_removerTagsDeFormatacaoDeChat(str, not (not removerSmileys)); +end; + +function utils.compareStringPtBr(strLeft, strRight) + return _util_compareStringsPtBr(strLeft, strRight); +end; + +function utils.sortPtBrArray(array) + table.sort(array, function(l, r) return utils.compareStringPtBr(l, r) < 0; end); +end; + +local __settedTimers = {}; +local __timersGeneratorId = 1; + +local function __unsetupTemporizador(timerId, temporizador) + if temporizador == nil then + temporizador = __settedTimers[timerId]; + end; + + __settedTimers[timerId] = nil; + + if (temporizador ~= nil) and (temporizador.timer ~= nil) then + local timer = temporizador.timer; + timer.enabled = false; + temporizador.callback = nil; + temporizador.parametros = nil; + temporizador.timer = nil; -- liberar para o garbage collector + end; +end; + +local function __setupTemporizador(callback, interval, isInterval, ...) + if (type(callback) ~= "function") or (type(interval) ~= "number") then + return nil; + end; + + if interval < 1 then + interval = 1; + end; + + __timersGeneratorId = __timersGeneratorId + 1; + + local temporizador = {}; + local timer = rrpgObjs.newTimer(); + local timerId = __timersGeneratorId; + + + temporizador.id = timerId; + temporizador.timer = timer; + temporizador.interval = interval; + temporizador.isInterval = isInterval; + temporizador.callback = callback; + temporizador.parametros = table.pack(...); + + temporizador.onTimerEventListenerId = timer:addEventListener("onTimer", + function () + local callbackFunction = temporizador.callback; + local parametros = temporizador.parametros; + + if not temporizador.isInterval then + __unsetupTemporizador(timerId, temporizador); + end; + + local ret; + + if callbackFunction ~= nil then + if parametros ~= nil then + ret = callbackFunction(table.unpack(parametros)); + else + ret = callbackFunction(); + end; + else + ret = false; + end; + + if temporizador.isInterval and (ret == false) then + __unsetupTemporizador(timerId, temporizador); + end; + end); + + __settedTimers[timerId] = temporizador; + timer.interval = interval; + timer.enabled = true; + return timerId; +end; + +function utils.setTimeout(callback, interval, ...) + interval = tonumber(interval); + + if (interval == nil) or (interval <= 0) then + callback(...); + return nil; + else + return __setupTemporizador(callback, interval, false, ...); + end; +end; + +function utils.setInterval(callback, interval, ...) + return __setupTemporizador(callback, interval, true, ...); +end; + +function utils.clearInterval(intervalId) + return __unsetupTemporizador(intervalId); +end; + +function utils.clearTimeout(timeoutId) + return __unsetupTemporizador(timeoutId); +end; + +function setTimeout(callback, interval, ...) + return utils.setTimeout(callback, interval, ...); +end; + +function setInterval(callback, interval, ...) + return utils.setInterval(callback, interval, ...); +end; + +function clearInterval(intervalId) + return utils.clearInterval(intervalId); +end; + +function clearTimeout(timeoutId) + return utils.clearTimeout(timeoutId); +end; + +function utils.binaryEncode(destArray, format, value, startIndex) + if type(destArray) ~= "table" then + return; + end; + + if type(startIndex) ~= "number" then + startIndex = 1; + end; + + return _util_binaryEncode(destArray, format, value, startIndex); +end; + +function utils.binaryDecode(sourceArray, format, startIndex, length) + if type(sourceArray) ~= "table" then + return nil; + end; + + if type(startIndex) ~= "number" then + startIndex = 1; + end; + + if type(length) ~= "number" then + length = #sourceArray - startIndex + 1; + end; + + return _util_binaryDecode(sourceArray, format, startIndex, length); +end; + +function utils.getBinarySize(format) + return _util_getBinarySize(format); +end; + +local __streamProps = nil; + +function utils.streamFromHandle(handle) + local stream = rrpgObjs.tryFindFromHandle(handle); + + if stream ~= nil then + return stream; + end; + + stream = rrpgObjs.objectFromHandle(handle); + + function stream:getSize() return _obj_getProp(self.handle, "Size"); end; + function stream:setSize(v) _obj_setProp(self.handle, "Size", v); end; + + function stream:getPosition() return _obj_getProp(self.handle, "Position"); end; + function stream:setPosition(v) _obj_setProp(self.handle, "Position", v); end; + + function stream:read(destArray, qtBytes) return _obj_invokeEx(self.handle, "ReadBytes", destArray, qtBytes); end; + function stream:write(sourceArray, qtBytes) return _obj_invokeEx(self.handle, "WriteBytes", sourceArray, qtBytes); end; + + function stream:getRemainingBytes() + local r = self.size - self.position; + + if r < 0 then + return 0; + else + return r; + end; + end; + + function stream:close() _obj_invoke(self.handle, "Close"); end; + + function stream:writeBinary(format, ...) + local qt = select("#", ...); + local qtBytesEscrito = 0; + local binario = {}; + + for i = 1, qt, 1 do + local v = select(i, ...); + local qtBytesEste = utils.binaryEncode(binario, format, v); + local qtEscritoNeste = self:write(binario, qtBytesEste); + qtBytesEscrito = qtBytesEscrito + qtEscritoNeste; + + if qtEscritoNeste < qtBytesEste then + return qtBytesEscrito; + end; + end; + + return qtBytesEscrito; + end; + + function stream:readBinary(format, qt) + local qtBytesPorItem = utils.getBinarySize(format); + local qtBytesALer; + + if type(qt) ~= "number" then + qt = 1; + end; + + if qt <= 0 then + return; + end; + + if qtBytesPorItem < 0 then + -- tamanho variável. + qtBytesALer = self.remainingBytes; + else + qtBytesALer = qt * qtBytesPorItem; + end; + + local bts = {}; + local bytesLido = self:read(bts, qtBytesALer); + + if (qt == 1) or (qtBytesPorItem <= 0) then + return utils.binaryDecode(bts, format, 1, bytesLido); + else + local retornos = {}; + local currentIndex = 1; + + for i = 1, qt, 1 do + local retValue, bytesUsados = utils.binaryDecode(bts, format, currentIndex, qtBytesPorItem); + retornos[i] = retValue; + currentIndex = currentIndex + bytesUsados; + end; + + return table.unpack(retornos); + end; + end; + + function stream:readAsBase64(qtBytes) + if qtBytes == nil then + qtBytes = self.remainingBytes; + else + qtBytes = tonumber(qtBytes); + + if qtBytes < 0 then + qtBytes = 0; + elseif qtBytes > self.remainingBytes then + qtBytes = self.remainingBytes; + end; + end; + + return _obj_invoke(self.handle, "ReadAsBase64", qtBytes); + end; + + function stream:writeBase64(str) + if str == nil or str == "" then + return 0; + end; + + return _obj_invoke(self.handle, "WriteBase64", tostring(str)); + end; + + function stream:copyFrom(sourceStream, qtBytes) + qtBytes = tonumber(qtBytes); + + if (type(sourceStream) ~= "table") or (sourceStream.handle == nil) or (qtBytes == nil) or (qtBytes <= 0) then + return 0; + end; + + return _obj_invokeEx(self.handle, "CopyFrom", sourceStream.handle, qtBytes); + end; + + function stream:share() return _obj_invoke(self.handle, "ShareStream"); end; + + function stream:getMD5() return _obj_invoke(self.handle, "CalculateMD5"); end; + function stream:getSHA1() return _obj_invoke(self.handle, "CalculateSHA1"); end; + + if __streamProps == nil then + __streamProps = stream.props or {}; + __streamProps["size"] = {setter = "setSize", getter = "getSize", tipo = "int"}; + __streamProps["position"] = {setter = "setPosition", getter = "getPosition", tipo = "int"}; + __streamProps["remainingBytes"] = {getter = "getRemainingBytes", tipo = "int"}; + __streamProps["md5"] = {getter = "getMD5", tipo = "string"}; + __streamProps["sha1"] = {getter = "getSHA1", tipo = "string"}; + end; + + stream.props = __streamProps; + + rrpgObjs.registerHandle(handle, stream); + return stream; +end; + +string.upper = function(str) + return _util_upperCase(str); +end; + +string.lower = function(str) + return _util_lowerCase(str); +end; + +function utils.zlibCompress(sourceStream, destStream, level, qtBytesInSource) + if level ~= "none" and level ~= "fastest" and level ~= "default" and level ~= "max" then + level = "default"; + end; + + if qtBytesInSource == nil then + qtBytesInSource = sourceStream.remainingBytes; + else + qtBytesInSource = tonumber(qtBytesInSource); + + if qtBytesInSource < 0 then + qtBytesInSource = 0; + elseif qtBytesInSource > sourceStream.remainingBytes then + qtBytesInSource = sourceStream.remainingBytes; + end; + end; + + return _util_zlibCompress(sourceStream.handle, destStream.handle, level, qtBytesInSource); +end; + +function utils.zlibDecompress(sourceStream, destStream) + return _util_zlibDecompress(sourceStream.handle, destStream.handle); +end; + +function utils.zlibCompressAsync(sourceStream, destStream, level, qtBytesInSource, onFinish, onError) + if level ~= "none" and level ~= "fastest" and level ~= "default" and level ~= "max" then + level = "default"; + end; + + if qtBytesInSource == nil then + qtBytesInSource = sourceStream.remainingBytes; + else + qtBytesInSource = tonumber(qtBytesInSource); + + if qtBytesInSource < 0 then + qtBytesInSource = 0; + elseif qtBytesInSource > sourceStream.remainingBytes then + qtBytesInSource = sourceStream.remainingBytes; + end; + end; + + local compressObject = require("rrpgUtil_async.dlua").newAsyncZLibObject(); + compressObject:zlibCompressAsync(sourceStream, destStream, level, qtBytesInSource, onFinish, onError); +end; + +function utils.zlibDecompressAsync(sourceStream, destStream, onFinish, onError) + local compressObject = require("rrpgUtil_async.dlua").newAsyncZLibObject(); + compressObject:zlibDecompressAsync(sourceStream, destStream, onFinish, onError); +end; + +function utils.newMemoryStream() + return utils.streamFromHandle(_util_newMemoryStream()); +end; + +function utils.newTempFileStream() + return utils.streamFromHandle(_util_newTempFileStream()); +end; + +function utils.openSharedStream(sharedId) + return utils.streamFromHandle(_util_openSharedStream(sharedId)); +end; + +function utils.generateUniqueString() + return _rrpg_generateUniqueStrID(); +end; + +function utils.cloneTable(t, deep) + if t == nil then + return nil; + end; + + local r = {}; + + for i = 1, #t do + local v = t[i]; + + if (deep) and (type(v) == "table") then + r[i] = utils.cloneTable(v); + else + r[i] = v; + end; + end; + + for k, v in pairs(t) do + if r[k] == nil then + if (deep) and (type(v) == "table") then + r[k] = utils.cloneTable(v); + else + r[k] = v; + end; + end; + end; + + return r; +end; + +utils.colorToRGBA = _gui_colorToRGBA; +utils.RGBAToColor = _gui_RGBAToColor; + +colorToRGBA = utils.colorToRGBA; +RGBAToColor = utils.RGBAToColor; + +return utils; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil_async.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil_async.dlua new file mode 100644 index 00000000..cc51a94d --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgUtil_async.dlua @@ -0,0 +1,78 @@ +local objs = require("rrpgObjs.lua"); +local async = {}; + +local __asyncsWorking = {}; + +function async.newAsyncZLibObject() + local obj = objs.objectFromHandle(_obj_newObject("asyncZLibObject")); + + if obj.eves == nil then + obj.eves = {}; + end; + + obj.eves["onFinish"] = ""; + obj.eves["onError"] = ""; + + function obj:undoReferenceToStreams() + rawset(obj, "__sourceStream", nil); + rawset(obj, "__destStream", nil); + end; + + function obj:setWorking() + __asyncsWorking[obj] = true; + end; + + function obj:setNotWorking() + obj:undoReferenceToStreams(); + __asyncsWorking[obj] = nil; + end; + + function obj:zlibCompressAsync(sourceStream, destStream, level, qtBytesInSource, onFinish, onError) + rawset(obj, "__sourceStream", sourceStream); + rawset(obj, "__destStream", destStream); + + obj.onFinish = function (...) + if onFinish ~= nil then + onFinish(...); + obj:setNotWorking(); + end; + end; + + obj.onError = function (...) + if onError ~= nil then + onError(...); + obj:setNotWorking(); + end; + end; + + obj:setWorking(); + _obj_invokeEx(obj.handle, "ZLibCompressAsync", sourceStream.handle, destStream.handle, level, qtBytesInSource); + end; + + function obj:zlibDecompressAsync(sourceStream, destStream, onFinish, onError) + rawset(obj, "__sourceStream", sourceStream); + rawset(obj, "__destStream", destStream); + + obj.onFinish = function () + if onFinish ~= nil then + onFinish(); + obj:setNotWorking(); + end; + end; + + obj.onError = function (errorMsg) + if onError ~= nil then + onError(errorMsg); + obj:setNotWorking(); + end; + end; + + obj:setWorking(); + _obj_invokeEx(obj.handle, "ZLibDecompressAsync", sourceStream.handle, destStream.handle); + end; + + objs.registerHandle(obj.handle, obj); + return obj; +end; + +return async; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgWrappers.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgWrappers.lua new file mode 100644 index 00000000..b4b39038 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/rrpgWrappers.lua @@ -0,0 +1,1185 @@ +local objs = require("rrpgObjs.lua"); +local SharedObjects = require("rrpgSharedObjects.lua"); +local rrpgWrappers = {}; +local localStrongRefContextoObjects = {}; +local Locale = require("locale.lua"); +local Async = require("async.lua"); +local Utils = require('utils.lua'); + +local SHARED_OBJECT_TYPE = "rrpgObject"; + +--[ Anti Flood System ]-- + +local function newTimedJobQueue(interval) + local o = {}; + o.interval = interval; + + o.timer = objs.newTimer(interval, + function() + + -- Pesquisar novo job + local achouJob = false; + local jobEncontrado = nil; + local idJobEncontrado = nil; + + while (not achouJob) and (o.ultimoJobExecutado < o.gerador) do + o.ultimoJobExecutado = o.ultimoJobExecutado + 1; + local jobObject = o.jobs[o.ultimoJobExecutado]; + + if jobObject ~= nil then + achouJob = true; + jobEncontrado = jobObject; + idJobEncontrado = o.ultimoJobExecutado; + end; + end; + + if achouJob and (jobEncontrado ~= nil) then + o.jobs[idJobEncontrado] = nil; + + if jobEncontrado.parameters ~= nil then + jobEncontrado.callback(table.unpack(jobEncontrado.parameters)); + else + jobEncontrado.callback(); + end; + else + o.readyForJob = true; + o.timer.enabled = false; + end; + + end); + + o.timer.enabled = false; + + function o:addJob(callback, ...) + if o.readyForJob then + o.readyForJob = false; + o.timer.enabled = true; + callback(...); + else + o.gerador = o.gerador + 1; + local idJob = o.gerador; + local jobObject = {}; + jobObject.callback = callback; + jobObject.parameters = table.pack(...); + o.jobs[idJob] = jobObject; + end; + end; + + function o:addAsyncJob(callback, ...) + local promise, resolution = Async.Promise.toResolve(); + assert((promise ~= nil) and (resolution ~= nil)); + + o:addJob( + function(...) + assert(resolution ~= nil); + + local function protectedCallback(...) + local ret = table.pack(pcall(callback, ...)); + + if ret[1] then + return table.unpack(ret, 2); + else + return Async.Promise.failed(ret[2]); + end; + end; + + Async.execute(protectedCallback, ...):thenResolve(resolution); + end, ...); + + return promise; + end; + + function o:clear() + o.timer.enabled = false; + o.gerador = 0; + o.ultimoJobExecutado = 0; + o.jobs = {}; + o.readyForJob = true; + end; + + o:clear(); + return o; +end; + +local __serverRequestQueue = newTimedJobQueue(250); +rrpgWrappers.__serverRequestQueue = __serverRequestQueue; + +local function initWrappedObjectFromHandle(handle) + local wObj = objs.objectFromHandle(handle); + + if (wObj.props == nil) then + wObj.props = {}; + end; + + function wObj:getObjectID() return _obj_getProp(self.handle, "ContextoObjectID"); end; + function wObj:getObjectType() return _obj_getProp(self.handle, "WrappedObjectType"); end; + function wObj:getIsObjectAlive() return _obj_getProp(self.handle, "IsObjectAlive"); end; + function wObj:isType(typeName) return _rrpg_IsWrapperOfType(self.handle, typeName); end; + + function wObj:getShareID() return {objectType=SHARED_OBJECT_TYPE, objectID=tostring(self:getObjectID())} end; + + wObj.props["objectType"] = {getter = "getObjectType", tipo = "string"}; + wObj.props["isObjectAlive"] = {getter = "getIsObjectAlive", tipo = "bool"}; + wObj.props["objectID"] = {getter = "getObjectID", tipo = "int"}; + return wObj; +end; + +--[ OBJETO MESA ]-- + +local function initMesaWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local mesa = wObj; + + function mesa:getActiveChat() + local objMesa = rrpgWrappers.objectFromID(_obj_getProp(self.handle, "ActiveChatObjectID")); + + if objMesa == nil then + return mesa:getChat(); + else + return objMesa; + end; + end; + + function mesa:getAudioPlayer() + local cachedPlayer = rawget(self, "__cachedAudioPlayer"); + + if cachedPlayer == nil then + local audioLib = require("audioCore.dlua"); + + if self.isObjectAlive then + local audioPlayerHandle = _obj_invokeEx(self.handle, 'CreateRoomAudioPlayer'); + + if audioPlayerHandle ~= nil then + cachedPlayer = audioLib._audioPlayerWrapperFromHandle(audioPlayerHandle); + else + cachedPlayer = audioLib._newNullAudioPlayerWrapper("Failed to initialize room audio player"); + end; + else + cachedPlayer = audioLib._newNullAudioPlayerWrapper("Not in room"); + end; + + assert(cachedPlayer ~= nil); + rawset(self, "__cachedAudioPlayer", cachedPlayer); + end; + + return cachedPlayer; + end; + + function mesa:getChat() + local objMesa = rrpgWrappers.objectFromID(_obj_getProp(self.handle, "ChatObjectID")); + + if objMesa == nil then + return rrpgWrappers.NullChatWrapper; -- ao invés de retornar NULL, vamos retorna um objeto que não faz nada. + else + return objMesa; + end; + end; + + function mesa:getJogadores() + local hs = _obj_getProp(self.handle, "JogadoresObjectIDs"); + local jogadores = {}; + local idx = 1; + + for p, v in pairs(hs) do + jogadores[idx] = rrpgWrappers.contextObjectFromID(v); + idx = idx + 1; + end + + return jogadores; + end + + function mesa:findBibliotecaItem(codigoInterno) return rrpgWrappers.objectFromID(_obj_invoke(self.handle, "TryFindBibliotecaItem", codigoInterno)); end; + + function mesa:findJogador(loginOuCodigoInterno) + if type(loginOuCodigoInterno) == "string" then + return rrpgWrappers.objectFromID(_obj_invoke(self.handle, "TryFindJogadorByLogin", loginOuCodigoInterno)); + elseif type(loginOuCodigoInterno) == "number" then + return rrpgWrappers.objectFromID(_obj_invoke(self.handle, "TryFindJogadorById", loginOuCodigoInterno)); + else + return nil; + end; + end; + + function mesa:getNome() return _obj_getProp(self.handle, "Nome"); end; + function mesa:getDescricao() return _obj_getProp(self.handle, "Descricao"); end; + function mesa:getMsgStatus() return _obj_getProp(self.handle, "MsgStatus"); end; + function mesa:getSite() return _obj_getProp(self.handle, "Site"); end; + function mesa:getLogotipo() return _obj_getProp(self.handle, "Logotipo"); end; + function mesa:getSistema() return _obj_getProp(self.handle, "Sistema"); end; + function mesa:getMsgBoasVindas() return _obj_getProp(self.handle, "MsgBoasVindas"); end; + function mesa:getCodigoInterno() return math.tointeger(_obj_getProp(self.handle, "CodigoInterno")); end; + function mesa:getIsRestrito18Anos() return _obj_getProp(self.handle, "IsRestrito18Anos"); end; + function mesa:getHaVagas() return _obj_getProp(self.handle, "HaVagas"); end; + function mesa:getIsModerada() return _obj_getProp(self.handle, "IsModerada"); end; + function mesa:getMeuJogador() return rrpgWrappers.contextObjectFromID(_obj_getProp(self.handle, "MeuJogadorObjectID")); end; + function mesa:getBiblioteca() return rrpgWrappers.contextObjectFromID(_obj_getProp(self.handle, "BibliotecaObjectID")); end; + function mesa:getPodeTablesDock() return _obj_getProp(self.handle, "PodeTablesDock"); end; + + function mesa:requestSetModerada(moderada) + moderada = Locale.autoEval(moderada); + __serverRequestQueue:addJob(function () _obj_invokeNoEval(self.handle, "RequestSetModerada", not (not moderada)); end); + end; + + function mesa:abrirNDBDeMesa(nome, callback, opcoes) + local ndbBib = require("ndb.lua"); + + if type(opcoes) ~= "table" then + opcoes = {}; + else + opcoes = Utils.cloneTable(opcoes, true); + end; + + opcoes.criar = not not opcoes.criar; + + local ndbHandle = _obj_invokeEx(self.handle, 'AbrirNDBDeMesa', tostring(nome) or "", opcoes.criar); + local ndbObj = nil; + local rootNode = nil; + + if ndbHandle ~= nil then + ndbObj = ndbBib.openNodeDatabaseFromHandle(ndbHandle); + end; + + if ndbObj ~= nil then + rootNode = ndbBib.getRoot(ndbObj); + end; + + if rootNode ~= nil then + local jaNotificou = false; + local jaNotificouEmCarregamento = false; + local listenerProvider = nil; + local listenerLoaded = nil; + + local function checkState() + if not jaNotificou then + local state = ndbBib.getState(rootNode); + + if state == "open" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, rootNode); + end; + elseif state == "closed" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, nil); + end; + else + if (not jaNotificouEmCarregamento) and (not jaNotificou) then + jaNotificouEmCarregamento = true; + + if opcoes.callbackDeCarga ~= nil then + opcoes.callbackDeCarga(rootNode); + end; + end; + end; + + if jaNotificou and (ndbObj ~= nil) then + ndbObj:removeEventListener(listenerProvider); + ndbObj:removeEventListener(listenerLoaded); + --ndbObj = nil; + end; + end; + end; + + listenerProvider = ndbObj:addEventListener("OnProviderStateChange", checkState); + listenerLoaded = ndbObj:addEventListener("OnLoaded", checkState); + + checkState(); + elseif callback ~= nil then + setTimeout(callback, 1, nil); + end; + end; + + function mesa:asyncOpenRoomNDB(name, options) + options = options or {}; + + local promise, resolution = Async.Promise.pending(); + + local adaptedOptions = {}; + adaptedOptions.criar = options.create; + + if options.skipLoad then + adaptedOptions.callbackDeCarga = + function(loadingNode) + resolution:setSuccess(loadingNode); + end; + end; + + self:abrirNDBDeMesa(name, + function(loadedNode) + if loadedNode ~= nil then + resolution:setSuccess(loadedNode); + else + resolution:setFailure("Could not load room nodedatabase"); + end; + end, + adaptedOptions); + + return promise; + end; + + function mesa:asyncOpenUserRoomNDB(name, options) + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncOpenUserRoomNDB", name, options)); + end); + end; + + function mesa:getFirecastURI() + return _obj_invokeEx(self.handle, "GetFirecastURI"); + end; + + function mesa:asyncOpenPVT(login, params) + local promiseHandle = _obj_invokeEx(self.handle, "AsyncOpenPVT", login, params); + return Async.Promise.wrap(promiseHandle); + end; + + function mesa:asyncCreateGroupPVT(logins, params) + local clonedLogins = Utils.cloneTable(logins); + local clonedParams = Utils.cloneTable(params); + + return __serverRequestQueue:addAsyncJob( + function () + local promiseHandle = _obj_invokeEx(self.handle, "AsyncCreateGroupPVT", clonedLogins, clonedParams); + return Async.Promise.wrap(promiseHandle); + end); + end; + + function mesa:getChats() + return _obj_invokeEx(self.handle, "GetChats"); + end; + + wObj.props["activeChat"] = {getter="getActiveChat", tipo="table"}; + wObj.props["audioPlayer"] = {getter="getAudioPlayer", tipo="table"}; + wObj.props["nome"] = {getter = "getNome", tipo = "string"}; + wObj.props["descricao"] = {getter = "getDescricao", tipo = "string"}; + wObj.props["msgStatus"] = {getter = "getMsgStatus", tipo = "string"}; + wObj.props["site"] = {getter = "getSite", tipo = "string"}; + wObj.props["logotipo"] = {getter = "getLogotipo", tipo = "string"}; + wObj.props["sistema"] = {getter = "getSistema", tipo = "string"}; + wObj.props["msgBoasVindas"] = {getter = "getMsgBoasVindas", tipo = "string"}; + wObj.props["codigoInterno"] = {getter = "getCodigoInterno", tipo = "int"}; + wObj.props["firecastURI"] = {getter = "getFirecastURI", tipo = "string"}; + wObj.props["isRestrito18Anos"] = {getter = "getIsRestrito18Anos", tipo = "bool"}; + wObj.props["haVagas"] = {getter = "getHaVagas", tipo = "bool"}; + wObj.props["isModerada"] = {getter = "getIsModerada", tipo = "bool"}; + wObj.props["podeTablesDock"] = {getter = "getPodeTablesDock", tipo = "bool"}; + wObj.props["jogadores"] = {getter = "getJogadores", tipo = "table"}; + wObj.props["meuJogador"] = {getter = "getMeuJogador", tipo = "table"}; + wObj.props["biblioteca"] = {getter = "getBiblioteca", tipo = "table"}; + wObj.props["chat"] = {getter="getChat", tipo="table"}; + + wObj.props["library"] = wObj.props["biblioteca"]; + wObj.props["me"] = wObj.props["meuJogador"]; + + return wObj; +end; + +--[ OBJETO JOGADOR ]-- + +local function initJogadorWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local jogador = wObj; + + function jogador:getMesa() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "MesaID")); end; + function jogador:getNick() return _obj_getProp(self.handle, "Nick"); end; + function jogador:getLogin() return _obj_getProp(self.handle, "Login"); end; + function jogador:getAvatar() return _obj_getProp(self.handle, "Avatar"); end; + function jogador:getCapa() return _obj_getProp(self.handle, "Capa"); end; + function jogador:getIsGold() return _obj_getProp(self.handle, "IsGold"); end; + function jogador:getIsGoldPlus() return _obj_getProp(self.handle, "IsGoldPlus"); end; + function jogador:getIsRuby() return _obj_getProp(self.handle, "IsRuby"); end; + function jogador:getIsAusente() return _obj_getProp(self.handle, "IsAusente"); end; + function jogador:getIsCnxDormente() return _obj_getProp(self.handle, "IsCnxDormente"); end; + function jogador:getIsSessaoMobile() return _obj_getProp(self.handle, "IsSessaoMobile"); end; + function jogador:getIsJuggernaut() return _obj_getProp(self.handle, "IsJuggernaut"); end; + function jogador:getIsMestre() return _obj_getProp(self.handle, "IsMestre"); end; + function jogador:getIsJogador() return _obj_getProp(self.handle, "IsJogador"); end; + function jogador:getIsEspectador() return _obj_getProp(self.handle, "IsEspectador"); end; + function jogador:getIsMudo() return _obj_getProp(self.handle, "IsMudo"); end; + function jogador:getIsCego() return _obj_getProp(self.handle, "IsCego"); end; + function jogador:getHaveVoice() return _obj_getProp(self.handle, "HaveVoice"); end; + function jogador:getCodigoInterno() return _obj_getProp(self.handle, "CodigoInterno"); end; + + function jogador:__innerRequestSetMode(modo, ativar) + modo, ativar = Locale.autoEval(modo, ativar); + + __serverRequestQueue:addJob(function() + _obj_invokeNoEval(self.handle, "RequestSetMode", modo, not (not ativar)); + end); + end; + + function jogador:requestSetCego(cego) self:__innerRequestSetMode("cego", cego); end; + function jogador:requestSetMudo(mudo) self:__innerRequestSetMode("mudo", mudo); end; + function jogador:requestSetVoz(voz) self:__innerRequestSetMode("voz", voz); end; + function jogador:requestSetJogador(isJogador) self:__innerRequestSetMode("jogador", isJogador); end; + function jogador:requestKick() __serverRequestQueue:addJob(function() _obj_invoke(self.handle, "RequestKick", ""); end); end; + function jogador:getBarValue(index) return _obj_invokeEx(self.handle, "LuaGetBarValue", index); end; + + function jogador:requestSetBarValue(index, currentValue, maxValue) + index, currentValue, maxValue = Locale.autoEval(index, currentValue, maxValue); + + __serverRequestQueue:addJob( + function() + _obj_invokeExNoEval(self.handle, "LuaRequestSetBarValue", index, currentValue, maxValue); + end); + end; + + function jogador:getEditableLine(index) return _obj_invokeEx(self.handle, "LuaGetEditableLine", index); end; + function jogador:requestSetEditableLine(index, text) index, text = Locale.autoEval(index, text); __serverRequestQueue:addJob(function() _obj_invokeExNoEval(self.handle, "LuaRequestSetEditableLine", index, text); end); end; + + wObj.props["mesa"] = {getter = "getMesa", tipo = "table"}; + wObj.props["nick"] = {getter = "getNick", tipo = "string"}; + wObj.props["login"] = {getter = "getLogin", tipo = "string"}; + wObj.props["avatar"] = {getter = "getAvatar", tipo = "string"}; + wObj.props["isGold"] = {getter = "getIsGold", tipo = "bool"}; + wObj.props["isGoldPlus"] = {getter = "getIsGoldPlus", tipo = "bool"}; + wObj.props["isRuby"] = {getter = "getIsRuby", tipo = "bool"}; + wObj.props["isAusente"] = {getter = "getIsAusente", tipo = "bool"}; + wObj.props["isCnxDormente"] = {getter = "getIsCnxDormente", tipo = "bool"}; + wObj.props["isSessaoMobile"] = {getter = "getIsSessaoMobile", tipo = "bool"}; + wObj.props["isJuggernaut"] = {getter = "getIsJuggernaut", tipo = "bool"}; + wObj.props["isMestre"] = {getter = "getIsMestre", tipo = "bool"}; + wObj.props["isJogador"] = {getter = "getIsJogador", tipo = "bool"}; + wObj.props["isEspectador"] = {getter = "getIsEspectador", tipo = "bool"}; + wObj.props["isMudo"] = {getter = "getIsMudo", tipo = "bool"}; + wObj.props["isCego"] = {getter = "getIsCego", tipo = "bool"}; + wObj.props["haveVoice"] = {getter = "getHaveVoice", tipo = "bool"}; + wObj.props["haveVoz"] = {getter = "getHaveVoice", tipo = "bool"}; + wObj.props["codigoInterno"] = {getter = "getCodigoInterno", tipo = "int"}; + wObj.props["personagemPrincipal"] = {readProp="PersonagemPrincipal", tipo = "int"}; + wObj.props["id"] = {readProp="ID", tipo = "int"}; + + return wObj; +end; + +--[ OBJETO BIBLIOTECA ITEM ]-- + +local function initBibliotecaItemWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local bibItem = wObj; + + function bibItem:getFilhos() + local hs = _obj_getProp(self.handle, "FilhosObjectIDs"); + local filhos = {}; + local idx = 1; + + for p, v in pairs(hs) do + filhos[idx] = rrpgWrappers.objectFromID(v); + idx = idx + 1; + end + + return filhos; + end; + + function bibItem:__asyncCreateBibItem(bibItemType, params) + assert(type(params) == "table"); + + local innerPromise = __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncCreateBibItemObjectID", bibItemType, params)); + end); + + return Async.Promise.toHandle(innerPromise, + function (newObjectID) + local newObj = rrpgWrappers.contextObjectFromID(newObjectID); + + if newObj ~= nil then + return newObj; + else + error("Could not find the new created library item"); + end; + end); + end; + + function bibItem:asyncCreateChar(charParams) + if type(charParams) ~= "table" then + error("charParams must be a table"); + end; + + if charParams.name == nil then + error("Required field: charParams.name"); + end; + + if charParams.name == nil then + error("Required field: charParams.dataType"); + end; + + return bibItem:__asyncCreateBibItem('character', charParams); + end; + + function bibItem:asyncCreateDir(dirParams) + if type(dirParams) ~= "table" then + error("dirParams must be a table"); + end; + + if dirParams.name == nil then + error("Required field: dirParams.name"); + end; + + return bibItem:__asyncCreateBibItem('directory', dirParams); + end; + + function bibItem:asyncCreateScene3(gridParams) + if type(gridParams) ~= "table" then + error("gridParams must be a table"); + end; + + if gridParams.name == nil then + error("Required field: gridParams.name"); + end; + + return bibItem:__asyncCreateBibItem('scene3', gridParams); + end; + + function bibItem:asyncDelete() + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(bibItem.handle, "AsyncDelete")); + end); + end; + + function bibItem:asyncMoveTo(newParent) + if type(newParent) ~= 'table' then + error('Parameter "newParent" must be an object'); + end; + + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(bibItem.handle, "AsyncMoveTo", newParent.objectID)); + end); + end; + + function bibItem:asyncUpdate(changes) + if type(changes) ~= 'table' then + error('Parameter "changes" must be a table'); + end; + + return __serverRequestQueue:addAsyncJob( + function () + return Async.Promise.wrap(_obj_invokeEx(bibItem.handle, "AsyncUpdate", changes)); + end); + end; + + function bibItem:getFirecastURI() + return _obj_invokeEx(self.handle, "GetFirecastURI"); + end; + + function bibItem:getMesa() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "MesaObjectID")); end; + function bibItem:getNome() return _obj_getProp(self.handle, "Nome"); end; + function bibItem:getPai() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "ItemMaeObjectID")); end; + function bibItem:getDono() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "JogadorOwnerObjectID")); end; + function bibItem:getLoginDono() return _obj_getProp(self.handle, "LoginDono"); end; + function bibItem:getCriador() return rrpgWrappers.objectFromID(_obj_getProp(self.handle, "JogadorCriadorObjectID")); end; + function bibItem:getLoginCriador() return _obj_getProp(self.handle, "LoginCriador"); end; + function bibItem:getVisivel() return _obj_getProp(self.handle, "Visivel"); end; + function bibItem:getVisivelRecursivamente() return _obj_getProp(self.handle, "VisivelNaHierarquia"); end; + function bibItem:getTipo() return _obj_getProp(self.handle, "Tipo"); end; + function bibItem:getCodigoInterno() return _obj_getProp(self.handle, "CodigoInterno"); end; + + wObj.props["mesa"] = {getter = "getMesa", tipo = "table"}; + wObj.props["filhos"] = {getter = "getFilhos", tipo = "table"}; + wObj.props["pai"] = {getter = "getPai", tipo = "table"}; + wObj.props["nome"] = {getter = "getNome", tipo = "string"}; + wObj.props["dono"] = {getter = "getDono", tipo = "table"}; + wObj.props["loginDono"] = {getter = "getLoginDono", tipo = "string"}; + wObj.props["criador"] = {getter = "getCriador", tipo = "table"}; + wObj.props["loginCriador"] = {getter = "getLoginCriador", tipo = "string"}; + wObj.props["visivel"] = {getter = "getVisivel", tipo = "bool"}; + wObj.props["visivelRecursivamente"] = {getter = "getVisivelRecursivo", tipo = "bool"}; + wObj.props["tipo"] = {getter = "getTipo", tipo = "string"}; + wObj.props["codigoInterno"] = {getter = "getCodigoInterno", tipo = "int"}; + + wObj.props["room"] = wObj.props["mesa"]; + wObj.props["parent"] = wObj.props["pai"]; + wObj.props["name"] = wObj.props["nome"]; + wObj.props["children"] = wObj.props["filhos"]; + wObj.props["firecastURI"] = {getter = "getFirecastURI", tipo = "string"}; + wObj.props["ownerLogin"] = wObj.props["loginDono"]; + wObj.props["creatorLogin"] = wObj.props["loginCriador"]; + wObj.props["creator"] = wObj.props["criador"]; + wObj.props["owner"] = wObj.props["dono"]; + wObj.props["visible"] = wObj.props["visivel"]; + wObj.props["recursiveVisible"] = wObj.props["visivelRecursivamente"]; + return wObj; +end; + +--[ OBJETO PERSONAGEM ]-- + +local __PersonagemWrappedObjectProps = {}; + +for i = 0, 3 do + local barIndex = i; + + __PersonagemWrappedObjectProps["bar" .. tostring(i) .. "Val"] = {tipo = "int", getter = function (personagem) + return _obj_invokeEx(personagem.handle, "GetBarVal", barIndex) + end}; + + __PersonagemWrappedObjectProps["bar" .. tostring(i) .. "Max"] = {tipo = "int", getter = function (personagem) + return _obj_invokeEx(personagem.handle, "GetBarMax", barIndex) + end}; +end; + +for i = 0, 1 do + local edtLineIndex = i; + + __PersonagemWrappedObjectProps["edtLine" .. tostring(i)] = {tipo = "string", getter = function (personagem) + return _obj_invokeEx(personagem.handle, "GetEdtLine", edtLineIndex) + end}; +end; + +local function initBibPersonagemWrappedObjectFromHandle(handle) + local wObj = initBibliotecaItemWrappedObjectFromHandle(handle); + local bibItem = wObj; + + function bibItem:getDataType() return _obj_getProp(self.handle, "DataType"); end; + function bibItem:getEscritaBloqueada() return _obj_getProp(self.handle, "EscritaBloqueada"); end; + + function bibItem:loadSheetNDB(callback, params) + params = params or {}; + + local ndbBib = require("ndb.lua"); + local ndbHandle = _obj_invokeEx(self.handle, 'GetOrCreateSheetNDB'); + + local function scheduleFailReturn() + if callback ~= nil then + setTimeout(callback, 1, nil); + end; + end; + + if ndbHandle == nil then + scheduleFailReturn(); + return; + end; + + local ndbObj = nil; + local rootNode = nil; + + if ndbHandle ~= nil then + ndbObj = ndbBib.openNodeDatabaseFromHandle(ndbHandle); + end; + + if ndbObj ~= nil then + rootNode = ndbBib.getRoot(ndbObj); + end; + + if rootNode == nil then + scheduleFailReturn(); + return; + end; + + local state = ndbBib.getState(rootNode); + + if (state == "open") or + ((state == "opening") and (params.skipLoad)) then + -- Already loaded + if callback ~= nil then + callback(rootNode); + end; + + return; + end; + + -- Not loaded yet, letz monitor + + local jaNotificou = false; + local listenerProvider = nil; + local listenerLoaded = nil; + + local function checkState() + if not jaNotificou then + state = ndbBib.getState(rootNode); + + if state == "open" then + jaNotificou = true; + + if callback ~= nil then + setTimeout(callback, 1, rootNode); + end; + elseif state == "closed" then + jaNotificou = true; + scheduleFailReturn(); + end; + + if jaNotificou then + ndbObj:removeEventListener(listenerProvider); + ndbObj:removeEventListener(listenerLoaded); + end; + end; + end; + + listenerProvider = ndbObj:addEventListener("OnProviderStateChange", checkState); + listenerLoaded = ndbObj:addEventListener("OnLoaded", checkState); + + checkState(); + end; + + function bibItem:asyncOpenNDB(options) + options = options or {}; + local promise, resolution = Async.Promise.pending(); + + self:loadSheetNDB( + function (loadedNDB) + if loadedNDB ~= nil then + resolution:setSuccess(loadedNDB); + else + resolution:setFailure("Could not load character nodedatabase"); + end; + end, options); + + return promise; + end; + + wObj.props["dataType"] = {getter = "getDataType", tipo = "string"}; + wObj.props["escritaBloqueada"] = {getter = "getEscritaBloqueada", tipo = "bool"}; + wObj.props["avatar"] = {readProp="Avatar", tipo = "string"}; + + for k, v in pairs(__PersonagemWrappedObjectProps) do + wObj.props[k] = v; + end; + + wObj.props["editionBlocked"] = wObj.props["escritaBloqueada"]; + return wObj; +end; + +--[ OBJETO SceneUnitClass ]-- + +local function initBibSceneUnitClassWrappedObjectFromHandle(handle) + local wObj = initBibliotecaItemWrappedObjectFromHandle(handle); + + wObj.props["tamanhoX"] = {readProp = "TamanhoX", tipo = "double"}; + wObj.props["tamanhoY"] = {readProp = "TamanhoY", tipo = "double"}; + wObj.props["camada"] = {readProp = "Camada", tipo = "enum", values={"tokens", "objects", "background"}}; + wObj.props["descricao"] = {readProp = "Descricao", tipo = "string"}; + wObj.props["urlImg"] = {readProp = "URLImg", tipo = "string"}; + wObj.props["facing"] = {readProp = "Facing", tipo = "enum", values={"rotate", "drawArrow"}}; + wObj.props["snapToGrid"] = {readProp = "SnapToGrid", tipo = "bool"}; + wObj.props["direcaoImg"] = {readProp = "DirecaoImg", tipo = "double"}; + wObj.props["layoutCenterX"] = {readProp = "LayoutCenterX", tipo = "double"}; + wObj.props["layoutCenterY"] = {readProp = "LayoutCenterY", tipo = "double"}; + wObj.props["layoutTamX"] = {readProp = "LayoutTamX", tipo = "double"}; + wObj.props["layoutTamY"] = {readProp = "LayoutTamY", tipo = "double"}; + + return wObj; +end; + + +--[ OBJETO CHAT ]-- + +local function _setupCallbackTrapForUniqueRoll(idOfRoll, callbackFunction) + local trabTable = {}; + + trabTable.listenerId = rrpg.messaging.listenOnce("InternalRollCallbackReceive", + function(msg) + clearTimeout(trabTable.timeoutId); + trabTable.timeoutId = nil; + + if type(callbackFunction) == "function" then + local rolagemObject = rrpg.loadRolagemFromBase64EncodedString(msg.rollBase64 or ""); + callbackFunction(rolagemObject); + end; + end, {id=idOfRoll}); + + trabTable.timeoutId = setTimeout( + function() + rrpg.messaging.unlisten(trabTable.listenerId); + trabTable.listenerId = nil; + end, 120000); +end; + +local _NULL_FUNCTION = function() end; +local _NULL_ARRAY_FUNCTION = function() return {}; end; +local _NULL_PROMISE_FUNCTION = function() Async.Promise.failed("Chat is not alive"); end; + +rrpgWrappers.NullChatWrapper = {enviarMensagem = _NULL_FUNCTION, + rolarDados = _NULL_FUNCTION, + enviarAcao = _NULL_FUNCTION, + enviarRisada = _NULL_FUNCTION, + enviarMensagemNPC = _NULL_FUNCTION, + enviarNarracao = _NULL_FUNCTION, + setImpersonation = _NULL_FUNCTION, + readLogRecs = _NULL_ARRAY_FUNCTION, + asyncQueryLogRecs = _NULL_PROMISE_FUNCTION, + asyncSendLaugh = _NULL_PROMISE_FUNCTION, + asyncSendAction = _NULL_PROMISE_FUNCTION, + asyncSendStd = _NULL_PROMISE_FUNCTION, + asyncInvite = _NULL_PROMISE_FUNCTION, + participants = {}, + medium = {kind="undefined"} + }; + +local function initBaseChatWrappedObjectFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + local wChat = wObj; + + function wChat:_getTimedJobQueue() + local queue = rawget(self, "_timedJobQueue"); + + if queue == nil then + queue = newTimedJobQueue(250); + rawset(self, "_timedJobQueue", queue); + end; + + return queue; + end; + + function wChat:_getLongTimedJobQueue() + local queue = rawget(self, "_longTimedJobQueue"); + + if queue == nil then + queue = newTimedJobQueue(1000); + rawset(self, "_longTimedJobQueue", queue); + end; + + return queue; + end; + + function wChat:escrever(texto, quebrarLinha, permitirSmileys) + if quebrarLinha == nil then + quebrarLinha = true; + end; + + if permitirSmileys == nil then + permitirSmileys = true; + end; + + if texto ~= nil then + return _obj_invokeEx(self.handle, "Escrever", tostring(texto), quebrarLinha, permitirSmileys); + end; + end; + + function wChat:enviarMensagem(msg, callback) + msg = Locale.autoEval(tostring(msg)); + + if msg ~= nil then + local queue = self:_getTimedJobQueue() + + function queuedSendTheMessage() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarMensagem", msg); + + if type(callback) == 'function' then + callback(); + end; + end; + end; + + queue:addJob(queuedSendTheMessage); + end; + end; + + function wChat:enviarMensagemNPC(npc, msg, callback) + npc, msg = Locale.autoEval(npc, msg); + + if msg ~= nil and npc ~= nil then + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarMensagemNPC", tostring(npc), tostring(msg)); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + end; + + function wChat:enviarNarracao(msg, callback) + msg = Locale.autoEval(msg); + + if msg ~= nil then + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarNarracao", tostring(msg)); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + end; + + function wChat:enviarAcao(acao, callback) + acao = Locale.autoEval(acao); + + if acao ~= nil then + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invokeNoEval(wChat.handle, "EnviarAcao", tostring(acao)); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + end; + + function wChat:enviarRisada(callback) + local queue = self:_getTimedJobQueue() + + queue:addJob(function() + if self.handle ~= nil then + _obj_invoke(wChat.handle, "EnviarRisada"); + + if type(callback) == 'function' then + callback(); + end; + end; + end); + end; + + function wChat:rolarDados(rolagem, msg, callbackFunction) + local rolAsStr; + msg = Locale.autoEval(msg); + + if type(rolagem) == "string" then + rolAsStr = Locale.autoEval(rolagem); + elseif (type(rolagem) == "table") and (rolagem.getAsString ~= nil) then + rolAsStr = rolagem:getAsString(); + else + rolAsStr = nil; + end; + + if rolAsStr ~= nil then + local queue = self:_getTimedJobQueue() + --local queue = __serverRequestQueue; + + if type(callbackFunction) == "function" then + local idUnicaRolagem = _rrpg_generateUniqueMessageIDForMe(); + _setupCallbackTrapForUniqueRoll(idUnicaRolagem, callbackFunction); + + queue:addJob( + function () + if self.handle ~= nil then + return _obj_invokeNoEval(self.handle, "EnviarRolagemEx", rolAsStr, msg, idUnicaRolagem); + end; + end); + else + queue:addJob( + function () + if self.handle ~= nil then + return _obj_invokeNoEval(self.handle, "EnviarRolagem", rolAsStr, msg); + end; + end); + end; + end; + end; + + function wChat:getRoom() + local selfHandle = rawget(self, "handle"); + + if selfHandle ~= nil then + mesaObjectID = _rrpg_tryGetMesaObjectIDRelatedToHandle(selfHandle); + + if (mesaObjectID ~= nil) then + mesaObjectID = tonumber(mesaObjectID); + end; + + if mesaObjectID ~= nil then + return rrpgWrappers.contextObjectFromID(mesaObjectID); + end; + end; + end; + + function wChat:__asyncSendEx(msgDesc, params) + local finalMsgDesc = Utils.cloneTable(params) or {}; + + for k, v in pairs(msgDesc) do + finalMsgDesc[k] = v; + end; + + local queue = self:_getTimedJobQueue() + + return queue:addAsyncJob( + function() + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncSendEx", finalMsgDesc)); + end); + end; + + function wChat:asyncSendStd(content, params) + return self:__asyncSendEx({msgType="standard", content=content}, params); + end; + + function wChat:asyncSendAction(content, params) + return self:__asyncSendEx({msgType="action", content=content}, params); + end; + + function wChat:asyncSendLaugh(params) + return self:__asyncSendEx({msgType="laugh"}, params); + end; + + function wChat:asyncRoll(expression, message, params) + local expressionAsStr; + + if type(expression) == "string" then + expressionAsStr = Locale.autoEval(expression); + elseif (type(expression) == "table") and (expression.getAsString ~= nil) then + expressionAsStr = expression:getAsString(); + else + expressionAsStr = nil; + end; + + local sendPromise = self:__asyncSendEx({msgType="dice", expression=expressionAsStr, content=message}, params); + + return sendPromise:thenDo( + function(logRec) + local roll = logRec.msg.roll; + assert(roll ~= nil); + + return roll.resultado, roll, logRec; + end); + end; + + function wChat:readLogRecs() + return _obj_invokeEx(self.handle, "ReadValidLogRecs"); + end; + + function wChat:getImpersonation() + return _obj_invokeEx(self.handle, "GetUIImpersonation"); + end; + + function wChat:setImpersonation(impersonation) + return _obj_invokeEx(self.handle, "SetUIImpersonation", impersonation); + end; + + function wChat:getTalemarkOptions() + return _obj_invokeEx(self.handle, "GetTalemarkOptions"); + end; + + function wChat:setTalemarkOptions(options) + return _obj_invokeEx(self.handle, "SetTalemarkOptions", options); + end; + + function wChat:getMedium() + return _obj_invokeEx(self.handle, "GetMedium"); + end; + + function wChat:getParticipants() + return _obj_invokeEx(self.handle, "GetParticipants"); + end; + + function wChat:asyncQueryLogRecs(params) + params = Utils.cloneTable(params or {}); + + local queue = self:_getLongTimedJobQueue() + + return queue:addAsyncJob( + function() + return Async.Promise.wrap(_obj_invokeEx(self.handle, "AsyncQueryLogRecsFromServer", params)); + end); + end; + + function wChat:writeEx(text, talemarkOptions) + return _obj_invokeEx(self.handle, "WriteEx", text, talemarkOptions); + end; + + function wChat:asyncInvite(logins) + local clonedLogins = Utils.cloneTable(logins); + + return __serverRequestQueue:addAsyncJob( + function () + local promiseHandle = _obj_invokeEx(self.handle, "AsyncInvite", clonedLogins); + return Async.Promise.wrap(promiseHandle); + end); + end; + + wChat.props["room"] = {getter = "getRoom", tipo = "table"}; + wChat.props["impersonation"] = {getter = "getImpersonation", setter = "setImpersonation", tipo = "table"}; + wChat.props["talemarkOptions"] = {getter = "getTalemarkOptions", setter="setTalemarkOptions", tipo = "table"}; + wChat.props["medium"] = {getter = "getMedium", tipo = "table" }; + wChat.props["participants"] = {getter = "getParticipants", tipo = "table" }; + + -- aliases + wChat.write = wChat.escrever; + + return wObj; +end; + +function rrpgWrappers.contextObjectFromID(objectID) + local ctxObj = localStrongRefContextoObjects[objectID]; + + if ctxObj ~= nil then + return ctxObj; + end; + + local objWrapperHandle; + objWrapperHandle = _rrpg_GetOrCreateObjectWrapperForObjectID(objectID); + + if objWrapperHandle == nil then + return nil; + end; + + ctxObj = objs.tryFindFromHandle(objWrapperHandle); + + if ctxObj ~= nil then + if _rrpg_IsObjectIDAlive(objectID) then + localStrongRefContextoObjects[objectID] = ctxObj; + end; + + return ctxObj; + end; + + + if _rrpg_IsWrapperOfType(objWrapperHandle, "mesa") then + ctxObj = initMesaWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "jogador") then + ctxObj = initJogadorWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "personagem") then + ctxObj = initBibPersonagemWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "sceneUnitClass") then + ctxObj = initBibSceneUnitClassWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "bibliotecaItem") then -- Deve ser o ultimo dos IFs dos Wrappers dos tipos de item de biblioteca + ctxObj = initBibliotecaItemWrappedObjectFromHandle(objWrapperHandle); + elseif _rrpg_IsWrapperOfType(objWrapperHandle, "chatBase") then -- Deve ser o ultimo dos IFs dos Wrappers dos tipos de CHAT + ctxObj = initBaseChatWrappedObjectFromHandle(objWrapperHandle); + else + ctxObj = initWrappedObjectFromHandle(objWrapperHandle); + end; + + objs.registerHandle(objWrapperHandle, ctxObj); + + if _rrpg_IsObjectIDAlive(objectID) then + localStrongRefContextoObjects[objectID] = ctxObj; + end; + + return ctxObj; +end; + +function rrpgWrappers.objectFromID(objectID) + return rrpgWrappers.contextObjectFromID(objectID); +end; + +function _INTERNAL_EVE_OnWrappedObjectWasDestroyed(objectID) + localStrongRefContextoObjects[objectID] = nil; -- Permitir o Garbage Collector coletar este objeto +end; + +function _INTERNAL_AUX_ContextObjectFromID(objectID) + return rrpgWrappers.contextObjectFromID(objectID); +end; + +function _INTERNAL_AUX_NullChatWrapper() + return rrpgWrappers.NullChatWrapper; +end; + +SharedObjects.registerUnpacker(SHARED_OBJECT_TYPE, + function (sid) + local objectIdN = tonumber(sid.objectID); + + if objectIdN ~= nil then + return rrpgWrappers.contextObjectFromID(objectIdN); + else + return nil; + end; + end); + +return rrpgWrappers; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/scene.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/scene.lua new file mode 100644 index 00000000..ff21abba --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/scene.lua @@ -0,0 +1,13 @@ +local _SceneLib = require("delayedLoad.dlua").new("sceneCore.dlua"); +local _SceneWrapperLib = nil; + +function _INTERNAL_export_getSceneObjectFromID(objectID) + if _SceneWrapperLib == nil then + _SceneWrapperLib = require("sceneWrappers.dlua"); + end; + + return _SceneWrapperLib.objectFromID(objectID); +end; + +SceneLib = _SceneLib; +return _SceneLib; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneCore.dlua new file mode 100644 index 00000000..c0651997 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneCore.dlua @@ -0,0 +1,146 @@ +local Objs = require("rrpgObjs.lua") +local SceneWrappers = require("sceneWrappers.dlua"); +require("utils.lua"); +require("rrpg.lua"); + +local SceneLib = {}; +local LocalSceneLib = {}; + + +-- OBJETO SC3PLUGIN + +local __runningPlugins = {}; + +function LocalSceneLib.newPlugin() + local handle = _obj_newObject('TSC3LuaPlugin'); + local o = Objs.objectFromHandle(handle); + + + Objs.registerHandle(handle, o); + return o; +end; + +-- Funções públicas da SceneLib + +function SceneLib.registerPlugin(attachCallback) + local plug = LocalSceneLib.newPlugin(); + local pluginAttachments = {}; + + __runningPlugins[plug.handle] = plug; + + setTimeout( + function() + if __runningPlugins[plug.handle] ~= nil then + _obj_invoke(plug.handle, "RegisterYourself"); + end; + end, 1); + + local function startAttachToScene(scene) + local oID = scene.objectID; + local att = pluginAttachments[oID]; + + if att ~= nil then + return; + end; + + att = Objs.objectFromHandle(_obj_invoke(plug.handle, "LuaCreatePluginAttachment", oID)); + + if att ~= nil then + Objs.registerHandle(att.handle, att); + + local eves = att.eves; + + if eves == nil then + att.eves = {}; + eves = att.eves; + end; + + eves["OnDettach"] = ""; + + pluginAttachments[oID] = att; + + if attachCallback ~= nil then + setTimeout(function() + if scene ~= nil and scene.isObjectAlive then + attachCallback(scene, att); + end; + end, 1) + end; + end; + end; + + local function startDettachFromScene(scene) + local oID = scene.objectID; + local att = pluginAttachments[oID]; + + if att ~= nil then + pluginAttachments[oID] = nil; + end; + end; + + -- Anexar aos scenes já rodando... + local scenes = SceneLib.getLoadedScenes(); + + for i = 1, #scenes, 1 do + startAttachToScene(scenes[i]); + end; + + -- Instalar listeners para detectar novos scenes rodando + + plug._lstSceneLoaded = RRPG.listen('SC3SceneLoaded', + function(msg) + if msg.scene ~= nil then + startAttachToScene(msg.scene); + msg.scene = nil; + end; + end); + + plug._lstSceneUnloaded = RRPG.listen('SC3SceneUnloaded', + function(msg) + if msg.scene ~= nil then + startDettachFromScene(msg.scene); + msg.scene = nil; + end; + end); + + return plug.handle; +end; + +function SceneLib.unregisterPlugin(pluginHandle) + local plug = __runningPlugins[pluginHandle]; + + if plug ~= nil then + if plug._lstSceneUnloaded ~= nil then + RRPG.unlisten(plug._lstSceneUnloaded); + plug._lstSceneUnloaded = nil; + end; + + if plug._lstSceneLoaded ~= nil then + RRPG.unlisten(plug._lstSceneLoaded); + plug._lstSceneLoaded = nil; + end; + + _obj_invoke(plug.handle, "UnregisterYourself"); + __runningPlugins[pluginHandle] = nil; + _obj_invoke(plug.handle, "DettachAllAttachments"); + end; +end; + +function SceneLib.getLoadedScenes() + local L = _scene3_GetLoadedScenesObjectIDs(); + + for i = 1, #L, 1 do + L[i] = SceneWrappers.objectFromID(L[i]); + end; + + return L; +end; + + +SceneLib.Math = {}; + +SceneLib.Math.newRotationMatrix = _scene3_math_newRotationMatrix; +SceneLib.Math.transformPoint = _scene3_math_transformPoint; +SceneLib.Math.rotatePoint = _scene3_math_rotatePoint; + +return SceneLib; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneWrappers.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneWrappers.dlua new file mode 100644 index 00000000..d93f30c7 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sceneWrappers.dlua @@ -0,0 +1,1123 @@ +local Objs = require("rrpgObjs.lua"); +local objs = Objs; +local NDB = require("ndb.lua"); +local GUI = nil; + +local _userDataScopeAttr = '__userDataScope'; + +local SceneWrappers = {}; + +local _localStrongRefSceneObjects = {}; + +--- [[ Wrapper Object BASE ]] +local function initWrappedObjectFromHandle(handle) + local wObj = Objs.objectFromHandle(handle); + + if (wObj.props == nil) then + wObj.props = {}; + end; + + function wObj:getObjectID() return _obj_getProp(self.handle, "ObjectID"); end; + function wObj:getObjectType() return _obj_getProp(self.handle, "WrappedObjectType"); end; + function wObj:getIsObjectAlive() return _obj_getProp(self.handle, "IsObjectAlive"); end; + function wObj:isType(typeName) return _scene3_IsWrapperOfType(self.handle, typeName); end; + function wObj:beginUpdate() _obj_invoke(self.handle, "BeginUpdate"); end; + function wObj:endUpdate() _obj_invoke(self.handle, "EndUpdate"); end; + function wObj:getUserData() return _obj_invokeEx(self.handle, "GetUserData"); end; + + function wObj:newUserDataLink(field) + if GUI == nil then + GUI = require("gui.lua"); + end; + + local dataScope = rawget(self, _userDataScopeAttr); + + if dataScope == nil then + dataScope = Objs.hierarchyObjectFromHandle(_obj_newObject("nonVisualDataScope")); + rawset(self, _userDataScopeAttr, dataScope); + _obj_invokeEx(self.handle, "PrepareUserDataScope", dataScope.handle); + end + + local dl = GUI.newDataLink(); + + if field ~= nil then + dl.field = field; + end; + + dl:setParent(dataScope); + return dl; + end; + + wObj.props["objectType"] = {getter = "getObjectType", tipo = "string"}; + wObj.props["isObjectAlive"] = {getter = "getIsObjectAlive", tipo = "bool"}; + wObj.props["objectID"] = {getter = "getObjectID", tipo = "int"}; + wObj.props["userData"] = {getter = "getUserData", tipo = "table"}; + + rawset(wObj, "objectID", wObj:getObjectID()); + return wObj; +end; + +--- [[ Wrapper Object SCENE ]] + +local __sceneProps = {worldWidth = {tipo = "double", readProp = "WorldWidth", writeProp = "WorldWidth"}, + worldHeight = {tipo = "double", readProp = "WorldHeight", writeProp = "WorldHeight"}, + worldMetricName = {tipo = "string", readProp = "WorldMetricName", writeProp = "WorldMetricName"}, + bkgColor = {tipo = "color", readProp = "BkgColor", writeProp = "BkgColor"}, + bkgImageURL = {tipo = "string", readProp="BkgImageURL", writeProp = "BkgImageURL"}, + workingLayer = {tipo = "enum", readProp = "WorkingLayer", writeProp = "WorkingLayer", values={"background", "objects", "tokens"}}, + viewport = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_scene3_getViewportObjectIDOfScene(obj.objectID)); end;}, + grid = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "GridLayerObjectID")); end;}, + items = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "ItemsObjectID")); end}, + fogOfWar = {tipo = "table", getter=function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "FogOfWarObjectID")); end}, + isGM = {tipo="bool", readProp="IsGM"}, + currentUserID = {tipo="string", readProp="CurrentUserID"}, + isViewingAsGM = {tipo="bool", readProp="IsViewingAsGM", writeProp = "IsViewingAsGM"}, + isViewingWalls = {tipo="bool", readProp="IsViewingWalls", writeProp = "IsViewingWalls"}, + renderAsPlayer = {tipo="bool", readProp="RenderAsPlayer"}}; + +local __sceneEvents = {onWorkingLayerChange="", + onGMStateChange=""}; + +local __sceneMethods = { + newTransaction = function(scene) + local tr = Objs.objectFromHandle(_obj_newObject("TLuaScene3Transaction")); + Objs.registerHandle(tr.handle, tr); + _obj_invoke(tr.handle, "Initialize", scene.objectID); + + tr.commit = function(trObj) + _obj_invoke(trObj.handle, "Commit"); + end; + + tr.rollback = function(trObj) + _obj_invoke(trObj.handle, "Rollback"); + end; + + tr.createUndoData = function (trObj) + local handle = _obj_invoke(trObj.handle, "CreateUndoData"); + local obj = objs.objectFromHandle(handle); + objs.registerHandle(handle, obj); + return obj; + end; + + tr.applyUndoData = function(trObj, undoData) + _obj_invoke(trObj.handle, "ApplyUndoData", undoData.handle); + end; + + return tr; + end, + + pushTransaction = function(scene, transaction) + local trHandle; + + if transaction ~= nil then + trHandle = transaction.handle or 0; + else + trHandle = 0; + end; + + _obj_invoke(scene.handle, "PushTransaction", trHandle); + end, + + popTransaction = function(scene) + _obj_invoke(scene.handle, "PopTransaction"); + end, + + processCommand = function(scene, command) + return _obj_invokeEx(scene.handle, "ProcessCommand", command); + end, + + broadcastMessage = function(scene, messageId, message, loopBack) + local node = _obj_invokeEx(scene.handle, "LuaGetSceneNode"); + + if node ~= nil then + return NDB.broadcastMessage(node, messageId, message, loopBack); + end; + end, + + newBroadcastListener = function(scene, messageId, callback) + local node = _obj_invokeEx(scene.handle, "LuaGetSceneNode"); + + if node ~= nil then + return NDB.newBroadcastListener(node, messageId, + function(sender, returnedMessageId, message) + if scene.isObjectAlive and (callback ~= nil) then + callback(sender, returnedMessageId, message); + end; + end); + end; + end, + + sendDelayedUpdates = function(scene) + return _obj_invoke(scene.handle, "SendDelayedUpdates"); + end + + }; + +local function initWrappedSceneFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__sceneProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__sceneMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __sceneEvents; + return wObj; +end; + +--- [[ Wrapper Object VIEWPORT ]] + +local __viewportProps = {width = {tipo = "double", readProp = "Width"}, + height = {tipo = "double", readProp = "Height"}, + worldX = {tipo = "double", readProp = "WorldX", writeProp = "WorldX"}, + worldY = {tipo = "double", readProp = "WorldY", writeProp = "WorldY"}, + scale = {tipo = "double", readProp = "Scale", writeProp = "Scale"}, + cursor = {tipo = "enum", readProp = "Cursor", writeProp = "Cursor"}, + scene = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "SceneObjectID")); end;}}; + +local __viewportMethods = {screenToWorld = + function(vp, screenX, screenY) + return _obj_invokeEx(vp.handle, "ScreenToWorld", screenX, screenY); + end, + + worldToScreen = + function (vp, worldX, worldY) + return _scene3_ViewPort_WorldToScreen(vp.handle, worldX, worldY); + end, + + getScrollBounds = function(vp) return _obj_invokeEx(vp.handle, "GetScrollBounds"); end; + + setupToolCategory = + function(vp, name, title, order) + _obj_invoke(vp.handle, "SetupToolCategory", tostring(name), tostring(title), tonumber(order)); + end, + + addToolButton = + function (vp, categoryName, title, iconURL, order, options, callback, deactivationCallback) + if type(options) ~= "table" then + options = {}; + end; + + local hBtn = _obj_newObject("SC3ToolButton"); + local o = Objs.objectFromHandle(hBtn); + Objs.registerHandle(hBtn, o); + + if callback ~= nil then + o:listen("OnCallback", callback); + end; + + if deactivationCallback ~= nil then + o:listen("OnDeactivationCallback", deactivationCallback); + end; + + _obj_invoke(hBtn, "SetViewport", vp.objectID); + _obj_invokeEx(hBtn, "SetupButton", categoryName, title, iconURL, order, options); + + local tblTools = rawget(vp, "_TblTools"); + + if tblTools == nil then + tblTools = {}; + rawset(vp, "_TblTools", tblTools); + end; + + local genID = (tblTools.generator or 0) + 1; + tblTools.generator = genID; + + tblTools[genID] = o; + return genID; + end, + + removeToolButton = + function (vp, toolID) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + _obj_invoke(o.handle, "RemoveButton"); + tblTools[toolID] = nil; + end; + end; + end, + + checkToolButton = function(vp, toolID, checked) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + if checked == nil then + checked = true; + end; + + _obj_invoke(o.handle, "CheckToolButton", not not checked); + end; + end; + end, + + isToolButtonChecked = function(vp, toolID) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + return _obj_getProp(o.handle, "IsChecked"); + end; + end; + + return false; + end, + + selectToolButton = function(vp, toolID) + local tblTools = rawget(vp, "_TblTools"); + + if tblTools ~= nil then + local o = tblTools[toolID]; + + if o ~= nil then + _obj_invoke(o.handle, "Select"); + end; + end; + end, + + selectDefaultToolButton = function(vp) + _obj_invoke(vp.handle, "SelectDefaultToolButton"); + end, + + needRepaint = function (vp) + _obj_invoke(vp.handle, "NeedRepaint"); + end, + + showForm = function(vp, form, options) + if (form == nil) then + error("invalid parameter - form is nil"); + return false; + end; + + if type(options) ~= "table" then + options = {}; + end; + + local _popupFormShowers = vp._popupFormShowers; + + if _popupFormShowers == nil then + _popupFormShowers = {}; + setmetatable(_popupFormShowers, {__mode="k"}); -- popupFormShowers possui chaves weak-reference + vp._popupFormShowers = _popupFormShowers; + end; + + local popupShower = _popupFormShowers[form]; + + if popupShower == nil then + popupShower = Objs.objectFromHandle(_obj_newObject('TSC3ViewportFormShower')); + Objs.registerHandle(popupShower.handle, popupShower); + _popupFormShowers[form] = popupShower; + + _obj_invoke(popupShower.handle, "SetFormHandle", form.handle); + end; + + local closeListenerId = rawget(popupShower, "__closeListenerID"); + + if closeListenerId ~= nil then + popupShower:removeEventListener(closeListenerId); + rawset(popupShower, "__closeListenerID", nil); + end; + + if type(options.onClose) == "function" then + closeListenerId = popupShower:addEventListener("OnPopupClose", options.onClose); + rawset(popupShower, "__closeListenerID", closeListenerId); + end; + + _obj_setProp(popupShower.handle, "PopupPlacement", options.placement); + return _obj_invoke(popupShower.handle, "Show", vp.handle); + end, + + closeForm = function(vp, form) + local _popupFormShowers = vp._popupFormShowers; + + if type(form) == "table" and _popupFormShowers ~= nil then + local v = _popupFormShowers[form]; + + if v ~= nil then + _popupFormShowers[form] = nil; + return _obj_invoke(v.handle, "Close"); + end; + else + return false; + end; + end + }; + +local __viewportEvents = {onChange = "", + onMouseDown = "event", + onMouseUp = "event", + onMouseMove = "event", + onMouseWheel = "event", + onMouseDblClick = "event", + onFallbackMouseWheel = "event", + onGestureBeginZoom = "x, y", + onGestureZoom = "x, y, delta", + onGestureEndZoom = "x, y", + onGestureBeginRotation = "x, y", + onGestureRotation = "x, y, angle", + onGestureEndRotation = "x, y", + onGestureBeginPan = "x, y", + onGesturePan = "x, y", + onGestureEndPan = "x, y", + onGestureLongTap = "x, y"; + onKeyDown = "event", + onKeyUp = "event", + onBeforeDrawBkgLayer="", + onBeforeDrawGridLayer="", + onBeforeDrawObjsLayer="", + onBeforeDrawTokensLayer="", + onAfterDrawLayers="", + onStartDrop="drop, x, y, drag"}; + +local __viewportRenderMethods = { + prepareFill = _scene3_gfx_prepareFill, + fillRect = _scene3_gfx_fillRect, + fillEllipse = _scene3_gfx_fillEllipse, + fillPolygon = _scene3_gfx_fillPolygon, + fillACell = function(vp, i, j, opacity) _scene3_gfx_fillACell(vp.handle, i, j, opacity); end, + prepareDraw = _scene3_gfx_prepareDraw, + drawRect = _scene3_gfx_drawRect, + drawEllipse = _scene3_gfx_drawEllipse, + drawLine = _scene3_gfx_drawLine, + prepareFont = _scene3_gfx_prepareFont, + textSize = _scene3_gfx_textSize, + fillText = _scene3_gfx_fillText, + fillTextFit = _scene3_gfx_fillTextFit, + pushRenderState = _scene3_gfx_pushState, + popRenderState = _scene3_gfx_popState, + pushRotationTransform = _scene3_gfx_pushRotationTransform, + pushWorldToScreenTransform = function(vp) _scene3_gfx_pushWorldToScreenTransform(vp.handle) end, + popTransform = _scene3_gfx_popTransform + }; + +local function initWrappedViewportFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__viewportProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__viewportMethods) do + rawset(wObj, k, v); + end; + + for k, v in pairs(__viewportRenderMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __viewportEvents; + + return wObj; +end; + + +--- [[ Wrapper Object GRIDLayer ]] + +local __gridLayerProps = {gridType = {tipo = "enum", readProp = "GridType", writeProp="GridType", values={"square", "vertHex", "horzHex"}}, + offsetX = {tipo = "double", readProp = "OffsetX", writeProp = "OffsetX"}, + offsetY = {tipo = "double", readProp = "OffsetY", writeProp = "OffsetY"}, + cellSize = {tipo = "double", readProp = "CellSize", writeProp = "CellSize"}, + gridColor = {tipo = "color", readProp = "GridColor", writeProp = "GridColor"}, + grickThickness = {tipo = "double", readProp = "GridThickness", writeProp = "GridThickness"}, + drawGrid = {tipo = "bool", readProp = "DrawGrid", writeProp = "DrawGrid"}, + rowCount = {tipo = "int", readProp = "RowCount"}, + colCount = {tipo = "int", readProp = "ColumnCount"}, + squareDiagonals = {tipo="enum", readProp = "SquareDiagonals", writeProp="SquareDiagonals", values={"simplified", "manhattan", "alternated", "euclidean"}}, + scene = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "SceneObjectID")); end;}}; + +local __gridLayerMethods = {cellToWorld = + function(grid, i, j) + return _obj_invokeEx(grid.handle, "GetCellCenter", i, j); + end, + + worldToCell = + function (grid, worldX, worldY) + return _obj_invokeEx(grid.handle, "GetGridCellAtPos", worldX, worldY); + end, + + shortestPath = function (grid, srcI, srcJ, destI, destJ, options) + if (options ~= nil) and type(options) ~= "table" then + options = nil; + end; + + return _obj_invokeEx(grid.handle, "ShortestPath", srcI, srcJ, destI, destJ, options); + end}; + +local __gridLayerEvents = {onChange = ""}; + +local function initWrappedGridLayerFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__gridLayerProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__gridLayerMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __gridLayerEvents; + + return wObj; +end; + +--- [[ Wrapper Object GraphicItemList ]] + +local __GIL_Selection = "_xx_selection"; + +local __GILProps = {count = {tipo = "int", readProp = "Count"}, + selection = {tipo="table", getter="getSelection"}}; + +local __GILMethods = { get = function(t, idx) + local objID = _obj_invoke(t.handle, "GetItemObjectID", idx - 1); + local o = SceneWrappers.objectFromID(objID); + + if o == nil then + error("Invalid Scene GraphicItem Index"); + else + return o; + end; + end, + + enumInRect = function(t, rect, layer) + local retObjs = _obj_invokeEx(t.handle, "EnumInRect", rect, layer); + + for i = 1, #retObjs, 1 do + retObjs[i] = SceneWrappers.objectFromID(retObjs[i]); + end; + + return retObjs; + end, + + enumAtPoint = function(t, worldX, worldY, layer) + local retObjs = _obj_invokeEx(t.handle, "EnumInPoint", worldX, worldY, layer); + + for i = 1, #retObjs, 1 do + retObjs[i] = SceneWrappers.objectFromID(retObjs[i]); + end; + + return retObjs; + end, + + itemAtPoint = function(t, worldX, worldY, layer) + local retObjs = t:enumAtPoint(worldX, worldY, layer); + + if #retObjs > 0 then + return retObjs[#retObjs]; + else + return nil; + end; + end, + + getSelection = function(t) + local ss; + + ss = rawget(t, __GIL_Selection); + + if ss ~= nil then + return ss; + end; + + ss = _obj_invokeEx(t.handle, "EnumSelection"); + + for i = 1, #ss, 1 do + ss[i] = SceneWrappers.objectFromID(ss[i]); + end; + + rawset(t, __GIL_Selection, ss); + return ss; + end, + + clearSelection = function(t) + local ss = t.selection; + + for k, v in pairs(ss) do + v.selected = false; + end; + end, + + addToken = function(t, layer) + return SceneWrappers.objectFromID(_obj_invokeEx(t.handle, "AddToken", layer)); + end; + + addUserDrawing = function(t, layer) + return SceneWrappers.objectFromID(_obj_invokeEx(t.handle, "AddUserDrawing", layer)); + end; + }; + +local __GILEvents = {onChange = "", + onItemAdded="item", + onItemRemoved="item", + onItemSelected="item", + onItemDeselected="item", + onItemLayerChange="item"}; +local __GILMetatable = nil; + +local function initialize_GILMetatable(mtbase) + __GILMetatable = {}; + local oldIndexMT = mtbase.__index; + local oldNewIndexMT = mtbase.__newindex; + + for k, v in pairs(mtbase) do + __GILMetatable[k] = v; + end + + __GILMetatable.__len = function(t) + return _obj_getProp(t.handle, "Count"); + end; + + __GILMetatable.__index = function(t, k) + if type(k) == "number" then + local objID = _obj_invoke(t.handle, "GetItemObjectID", k - 1); + local o = SceneWrappers.objectFromID(objID); + + if o == nil then + error("Invalid Scene GraphicItem Index"); + else + return o; + end; + elseif oldIndexMT ~= nil then + return oldIndexMT(t, k); + else + return rawget(t, k); + end; + end; + + __GILMetatable.__newindex = function(t, k, v) + if type(k) == "number" then + error("Scene Graphic Item Index: Read-Only property"); + elseif oldNewIndexMT ~= nil then + return oldNewIndexMT(t, k, v); + else + rawset(t, k, v); + end; + end; +end; + +local function initWrappedGraphicItemListFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + if __GILMetatable == nil then + initialize_GILMetatable(getmetatable(wObj)); + end; + + setmetatable(wObj, __GILMetatable); + + for k, v in pairs(__GILProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__GILMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __GILEvents; + + -- Resetar o cache do selection + wObj:listen("OnItemSelected", function() rawset(wObj, __GIL_Selection, nil); end); + wObj:listen("OnItemDeselected", function() rawset(wObj, __GIL_Selection, nil); end); + return wObj; +end; + +--- [[ Wrapper Object GraphicItem ]] + +local __graphicItemProps = {width = {tipo = "double", readProp = "Width", writeProp="Width"}, + height = {tipo = "double", readProp = "Height", writeProp = "Height"}, + x = {tipo = "double", readProp = "X", writeProp = "X"}, + y = {tipo = "double", readProp = "Y", writeProp = "Y"}, + z = {tipo = "double", readProp = "Z", writeProp = "Z"}, + rotation = {tipo = "double", readProp = "Rotation", writeProp = "Rotation"}, + visible = {tipo = "bool", readProp = "Visible", writeProp = "Visible"}, + snapToGrid = {tipo = "bool", readProp = "SnapToGrid", writeProp="SnapToGrid"}, + locked = {tipo = "bool", readProp = "Locked", writeProp = "Locked"}, + selected = {tipo = "bool", readProp = "Selected", writeProp = "Selected"}, + isHover = {tipo = "bool", readProp = "IsHover", writeProp = "IsHover"}, + layer = {tipo = "enum", readProp = "Layer", writeProp = "Layer", values={"background", "objects", "token"}}, + isMine = {tipo = "bool", readProp = "IsMine"}, + canBeRendered = {tipo = "bool", readProp = "CanBeRendered"}, + ownerUserID = {tipo = "string", readProp = "OwnerUserID", writeProp="OwnerUserID"}, + canvas = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "CanvasObjectID")); end;}, + scene = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "SceneObjectID")); end;}}; + +local __graphicItemMethods = {getCenter = + function(t, snapToGrid) + return _obj_invokeEx(t.handle, "GetCenter", snapToGrid); + end, + + setCenter = + function (t, worldX, worldY, snapToGrid) + return _obj_invokeEx(t.handle, "SetCenter", worldX, worldY, snapToGrid); + end, + + getBounds = + function(t) + return _scene3_GraItem_getBounds(t.objectID); + end, + + setBounds = function(t, left, top, right, bottom, rotation) + return _scene3_GraItem_setBounds(t.objectID, left, top, right, bottom, rotation); + end, + + getCellsOccupied = function (t) + return _obj_invokeEx(t.handle, "GetCellsOccupied"); + end, + + compareZOrder = function(t, otherItem) + return _obj_invokeEx(t.handle, "CompareZOrder", otherItem.handle); + end, + + delete = function(t) _obj_invoke(t.handle, "Delete"); end, + + doSnapToGrid = function(t) _obj_invoke(t.handle, "DoSnapToGrid"); end; + }; + +local __graphicItemEvents = {onChange = "", + onBeforeDraw = "", + onAfterDraw = "", + onBoundsChange = "item"}; + +local function initWrappedGraphicItemFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__graphicItemProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__graphicItemMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __graphicItemEvents; + + return wObj; +end; + + +--- [[ Wrapper Object Token ]] + +local __tokenItemProps = {facingMode = {tipo = "enum", readProp = "FacingMode", writeProp="FacingMode", values={"rotate", "arrow"}}, + ownerCharacter = {tipo = "int", readProp = "OwnerCharacter", writeProp="OwnerCharacter"}, + friendOrFoe = {tipo = "enum", readProp = "FriendOrFoe", writeProp="FriendOrFoe", values={"unknown", "friend", "neutral", "foe"}}, + name = {tipo="string", readProp="Name", writeProp="Name"}, + visionIntenseLightRange = {tipo = "double", readProp = "VisIntenseLightRange", writeProp="VisIntenseLightRange"}, + visionWeakLightRange = {tipo = "double", readProp = "VisWeakLightRange", writeProp="VisWeakLightRange"}, + visionDarknessRange = {tipo = "double", readProp = "VisDarkRange", writeProp="VisDarkRange"}, + visionAngle = {tipo = "double", readProp = "VisionAngle", writeProp="VisionAngle"}, + visionHaveVision = {tipo = "bool", readProp = "VisHaveVision", writeProp="VisHaveVision"}, + lightIntenseRange = {tipo = "double", readProp = "LightIntenseRange", writeProp="LightIntenseRange"}, + lightWeakRange = {tipo = "double", readProp = "LightWeakRange", writeProp="LightWeakRange"}, + lightAngle = {tipo = "double", readProp = "LightAngle", writeProp="LightAngle"}, + image = {tipo = "table", getter = function(obj) return SceneWrappers.objectFromID(_obj_getProp(obj.handle, "ImageOpObjectID")); end;} + }; + +for i = 1, 3, 1 do + __tokenItemProps["barValue" .. i] = {tipo="string", + getter = function(obj) return _obj_invoke(obj.handle, "GetBarValue", i - 1); end, + setter = function(obj, value) _obj_invoke(obj.handle, "SetBarValue", i - 1, value); end}; + + __tokenItemProps["barMax" .. i] = {tipo="string", + getter = function(obj) return _obj_invoke(obj.handle, "GetBarMax", i - 1); end, + setter = function(obj, value) _obj_invoke(obj.handle, "SetBarMax", i - 1, value); end}; + + __tokenItemProps["barColor" .. i] = {tipo="color", + getter = function(obj) return _obj_invoke(obj.handle, "GetBarColor", i - 1); end, + setter = function(obj, value) _obj_invoke(obj.handle, "SetBarColor", i - 1, value); end}; +end; + +local __tokenMethods = {clearMemoryAreas = function(t) _obj_invoke(t.handle, "ClearMemoryAreas"); end + }; +local __tokenEvents = {}; + +for k, v in pairs(__graphicItemEvents) do + __tokenEvents[k] = v; +end; + + __tokenEvents.onChange = ""; + +local function initWrappedTokenFromHandle(handle) + local wObj = initWrappedGraphicItemFromHandle(handle); + + for k, v in pairs(__tokenItemProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__tokenMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __tokenEvents; + + return wObj; +end; + +--- [[ Wrapper UserDrawing ]] + +local __userDrawingItemProps = {}; + +local __userDrawingMethods = { + markAsMyDrawing = + function(t) + local scene = t.scene; + + if scene ~= nil then + if scene.isGM then + t.ownerUserID = ''; + else + t.ownerUserID = scene.currentUserID; + end; + end; + end + }; +local __userDrawingEvents = {}; + +for k, v in pairs(__graphicItemEvents) do + __userDrawingEvents[k] = v; +end; + +local function initWrappedUerDrawingFromHandle(handle) + local wObj = initWrappedGraphicItemFromHandle(handle); + + for k, v in pairs(__userDrawingItemProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__userDrawingMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __userDrawingEvents; + return wObj; +end; + +--- [[ Wrapper Object Persisted Canvas ]] + +local __PerCanvasProps = {opCount = {tipo = "int", readProp = "OpCount"}}; + + +local __PerCanvasMethods = {getOp = function(t, idx) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "GetOpObjectID", idx)); + end, + + addBitmap = function(t) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "AddBitmapOpObjectID")); + end, + + addPath = function(t) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "AddPathOpObjectID")); + end, + + addText = function(t) + return SceneWrappers.objectFromID(_obj_invoke(t.handle, "AddTextOpObjectID")); + end, + + findByName = function(t, name) + return SceneWrappers.objectFromID(_obj_invokeEx(t.handle, "FindByName", tostring(name))); + end, + + clear = function(t) _obj_invoke(t.handle, "Clear"); end; + }; + +local __PerCanvasEvents = {onChange = ""}; + +local function initWrappedPerCanvasFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__PerCanvasProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__PerCanvasMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __PerCanvasEvents; + + return wObj; +end; + + +--- [[ Wrapper Object DrawingOp ]] + +local __DOPBaseProps = {x = {tipo = "double", readProp = "X", writeProp="X"}, + y = {tipo = "double", readProp = "Y", writeProp="Y"}, + z = {tipo = "double", readProp = "Z", writeProp="Z"}, + width = {tipo = "double", readProp = "Width", writeProp="Width"}, + height = {tipo = "double", readProp = "Height", writeProp="Height"}, + rotMode = {tipo = "enum", readProp="RotMode", writeProp = "RotMode", values={"default", "ignoreCanvasRot"}}, + name = {tipo = "string", readProp = "Name", writeProp="Name"}, + opacity = {tipo = "double", readProp = "Opacity", writeProp="Opacity"}, + visibility = {tipo = "enum", readProp = "Visibility", writeProp="Visibility", values={"everyone", "gmOnly"}}, + rotation = {tipo="double", readProp="Rotation", writeProp="Rotation"}, + rotCenterX = {tipo="double", readProp="RotCenterX", writeProp="RotCenterX"}, + rotCenterY = {tipo="double", readProp="RotCenterY", writeProp="RotCenterY"}, + drawingTrigger = {tipo="set", readProp="DrawingTrigger", writeProp="DrawingTrigger", values={"hover", "selected"}}, + outOfOrderMode = {tipo="enum", readProp="OutOfOrderMode", writeProp="OutOfOrderMode", values={"noOutOfOrder", "afterFogOfWarLayer", "beforeOwnerLayer", "afterOwnerLayer"}}, + xMetric = {tipo="enum", readProp="XMetric", writeProp="XMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + yMetric = {tipo="enum", readProp="YMetric", writeProp="YMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + widthMetric = {tipo="enum", readProp="WidthMetric", writeProp="WidthMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + heightMetric = {tipo="enum", readProp="HeightMetric", writeProp="HeightMetric", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}}, + xOrigin = {tipo = "double", readProp = "XOrigin", writeProp="XOrigin"}, + yOrigin = {tipo = "double", readProp = "YOrigin", writeProp="YOrigin"} + }; + +local __DOPBaseMethods = {delete = function(t) + _obj_invoke(t.handle, "Delete"); + end + }; + +local __DOPBaseEvents = {onChange = ""}; + +local function initWrappedDrawingOpBaseFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__DOPBaseProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPBaseMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPBaseEvents; + + return wObj; +end; + + +--- [[ Wrapper Object DrawingOpBitmap ]] + +local __DOPBitmapProps = {url = {tipo = "string", readProp = "URL", writeProp="URL"}, + flipHorz = {tipo = "bool", readProp="FlipHorz", writeProp = "FlipHorz"}, + flipVert = {tipo = "bool", readProp="FlipVert", writeProp = "FlipVert"}, + grayscale = {tipo = "bool", readProp="Grayscale", writeProp = "Grayscale"}, + colorBlend = {tipo = "color", readProp="ColorBlend", writeProp = "ColorBlend"}, + colorMask = {tipo = "color", readProp="ColorMask", writeProp = "ColorMask"}, + filterEx = {tipo = "enum", readProp="FilterEx", writeProp = "FilterEx", + values={"none", "glow", "innerGlow", "blur", "sepia"}}, + filterExColor = {tipo = "color", readProp="FilterExColor", writeProp = "FilterExColor"}, + frame = {tipo = "enum", readProp="Frame", writeProp = "Frame", + values={"none", "boton"}}, + sourceRect = {tipo="table", readProp="SourceRect", writeProp="SourceRect"}}; + +local __DOPBitmapMethods = {}; +local __DOPBitmapEvents = {onChange = ""}; + +local function initWrappedDrawingOpBitmapFromHandle(handle) + local wObj = initWrappedDrawingOpBaseFromHandle(handle); + + for k, v in pairs(__DOPBitmapProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPBitmapMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPBitmapEvents; + + return wObj; +end; + +--- [[ Wrapper Object DrawingOpPath ]] + +local __DOPPathProps = {pathData = {tipo = "string", readProp = "PathData", writeProp="PathData"}, + data = {tipo = "string", readProp = "PathData", writeProp="PathData"}, + path = {tipo = "string", readProp = "PathData", writeProp="PathData"}, + color = {tipo="color", readProp="FillColor", writeProp="FillColor"}, + strokeColor = {tipo="color", readProp="StrokeColor", writeProp="StrokeColor"}, + strokeSize = {tipo="double", readProp="StrokeThickness", writeProp="StrokeThickness"}, + strokeSizeMetric = {tipo="enum", values={"screenMetric", "worldMetric", "canvasMetric", "cellMetric"}, readProp="StrokeThicknessMetric", writeProp="StrokeThicknessMetric"}, + strokeCap = {tipo="enum", readProp="StrokeCap", writeProp="StrokeCap", values={"flat", "round"}}, + strokeJoin = {tipo="enum", readProp="StrokeJoin", writeProp="StrokeJoin", values={"miter", "round", "bevel"}}, + strokeDash = {tipo="enum", readProp="StrokeDash", writeProp="StrokeDash", values={"solid", "dash", "dot", "dashDot", "dashDotDot"}} + } + +local __DOPPathMethods = {}; +local __DOPPathEvents = {onChange = ""}; + +local function initWrappedDrawingOpPathFromHandle(handle) + local wObj = initWrappedDrawingOpBaseFromHandle(handle); + + for k, v in pairs(__DOPPathProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPPathMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPPathEvents; + + return wObj; +end; + + + +--- [[ Wrapper Object DrawingOpText ]] + +local __DOPTextProps = {text = {tipo = "string", readProp = "Text", writeProp="Text"}, + color = {tipo = "color", readProp = "Color", writeProp="Color"}, + aspect = {tipo = "double", readProp = "Aspect"}, + fontStyle = {tipo="set", readProp="FontStyle", writeProp="FontStyle"}, + horzTextAlign = {tipo="enum", readProp="TextAlign", writeProp="TextAlign", values={"leading", "center", "trailing"}}, + vertTextAlign = {tipo="enum", readProp="VertTextAlign", writeProp="VertTextAlign", values={"leading", "center", "trailing"}} + } + +local __DOPTextMethods = {}; +local __DOPTextEvents = {}; + +local function initWrappedDrawingOpTextFromHandle(handle) + local wObj = initWrappedDrawingOpBaseFromHandle(handle); + + for k, v in pairs(__DOPTextProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__DOPTextMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __DOPTextEvents; + + return wObj; +end; + +--- [[ Wrapper Object FogOfWar FOW ]] + +local __fowProps = {enabled = {tipo="bool", readProp="Enabled", writeProp="Enabled"}, + ambientLight = {tipo="enum", readProp="AmbientLight", writeProp="AmbientLight", values={"intense", "weak", "none"}}, + sharingMode = {tipo="enum", readProp="SharingMode", writeProp="SharingMode", values={"individual", "group"}}}; + + +local __fowMethods = {setArea = function(t, polygon, areaType) + _obj_invokeEx(t.handle, "SetArea", polygon, areaType); + end, + + resetAreas = function(t) _obj_invoke(t.handle, "ResetAreas"); end, + + addOpaqueArea = function(t, polygon) + _obj_invokeEx(t.handle, "AddOpaqueArea", polygon); + end, + + removeOpaqueArea = function(t, polygon) + _obj_invokeEx(t.handle, "RemoveOpaqueArea", polygon); + end, + + resetOpaqueAreas = function(t) _obj_invoke(t.handle, "ResetOpaqueAreas"); end, + + testCircleMovementCollisionVsOpaqueAreas = function(t, centerX, centerY, r, offsetX, offsetY) + return _obj_invokeEx(t.handle, "TestCircleMovementCollisionVsOpaqueAreas", centerX, centerY, r, offsetX, offsetY); + end + + }; + +local __fowEvents = {onChange = ""}; + +local function initWrappedFogOfWarFromHandle(handle) + local wObj = initWrappedObjectFromHandle(handle); + + for k, v in pairs(__fowProps) do + wObj.props[k] = v; + end; + + for k, v in pairs(__fowMethods) do + rawset(wObj, k, v); + end; + + wObj.eves = __fowEvents; + + return wObj; +end; + +------------------------------------------ + + +local __wrappersInitializers = { + token = initWrappedTokenFromHandle, + userDrawing = initWrappedUerDrawingFromHandle, + graphicItem = initWrappedGraphicItemFromHandle, + scene = initWrappedSceneFromHandle, + pluginAttachment = initWrappedObjectFromHandle, + viewport = initWrappedViewportFromHandle, + persistedCanvas = initWrappedPerCanvasFromHandle, + gridLayer = initWrappedGridLayerFromHandle, + graphicItemList = initWrappedGraphicItemListFromHandle, + drawingOpBase = initWrappedDrawingOpBaseFromHandle, + opBitmap = initWrappedDrawingOpBitmapFromHandle, + opPath = initWrappedDrawingOpPathFromHandle, + opText = initWrappedDrawingOpTextFromHandle, + fogOfWar = initWrappedFogOfWarFromHandle, + } + +function SceneWrappers.objectFromID(objectID) + if (objectID == nil) or (objectID == 0) then + return nil; + end; + + local scObj = _localStrongRefSceneObjects[objectID]; + + if scObj ~= nil then + return scObj; + end; + + local objWrapperHandle; + objWrapperHandle = _scene3_GetOrCreateObjectWrapperForObjectID(objectID); + + if objWrapperHandle == nil then + return nil; + end; + + scObj = objs.tryFindFromHandle(objWrapperHandle); + + if scObj ~= nil then + if _scene3_IsObjectIDAlive(objectID) then + _localStrongRefSceneObjects[objectID] = scObj; + end; + + return scObj; + end; + + local oType = _scene3_GetWrapperType(objWrapperHandle); + local initer = __wrappersInitializers[oType]; + + if initer == nil then + -- Olhar por um wrapper na herança. + + for k, v in pairs(__wrappersInitializers) do + if _scene3_IsWrapperOfType(objWrapperHandle, k) then + initer = v; + break; + end; + end; + + if initer == nil then + initer = initWrappedObjectFromHandle; + end; + end; + + scObj = initer(objWrapperHandle); + objs.registerHandle(objWrapperHandle, scObj); + + if _scene3_IsObjectIDAlive(objectID) then + _localStrongRefSceneObjects[objectID] = scObj; + end; + + return scObj; +end; + +function _INTERNAL_EVE_OnWrappedSceneObjectWasDestroyed(objectID) + _localStrongRefSceneObjects[objectID] = nil; -- Permitir o Garbage Collector coletar este objeto +end; + +return SceneWrappers; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sdk3.lang b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sdk3.lang new file mode 100644 index 00000000..e3fdc8c5 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/sdk3.lang @@ -0,0 +1,11 @@ +[pt] +sdk3.err.ndb.functionAssign=Tentativa de armazenar uma função Lua na propriedade "%s", porém não é possível salvar funções em NodeDatabases +sdk3.err.ndb.func.exportToXML.invalidPar=Não foi passado um objeto Nodo válido no parâmetro da função NDB.exportXML +sdk3.err.ndb.func.importXML.invalidPar=Não foi passado um objeto Nodo válido no primeiro parâmetro da função NDB.importXML +sdk3.err.ndb.func.copy.invalidPar2=Não foi passado um objeto Nodo válido no segundo parâmetro da função NDB.copy + +[en] +sdk3.err.ndb.functionAssign=Attempting to store a Lua function in the property "%s", but it is not possible to store functions in NodeDatabases +sdk3.err.ndb.func.exportToXML.invalidPar=A valid Node object was not passed in the NDB.exportXML's first parameter +sdk3.err.ndb.func.importXML.invalidPar=A valid Node object was not passed in the NDB.importXML's first parameter +sdk3.err.ndb.func.copy.invalidPar2=A valid Node object was not passed in the NDB.copy's second parameter \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/serpent.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/serpent.dlua new file mode 100644 index 00000000..62f268a6 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/serpent.dlua @@ -0,0 +1,172 @@ +local function firecastQuotedStr(s) + local buildingStr = ""; + + for p, c in utf8.codes(s) do + if c == 22 then + buildingStr = buildingStr .. '\"' + elseif c == 10 then + buildingStr = buildingStr .. "\n" + elseif c == 13 then + buildingStr = buildingStr .. "\013" + else + buildingStr = buildingStr .. utf8.char(c); + end; + end; + + return '"' .. buildingStr .. '"'; +end; + +local n, v = "serpent", "0.303" -- (C) 2012-18 Paul Kulchenko; MIT License +local c, d = "Paul Kulchenko", "Lua serializer and pretty printer" +local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'} +local badtype = {thread = true, userdata = true, cdata = true} +local getmetatable = debug and debug.getmetatable or getmetatable + +-- local pairs = function(t) return next, t end -- avoid using __pairs in Lua 5.2+ -- it should use pairs because of nodeDatabase + +local keyword, globals, G = {}, {}, (_G or _ENV) +for _,k in ipairs({'and', 'break', 'do', 'else', 'elseif', 'end', 'false', + 'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', + 'return', 'then', 'true', 'until', 'while'}) do keyword[k] = true end +for k,v in pairs(G) do globals[v] = k end -- build func to name mapping +for _,g in ipairs({'coroutine', 'debug', 'io', 'math', 'string', 'table', 'os'}) do + for k,v in pairs(type(G[g]) == 'table' and G[g] or {}) do globals[v] = g..'.'..k end end + +local function s(t, opts) + local name, indent, fatal, maxnum = opts.name, opts.indent, opts.fatal, opts.maxnum + local sparse, custom, huge = opts.sparse, opts.custom, not opts.nohuge + local space, maxl = (opts.compact and '' or ' '), (opts.maxlevel or math.huge) + local maxlen, metatostring = tonumber(opts.maxlength), opts.metatostring + local iname, comm = '_'..(name or ''), opts.comment and (tonumber(opts.comment) or math.huge) + local numformat = opts.numformat or "%.17g" + local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0 + local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)", + -- tostring(val) is needed because __tostring may return a non-string value + function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return tostring(syms[s]) end)) end + local function safestr(s) return type(s) == "number" and (huge and snum[tostring(s)] or numformat:format(s)) + or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026 + or firecastQuotedStr(s):gsub("\010","n"):gsub("\026","\\026") end + -- handle radix changes in some locales + if opts.fixradix and (".1f"):format(1.2) ~= "1.2" then + local origsafestr = safestr + safestr = function(s) return type(s) == "number" + and (nohuge and snum[tostring(s)] or numformat:format(s):gsub(",",".")) or origsafestr(s) + end + end + local function comment(s,l) return comm and (l or 0) < comm and ' --[['..select(2, pcall(tostring, s))..']]' or '' end + local function globerr(s,l) return globals[s] and globals[s]..comment(s,l) or not fatal + and safestr(select(2, pcall(tostring, s))) or error("Can't serialize "..tostring(s)) end + local function safename(path, name) -- generates foo.bar, foo[3], or foo['b a r'] + local n = name == nil and '' or name + local plain = type(n) == "string" and n:match("^[%l%u_][%w_]*$") and not keyword[n] + local safe = plain and n or '['..safestr(n)..']' + return (path or '')..(plain and path and '.' or '')..safe, safe end + local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding + local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'} + local function padnum(d) return ("%0"..tostring(maxn).."d"):format(tonumber(d)) end + table.sort(k, function(a,b) + -- sort numeric keys first: k[key] is not nil for numerical keys + return (k[a] ~= nil and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum)) + < (k[b] ~= nil and 0 or to[type(b)] or 'z')..(tostring(b):gsub("%d+",padnum)) end) end + local function val2str(t, name, indent, insref, path, plainindex, level) + local ttype, level, mt = type(t), (level or 0), getmetatable(t) + local spath, sname = safename(path, name) + local tag = plainindex and + ((type(name) == "number") and '' or name..space..'='..space) or + (name ~= nil and sname..space..'='..space or '') + if seen[t] then -- already seen this element + sref[#sref+1] = spath..space..'='..space..seen[t] + return tag..'nil'..comment('ref', level) + end + -- protect from those cases where __tostring may fail + if type(mt) == 'table' and metatostring ~= false then + local to, tr = pcall(function() return mt.__tostring(t) end) + local so, sr = pcall(function() return mt.__serialize(t) end) + if (to or so) then -- knows how to serialize itself + seen[t] = insref or spath + t = so and sr or tr + ttype = type(t) + end -- new value falls through to be serialized + end + if ttype == "table" then + if level >= maxl then return tag..'{}'..comment('maxlvl', level) end + seen[t] = insref or spath + if next(t) == nil then return tag..'{}'..comment(t, level) end -- table empty + if maxlen and maxlen < 0 then return tag..'{}'..comment('maxlen', level) end + local maxn, o, out = math.min(#t, maxnum or #t), {}, {} + for key = 1, maxn do o[key] = key end + if not maxnum or #o < maxnum then + local n = #o -- n = n + 1; o[n] is much faster than o[#o+1] on large tables + for key in pairs(t) do + if o[key] ~= key then n = n + 1; o[n] = key end + end + end + if maxnum and #o > maxnum then o[maxnum+1] = nil end + if opts.sortkeys and #o > maxn then alphanumsort(o, t, opts.sortkeys) end + local sparse = sparse and #o > maxn -- disable sparsness if only numeric keys (shorter output) + for n, key in ipairs(o) do + local value, ktype, plainindex = t[key], type(key), n <= maxn and not sparse + if opts.valignore and opts.valignore[value] -- skip ignored values; do nothing + or opts.keyallow and not opts.keyallow[key] + or opts.keyignore and opts.keyignore[key] + or opts.valtypeignore and opts.valtypeignore[type(value)] -- skipping ignored value types + or sparse and value == nil then -- skipping nils; do nothing + elseif ktype == 'table' or ktype == 'function' or badtype[ktype] then + if not seen[key] and not globals[key] then + sref[#sref+1] = 'placeholder' + local sname = safename(iname, gensym(key)) -- iname is table for local variables + sref[#sref] = val2str(key,sname,indent,sname,iname,true) + end + sref[#sref+1] = 'placeholder' + local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']' + sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path)) + else + out[#out+1] = val2str(value,key,indent,nil,seen[t],plainindex,level+1) + if maxlen then + maxlen = maxlen - #out[#out] + if maxlen < 0 then break end + end + end + end + local prefix = string.rep(indent or '', level) + local head = indent and '{\n'..prefix..indent or '{' + local body = table.concat(out, ','..(indent and '\n'..prefix..indent or space)) + local tail = indent and "\n"..prefix..'}' or '}' + return (custom and custom(tag,head,body,tail,level) or tag..head..body..tail)..comment(t, level) + elseif badtype[ttype] then + seen[t] = insref or spath + return tag..globerr(t, level) + elseif ttype == 'function' then + seen[t] = insref or spath + if opts.nocode then return tag.."function() --[[..skipped..]] end"..comment(t, level) end + local ok, res = pcall(string.dump, t) + local func = ok and "((loadstring or load)("..safestr(res)..",'@serialized'))"..comment(t, level) + return tag..(func or globerr(t, level)) + else return tag..safestr(t) end -- handle all other types + end + local sepr = indent and "\n" or ";"..space + local body = val2str(t, name, indent) -- this call also populates sref + local tail = #sref>1 and table.concat(sref, sepr)..sepr or '' + local warn = opts.comment and #sref>1 and space.."--[[incomplete output with shared/self-references skipped]]" or '' + return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end" +end + +local function deserialize(data, opts) + local env = (opts and opts.safe == false) and G + or setmetatable({}, { + __index = function(t,k) return t end, + __call = function(t,...) error("cannot call functions") end + }) + local f, res = (loadstring or load)('return '..data, nil, nil, env) + if not f then f, res = (loadstring or load)(data, nil, nil, env) end + if not f then return f, res end + if setfenv then setfenv(f, env) end + return pcall(f) +end + +local function merge(a, b) if b then for k,v in pairs(b) do a[k] = v end end; return a; end +return { _NAME = n, _COPYRIGHT = c, _DESCRIPTION = d, _VERSION = v, serialize = s, + load = deserialize, + dump = function(a, opts) return s(a, merge({name = '_', compact = true, sparse = true}, opts)) end, + line = function(a, opts) return s(a, merge({sortkeys = true, comment = true}, opts)) end, + block = function(a, opts) return s(a, merge({indent = ' ', sortkeys = true, comment = true}, opts)) end } diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxdom.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxdom.dlua new file mode 100644 index 00000000..46b5bc87 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxdom.dlua @@ -0,0 +1,49 @@ +-- Optional parser that creates a flat DOM from parsing +local SLAXML = require 'slaxml.dlua' +function SLAXML:dom(xml,opts) + if not opts then opts={} end + local rich = not opts.simple + local push, pop = table.insert, table.remove + local stack = {} + local doc = { type="document", name="#doc", kids={} } + local current = doc + local builder = SLAXML:parser{ + startElement = function(name,nsURI) + local el = { type="element", name=name, kids={}, el=rich and {} or nil, attr={}, nsURI=nsURI, parent=rich and current or nil } + if current==doc then + if doc.root then error(("Encountered element '%s' when the document already has a root '%s' element"):format(name,doc.root.name)) end + doc.root = el + end + push(current.kids,el) + if current.el then push(current.el,el) end + current = el + push(stack,el) + end, + attribute = function(name,value,nsURI) + if not current or current.type~="element" then error(("Encountered an attribute %s=%s but I wasn't inside an element"):format(name,value)) end + local attr = {type='attribute',name=name,nsURI=nsURI,value=value,parent=rich and current or nil} + if rich then current.attr[name] = value end + push(current.attr,attr) + end, + closeElement = function(name) + if current.name~=name or current.type~="element" then error(("Received a close element notification for '%s' but was inside a '%s' %s"):format(name,current.name,current.type)) end + pop(stack) + current = stack[#stack] + end, + text = function(value) + if current.type~='document' then + if current.type~="element" then error(("Received a text notification '%s' but was inside a %s"):format(value,current.type)) end + push(current.kids,{type='text',name='#text',value=value,parent=rich and current or nil}) + end + end, + comment = function(value) + push(current.kids,{type='comment',name='#comment',value=value,parent=rich and current or nil}) + end, + pi = function(name,value) + push(current.kids,{type='pi',name=name,value=value,parent=rich and current or nil}) + end + } + builder:parse(xml,opts) + return doc +end +return SLAXML \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxml.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxml.dlua new file mode 100644 index 00000000..5929b785 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/slaxml.dlua @@ -0,0 +1,257 @@ +--[=====================================================================[ +v0.7 Copyright © 2013-2014 Gavin Kistner ; MIT Licensed +See http://github.com/Phrogz/SLAXML for details. +--]=====================================================================] +local SLAXML = { + VERSION = "0.7", + _call = { + pi = function(target,content) + --print(string.format("",target,content)) + end, + comment = function(content) + --print(string.format("",content)) + end, + startElement = function(name,nsURI,nsPrefix) + --[[ io.write("<") + if nsPrefix then io.write(nsPrefix,":") end + io.write(name) + if nsURI then io.write(" (ns='",nsURI,"')") end + print(">")]]-- + end, + attribute = function(name,value,nsURI,nsPrefix) + --[[ io.write(' ') + if nsPrefix then io.write(nsPrefix,":") end + io.write(name,'=',string.format('%q',value)) + if nsURI then io.write(" (ns='",nsURI,"')") end + io.write("\n")]]-- + end, + text = function(text) + --print(string.format(" text: %q",text)) + end, + closeElement = function(name,nsURI,nsPrefix) + --print(string.format("",name)) + end, + } +} + +function SLAXML:parser(callbacks) + return { _call=callbacks or self._call, parse=SLAXML.parse } +end + +function SLAXML:parse(xml,options) + if not options then options = { stripWhitespace=false } end + + -- Cache references for maximum speed + local find, sub, gsub, char, push, pop, concat = string.find, string.sub, string.gsub, string.char, table.insert, table.remove, table.concat + local first, last, match1, match2, pos2, nsURI + local unpack = table.unpack + local pos = 1 + local state = "text" + local textStart = 1 + local currentElement={} + local currentAttributes={} + local currentAttributeCt -- manually track length since the table is re-used + local nsStack = {} + local anyElement = false + + local utf8markers = { {0x7FF,192}, {0xFFFF,224}, {0x1FFFFF,240} } + function utf8(decimal) -- convert unicode code point to utf-8 encoded character string + if decimal<128 then return char(decimal) end + local charbytes = {} + for bytes,vals in ipairs(utf8markers) do + if decimal<=vals[1] then + for b=bytes+1,2,-1 do + local mod = decimal%64 + decimal = (decimal-mod)/64 + charbytes[b] = char(128+mod) + end + charbytes[1] = char(vals[2]+decimal) + return concat(charbytes) + end + end + end + local entityMap = { ["lt"]="<", ["gt"]=">", ["amp"]="&", ["quot"]='"', ["apos"]="'" } + local entitySwap = function(orig,n,s) return entityMap[s] or n=="#" and utf8(tonumber('0'..s)) or orig end + local function unescape(str) return gsub( str, '(&(#?)([%d%a]+);)', entitySwap ) end + + local function finishText() + if first>textStart and self._call.text then + local text = sub(xml,textStart,first-1) + if options.stripWhitespace then + text = gsub(text,'^%s+','') + text = gsub(text,'%s+$','') + if #text==0 then text=nil end + end + if text then self._call.text(unescape(text)) end + end + end + + local function findPI() + first, last, match1, match2 = find( xml, '^<%?([:%a_][:%w_.-]*) ?(.-)%?>', pos ) + if first then + finishText() + if self._call.pi then self._call.pi(match1,match2) end + pos = last+1 + textStart = pos + return true + end + end + + local function findComment() + first, last, match1 = find( xml, '^', pos ) + if first then + finishText() + if self._call.comment then self._call.comment(match1) end + pos = last+1 + textStart = pos + return true + end + end + + local function nsForPrefix(prefix) + if prefix=='xml' then return 'http://www.w3.org/XML/1998/namespace' end -- http://www.w3.org/TR/xml-names/#ns-decl + for i=#nsStack,1,-1 do if nsStack[i][prefix] then return nsStack[i][prefix] end end + error(("Cannot find namespace for prefix %s"):format(prefix)) + end + + local function startElement() + anyElement = true + first, last, match1 = find( xml, '^<([%a_][%w_.-]*)', pos ) + if first then + currentElement[2] = nil -- reset the nsURI, since this table is re-used + currentElement[3] = nil -- reset the nsPrefix, since this table is re-used + finishText() + pos = last+1 + first,last,match2 = find(xml, '^:([%a_][%w_.-]*)', pos ) + if first then + currentElement[1] = match2 + currentElement[3] = match1 -- Save the prefix for later resolution + match1 = match2 + pos = last+1 + else + currentElement[1] = match1 + for i=#nsStack,1,-1 do if nsStack[i]['!'] then currentElement[2] = nsStack[i]['!']; break end end + end + currentAttributeCt = 0 + push(nsStack,{}) + return true + end + end + + local function findAttribute() + first, last, match1 = find( xml, '^%s+([:%a_][:%w_.-]*)%s*=%s*', pos ) + if first then + pos2 = last+1 + first, last, match2 = find( xml, '^"([^<"]*)"', pos2 ) -- FIXME: disallow non-entity ampersands + if first then + pos = last+1 + match2 = unescape(match2) + else + first, last, match2 = find( xml, "^'([^<']*)'", pos2 ) -- FIXME: disallow non-entity ampersands + if first then + pos = last+1 + match2 = unescape(match2) + end + end + end + if match1 and match2 then + local currentAttribute = {match1,match2} + local prefix,name = string.match(match1,'^([^:]+):([^:]+)$') + if prefix then + if prefix=='xmlns' then + nsStack[#nsStack][name] = match2 + else + currentAttribute[1] = name + currentAttribute[4] = prefix + end + else + if match1=='xmlns' then + nsStack[#nsStack]['!'] = match2 + currentElement[2] = match2 + end + end + currentAttributeCt = currentAttributeCt + 1 + currentAttributes[currentAttributeCt] = currentAttribute + return true + end + end + + local function findCDATA() + first, last, match1 = find( xml, '^', pos ) + if first then + finishText() + if self._call.text then self._call.text(match1) end + pos = last+1 + textStart = pos + return true + end + end + + local function closeElement() + first, last, match1 = find( xml, '^%s*(/?)>', pos ) + if first then + state = "text" + pos = last+1 + textStart = pos + + -- Resolve namespace prefixes AFTER all new/redefined prefixes have been parsed + if currentElement[3] then currentElement[2] = nsForPrefix(currentElement[3]) end + if self._call.startElement then self._call.startElement(unpack(currentElement)) end + if self._call.attribute then + for i=1,currentAttributeCt do + if currentAttributes[i][4] then currentAttributes[i][3] = nsForPrefix(currentAttributes[i][4]) end + self._call.attribute(unpack(currentAttributes[i])) + end + end + + if match1=="/" then + pop(nsStack) + if self._call.closeElement then self._call.closeElement(unpack(currentElement)) end + end + return true + end + end + + local function findElementClose() + first, last, match1, match2 = find( xml, '^', pos ) + if first then + nsURI = nil + for i=#nsStack,1,-1 do if nsStack[i]['!'] then nsURI = nsStack[i]['!']; break end end + else + first, last, match2, match1 = find( xml, '^', pos ) + if first then nsURI = nsForPrefix(match2) end + end + if first then + finishText() + if self._call.closeElement then self._call.closeElement(match1,nsURI) end + pos = last+1 + textStart = pos + pop(nsStack) + return true + end + end + + while pos<#xml do + if state=="text" then + if not (findPI() or findComment() or findCDATA() or findElementClose()) then + if startElement() then + state = "attributes" + else + first, last = find( xml, '^[^<]+', pos ) + pos = (first and last or pos) + 1 + end + end + elseif state=="attributes" then + if not findAttribute() then + if not closeElement() then + error("Was in an element and couldn't find attributes or the close.") + end + end + end + end + + if not anyElement then error("Parsing did not discover any elements") end + if #nsStack > 0 then error("Parsing ended with unclosed elements") end +end + +return SLAXML \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/system.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/system.lua new file mode 100644 index 00000000..5e7bcf15 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/system.lua @@ -0,0 +1,3 @@ +system = require("delayedLoad.dlua").new("systemCore.dlua"); +System = system; +return system; diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/systemCore.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/systemCore.dlua new file mode 100644 index 00000000..622f8288 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/systemCore.dlua @@ -0,0 +1,51 @@ +local system = {}; + +function system.setClipboardText(text) + return _system_setClipboardText(text); +end; + +function system.getClipboardText() + return _system_getClipboardText(); +end; + +function system.readClipboardAsDragNDrop(callback, options) + if (type(callback) ~= 'function') then + return false; + end; + + options = options or {}; + options.x = tonumber(options.x) or 0; + options.y = tonumber(options.y) or 0; + + return _gui_readClipboardAsDragNDrop(options.x, options.y, callback); +end; + +function system.getScreenSize() + return _system_getScreenSize(); +end; + +function system.isMobile() + return _system_isMobile(); +end; + +function system.getTickCount() + return _system_getTickCount(); +end; + +function system.checkAPIVersion(major, minor) + return system.getAPIVersion() >= system.makeAPIVersionNumber(major, minor); +end; + +function system.getAPIVersion() + if _system_getAPIVersion ~= nil then + return _system_getAPIVersion(); + else + return system.makeAPIVersionNumber(87, 0); + end; +end; + +function system.makeAPIVersionNumber(major, minor) + return ((major or 0) << 16) | ((minor or 0) & 0xFFFF); +end; + +return system; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.lua new file mode 100644 index 00000000..f1fe1671 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.lua @@ -0,0 +1 @@ +return require("rrpgUtil.lua"); \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.serializer.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.serializer.dlua new file mode 100644 index 00000000..2c5de095 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/utils.serializer.dlua @@ -0,0 +1,339 @@ +local utils = require("utils.lua"); +local SharedObjects = require("rrpgSharedObjects.lua"); + +local serializer = {}; + +local TYPE_STRING = 1; +local TYPE_NUMBER = 2; +local TYPE_BOOLEAN = 3; +local TYPE_TABLE = 4; +local TYPE_NIL = 5; +local TYPE_NUMBER_AS_INTEGER = 10; + +local typeToId = {string=TYPE_STRING, number=TYPE_NUMBER, boolean=TYPE_BOOLEAN, table=TYPE_TABLE}; +typeToId["nil"] = TYPE_NIL; + +local typesForKey = {}; +typesForKey[TYPE_STRING] = true; +typesForKey[TYPE_NUMBER] = true; +typesForKey[TYPE_BOOLEAN] = true; + +local typesForValue = {}; +typesForValue[TYPE_STRING] = true; +typesForValue[TYPE_NUMBER] = true; +typesForValue[TYPE_BOOLEAN] = true; +typesForValue[TYPE_TABLE] = true; + +local function binaryWrite(format, value, scope) + local buffer = scope._buffer; + + if buffer == nil then + buffer = {}; + scope._buffer = buffer; + end; + + local tam = utils.binaryEncode(buffer, format, value); + return scope.writer(buffer, tam); +end; + +local function binaryWriteString(value, scope) + local buffer2 = scope._buffer2; + + if buffer2 == nil then + buffer2 = {}; + scope._buffer2 = buffer2; + end; + + local tam = utils.binaryEncode(buffer2, "utf8", value); + local writed1 = binaryWrite("u32", tam, scope); + local writed2 = scope.writer(buffer2, tam); + + return writed1 + writed2; +end; + +function serializer.outputValue(value, scope) + local idType = typeToId[type(value)]; + + if idType == TYPE_TABLE then + local conseguiu, so = serializer.tryPackSharedObject(value); + + if conseguiu then + value = so; + idType = typeToId[type(value)]; + end; + end; + + if idType == nil then + error("Tipo não tratado"); + elseif idType == TYPE_NUMBER then + local numberType = math.type(value); + + if numberType == "integer" then + idType = TYPE_NUMBER_AS_INTEGER; + end; + end; + + binaryWrite("u8", idType, scope); + + if idType == TYPE_STRING then + binaryWriteString(value, scope); + elseif idType == TYPE_NUMBER then + binaryWrite("double", value, scope); + elseif idType == TYPE_NUMBER_AS_INTEGER then + binaryWrite("s64", value, scope); + elseif idType == TYPE_BOOLEAN then + if value then + binaryWrite("u8", 1, scope); + else + binaryWrite("u8", 0, scope); + end; + elseif idType == TYPE_TABLE then + serializer.outputTable(value, scope); + else + if idType ~= TYPE_NIL then + error("Tipo desconhecido"); + end; + end; +end; + +function serializer.outputTable(tabela, scope) + local toWrite = {}; + + for k, v in pairs(tabela) do + local kType = typeToId[type(k)]; + local vType = typeToId[type(v)]; + + if (kType ~= nil) and (typesForKey[kType]) and (vType ~= nil) and (typesForValue[vType]) then + toWrite[#toWrite + 1] = k; + end; + end; + + binaryWrite("u32", #toWrite, scope); + + for i = 1, #toWrite, 1 do + local k = toWrite[i]; + local v = tabela[k]; + serializer.outputValue(k, scope); + serializer.outputValue(v, scope); + end; +end; + + +local function binaryRead(format, scope) + local buffer = scope._buffer; + + if buffer == nil then + buffer = {}; + scope._buffer = buffer; + end; + + local bTam = utils.getBinarySize(format); + + if (bTam ~= nil) and (bTam > 0) then + local tamLido = scope.reader(buffer, bTam); + + if tamLido ~= bTam then + error("End of Stream"); + end; + + local value = utils.binaryDecode(buffer, format, 1, tamLido); + return value, tamLido; + else + error("Não é possível prever o tamanho do binaryRead"); + end; +end; + +local function binaryReadString(scope) + local buffer2 = scope._buffer2; + + if buffer2 == nil then + buffer2 = {}; + scope._buffer2 = buffer2; + end; + + local stringTam = binaryRead("u32", scope); + local tamLido = scope.reader(buffer2, stringTam); + + if tamLido ~= stringTam then + error("End of stream"); + end; + + local value = utils.binaryDecode(buffer2, "utf8", 1, tamLido); + return value, tamLido; +end; + +function serializer.inputValue(scope) + local tipo = binaryRead("u8", scope); + + if tipo == TYPE_STRING then + local vstr = binaryReadString(scope); + local conseguiu, so = serializer.tryUnpackSharedObject(vstr); + + if conseguiu then + return so; + else + return vstr; + end; + elseif tipo == TYPE_NIL then + return nil; + elseif tipo == TYPE_NUMBER then + return binaryRead("double", scope); + elseif tipo == TYPE_NUMBER_AS_INTEGER then + return binaryRead("s64", scope); + elseif tipo == TYPE_TABLE then + return serializer.inputTable(scope); + elseif tipo == TYPE_BOOLEAN then + return binaryRead("u8", scope) == 1; + else + error("Tipo Desconhecido: " .. tostring(tipo)); + end; +end; + +function serializer.inputTable(scope) + local qtProps = binaryRead("u32", scope); + local r = {}; + + for i = 1, qtProps, 1 do + local k = serializer.inputValue(scope); + local v = serializer.inputValue(scope); + r[k] = v; + end; + + return r; +end; + +function serializer.valueToStream(value, stream) + local scope = {}; + + scope.writer = function(bytes, qtBytes) + return stream:write(bytes, qtBytes); + end; + + return serializer.outputValue(value, scope); +end; + +function serializer.streamToValue(stream) + local scope = {}; + + scope.reader = function(bytes, qtBytes) + return stream:read(bytes, qtBytes); + end; + + return serializer.inputValue(scope); +end; + +function serializer.serialize(value) + local stream = utils.newMemoryStream(); + local stream2 = utils.newMemoryStream(); + local ret; + serializer.valueToStream(value, stream); + stream.position = 0; + + if stream.size > 512 then + -- compactar + stream2.position = 0; + local buffer = {1}; + stream2:write(buffer, 1); -- sinalizar que está compactado + + utils.zlibCompress(stream, stream2); + else + -- Não compactar + stream2.position = 0; + local buffer = {0}; + stream2:write(buffer, 1); -- sinalizar que não está compactado + + stream2:copyFrom(stream, stream.size); + end; + + stream.size = 0; + stream2.position = 0; + + ret = stream2:readAsBase64(); + stream2.size = 0; + + return ret; +end; + +function serializer.deserialize(base64str) + local stream = utils.newMemoryStream(); + local buffer = {}; + local ret; + + stream:writeBase64(base64str); + stream.position = 0; + + if stream:read(buffer, 1) ~= 1 then + error("End of Stream"); + end; + + if buffer[1] == 1 then + -- compactado + local stream2 = utils.newMemoryStream(); + utils.zlibDecompress(stream, stream2); + stream.size = 0; + stream2.position = 0; + + ret = serializer.streamToValue(stream2); + stream2.size = 0; + else + -- descompactado + ret = serializer.streamToValue(stream); + stream.size = 0; + end; + + return ret; +end; + +function serializer.tryPackSharedObject(tabela) + return SharedObjects.tryPack(tabela); +end; + +function serializer.tryUnpackSharedObject(str) + return SharedObjects.tryUnpack(str); +end; + +local _SERIALIZER_PREFIX = "###SERIALIZER_"; +local _SERIALIZER_SUFIX = "_###"; +local _SERIALIZER_MATCH_MASK = _SERIALIZER_PREFIX .. "(.+)" .. _SERIALIZER_SUFIX; + +function serializer.packData(data) + local typeId = typeToId[type(data)]; + + if typeId ~= nil then + if typeId == TYPE_TABLE then + local conseguiu, so = serializer.tryPackSharedObject(data); + + if conseguiu then + return so; + else + return _SERIALIZER_PREFIX .. serializer.serialize(data) .. _SERIALIZER_SUFIX; + end; + else + return data; + end; + else + return nil; + end +end; + +function serializer.unpackData(data) + if type(data) == "string" then + local conseguiu, so = serializer.tryUnpackSharedObject(data); + + if conseguiu then + return so; + else + local mData = string.match(data, _SERIALIZER_MATCH_MASK); + + if mData ~= nil then + return serializer.deserialize(mData); + else + return data; + end; + end; + else + return data; + end; +end; + +return serializer; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vhd.lua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vhd.lua new file mode 100644 index 00000000..d5875959 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vhd.lua @@ -0,0 +1,77 @@ +local localVHD = {}; + +vhd = localVHD; +VHD = vhd; + +function vhd.expandFileName(shortFileName) + return __vhd__expandFileName(shortFileName); +end; + +function vhd.addSearchPath(directory) + __vhd_addSearchPath(directory); +end; + +function vhd.removeSearchPath(directory) + __vhd_removeSearchPath(directory); +end; + +function vhd.fileExists(fileName) + return __vhd_fileExists(fileName); +end; + +local rrpgUtils = nil; + +function vhd.openFile(fileName, mode) + if rrpgUtils == nil then + rrpgUtils = require("rrpgUtil.lua"); + end; + + if type(mode) ~= "string" then + mode = "r"; + end; + + local expandedFileName = vhd.expandFileName(fileName); + local streamHandle, msgError = _vhd_openFile(expandedFileName, mode); + + if streamHandle ~= nil then + return rrpgUtils.streamFromHandle(streamHandle); + else + return nil, msgError; + end; +end; + +function VHD.forceDirectory(directoryPath) + return __vhd_forceDirectory(directoryPath); +end; + +function VHD.deleteFile(fileName) + return __vhd_deleteFile(fileName); +end + +function VHD.deleteDirectory(directoryPath) + return __vhd_deleteDirectory(directoryPath); +end + +function VHD.directoryExists(path) + return __vhd_directoryExists(path); +end + +function VHD.enumerateContent(directoryPath) + return __vhd_enumerateContent(directoryPath); +end + +function VHD.registerAlias(aliases) + return __vhd_registerAlias(aliases); +end; + +function VHD.copyFile(srcFileName, dstFileName) + local srcFile = VHD.openFile(srcFileName, "r"); + local dstFile = VHD.openFile(dstFileName, "w+"); + + dstFile:copyFrom(srcFile, srcFile.size); + + dstFile:close(); + srcFile:close(); +end; + +return localVHD; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vkCodes.dlua b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vkCodes.dlua new file mode 100644 index 00000000..9c8b7462 --- /dev/null +++ b/Plugins/Sheets/Ficha Tormenta 20 Jogo do Ano/sdk/vkCodes.dlua @@ -0,0 +1,190 @@ +local codes = { + vkLButton = 0x01, + vkRButton = 0x02, + vkCancel = 0x03, + vkMButton = 0x04, + vkXButton1 = 0x05, + vkXButton2 = 0x06, + vkBack = 0x08, + vkTab = 0x09, + vkLineFeed = 0x0A, + vkClear = 0x0C, + vkReturn = 0x0D, + vkShift = 0x10, + vkControl = 0x11, + vkMenu = 0x12, + vkPause = 0x13, + vkCapital = 0x14, + vkKana = 0x15, + vkHangul = 0x15, + vkJunja = 0x17, + vkFinal = 0x18, + vkHanja = 0x19, + vkKanji = 0x19, + vkConvert = 0x1C, + vkNonConvert = 0x1D, + vkAccept = 0x1E, + vkModeChange = 0x1F, + vkEscape = 0x1B, + vkSpace = 0x20, + vkPrior = 0x21, + vkNext = 0x22, + vkEnd = 0x23, + vkHome = 0x24, + vkLeft = 0x25, + vkUp = 0x26, + vkRight = 0x27, + vkDown = 0x28, + vkSelect = 0x29, + vkPrint = 0x2A, + vkExecute = 0x2B, + vkSnapshot = 0x2C, + vkInsert = 0x2D, + vkDelete = 0x2E, + vkHelp = 0x2F, + + vk0 = 0x30, + vk1 = 0x31, + vk2 = 0x32, + vk3 = 0x33, + vk4 = 0x34, + vk5 = 0x35, + vk6 = 0x36, + vk7 = 0x37, + vk8 = 0x38, + vk9 = 0x39, + + vkA = 0x41, + vkB = 0x42, + vkC = 0x43, + vkD = 0x44, + vkE = 0x45, + vkF = 0x46, + vkG = 0x47, + vkH = 0x48, + vkI = 0x49, + vkJ = 0x4A, + vkK = 0x4B, + vkL = 0x4C, + vkM = 0x4D, + vkN = 0x4E, + vkO = 0x4F, + vkP = 0x50, + vkQ = 0x51, + vkR = 0x52, + vkS = 0x53, + vkT = 0x54, + vkU = 0x55, + vkV = 0x56, + vkW = 0x57, + vkX = 0x58, + vkY = 0x59, + vkZ = 0x5A, + vkLWin = 0x5B, + vkRWin = 0x5C, + vkApps = 0x5D, + vkSleep = 0x5F, + vkNumpad0 = 0x60, + vkNumpad1 = 0x61, + vkNumpad2 = 0x62, + vkNumpad3 = 0x63, + vkNumpad4 = 0x64, + vkNumpad5 = 0x65, + vkNumpad6 = 0x66, + vkNumpad7 = 0x67, + vkNumpad8 = 0x68, + vkNumpad9 = 0x69, + vkMultiply = 0x6A, + vkAdd = 0x6B, + vkSeparator = 0x6C, + vkSubtract = 0x6D, + vkDecimal = 0x6E, + vkDivide = 0x6F, + vkF1 = 0x70, + vkF2 = 0x71, + vkF3 = 0x72, + vkF4 = 0x73, + vkF5 = 0x74, + vkF6 = 0x75, + vkF7 = 0x76, + vkF8 = 0x77, + vkF9 = 0x78, + vkF10 = 0x79, + vkF11 = 0x7A, + vkF12 = 0x7B, + vkF13 = 0x7C, + vkF14 = 0x7D, + vkF15 = 0x7E, + vkF16 = 0x7F, + vkF17 = 0x80, + vkF18 = 0x81, + vkF19 = 0x82, + vkF20 = 0x83, + vkF21 = 0x84, + vkF22 = 0x85, + vkF23 = 0x86, + vkF24 = 0x87, + + vkCamera = 0x88, + vkHardwareBack = 0x89, + + vkNumLock = 0x90, + vkScroll = 0x91, + vkLShift = 0xA0, + vkRShift = 0xA1, + vkLControl = 0xA2, + vkRControl = 0xA3, + vkLMenu = 0xA4, + vkRMenu = 0xA5, + + vkBrowserBack = 0xA6, + vkBrowserForward = 0xA7, + vkBrowserRefresh = 0xA8, + vkBrowserStop = 0xA9, + vkBrowserSearch = 0xAA, + vkBrowserFavorites = 0xAB, + vkBrowserHome = 0xAC, + vkVolumeMute = 0xAD, + vkVolumeDown = 0xAE, + vkVolumeUp = 0xAF, + vkMediaNextTrack = 0xB0, + vkMediaPrevTrack = 0xB1, + vkMediaStop = 0xB2, + vkMediaPlayPause = 0xB3, + vkLaunchMail = 0xB4, + vkLaunchMediaSelect= 0xB5, + vkLaunchApp1 = 0xB6, + vkLaunchApp2 = 0xB7, + + vkSemicolon = 0xBA, + vkEqual = 0xBB, + vkComma = 0xBC, + vkMinus = 0xBD, + vkPeriod = 0xBE, + vkSlash = 0xBF, + vkTilde = 0xC0, + vkLeftBracket = 0xDB, + vkBackslash = 0xDC, + vkRightBracket = 0xDD, + vkQuote = 0xDE, + vkPara = 0xDF, + + vkOem102 = 0xE2, + vkIcoHelp = 0xE3, + vkIco00 = 0xE4, + vkProcessKey = 0xE5, + vkIcoClear = 0xE6, + vkPacket = 0xE7, + vkAttn = 0xF6, + vkCrsel = 0xF7, + vkExsel = 0xF8, + vkErEof = 0xF9, + vkPlay = 0xFA, + vkZoom = 0xFB, + vkNoname = 0xFC, + vkPA1 = 0xFD, + vkOemClear = 0xFE, + vkNone = 0xFF +}; + +return codes; \ No newline at end of file diff --git a/Plugins/Sheets/Ficha Tormente20 Jogo do Ano b/Plugins/Sheets/Ficha Tormente20 Jogo do Ano deleted file mode 160000 index 67fb0ca2..00000000 --- a/Plugins/Sheets/Ficha Tormente20 Jogo do Ano +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 67fb0ca278fed89807c509b5e583c6abab0870e7