### PLoop XList Dynamic List Usage Examples Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Provides various examples of `XList` (dynamic list) creation and usage in PLoop. It demonstrates how to define ranges with start, end, and step (including negative steps), and how to use `Each` and `Map` methods with different input types like iterators and existing lists. ```Lua require "PLoop" PLoop (function(_ENV) -- 开始, 结束[, 步长] XList(5, 10, 2):Each(print) -- 步长可以是负数 XList(4, 1, -1):Each(print) -- 结束 -- 开始和步长默认1 XList(10):Map("x=>x^2"):Each(print) -- 迭代函数[,列表[,索引]] XList(ipairs{1, 2, 3, 4}):Each(print) -- 列表 XList{1, 2, 3, 4}:Each(print) XList(List(10):Range(5, 8)):Each(print) end) ``` -------------------------------- ### Real-world Database Transaction Management with `with` Keyword in PLoop Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md A practical example demonstrating nested `with` blocks for managing database contexts and transactions. It shows how to open a DB context, start a transaction, query/lock data, save changes, or rollback on failure. ```Lua function RecordLastLogin(id) -- Create DB context, open database connection with(MyDBContext())(function(ctx) -- Start database transaction with(ctx.Transaction)(function(trans) -- Query and lock target user data local user = ctx.Users:Lock{ id = id }:First() if user then user.LastLogin = Date.Now -- Commit changes to database ctx:SaveChanges() else -- Cancel transaction processing trans:Rollback() end end) end) end ``` -------------------------------- ### Scorpio Module Initialization with Empty Version Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This example demonstrates how to initialize a Scorpio module using an empty string as the version token. This allows multiple Lua files to contribute to the same module without raising version conflict errors. ```Lua Scorpio "ScorpioTest" "" ``` -------------------------------- ### Lua: PLoop Dictionary Object Creation Examples Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Examples demonstrating how to create Dictionary objects using different constructors in PLoop. This includes converting the global environment _G into a dictionary and creating a dictionary where keys are mapped to their squares using a List and Map operation. ```lua require "PLoop" PLoop(function(_ENV) Dictionary(_G) -- Convert the _G to a dictionary -- key map to key^2 lst = List(10) Dictionary(lst, lst:Map(function(x)return x^2 end)) end) ``` -------------------------------- ### Examples of Wow.FromEvent Usage Source: https://github.com/kurapica/scorpio/blob/master/Docs/003.observable.md Provides various examples of using `Scorpio.Wow.FromEvent` to create observables from system events. This includes subscribing to print all arguments, mapping to specific data, filtering by unit, delaying frequent events with `Next()`, and using multiple events as a source. ```Lua -- print all event args of UNIT_HEALTH Scorpio.Wow.FromEvent("UNIT_HEALTH"):Subscribe(print) -- print the unit and its health Scorpio.Wow.FromEvent("UNIT_HEALTH"):Map(function(unit) return unit, UnitHealth(unit) end):Subscribe(print) -- only print player and its health Scorpio.Wow.FromEvent("UNIT_HEALTH"):MatchUnit("player"):Map(function(unit) return unit, UnitHealth(unit) end):Subscribe(print) -- Only print the BAG_UPDATE once per frame, The BAG_UPDATEA may occurs several times in the same time Scorpio.Wow.FromEvent("BAG_UPDATE"):Next():Subscribe(function() print("BAG_UPDATE", GetTime()) end)) -- Use multi events as source Scorpio.Wow.FromEvent("UNIT_HEALTH", "UNIT_MAXHEALTH"):Subscribe(print) ``` -------------------------------- ### PLoop Installation and Module Loading Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Demonstrates how to load the PLoop library in Lua. It shows how to modify `package.path` to include custom project directories for PLoop and the standard `require` statement for module loading. ```Lua package.path = package.path .. ";项目所在路径/?/init.lua;项目所在路径/?.lua" require "PLoop" ``` -------------------------------- ### Lua: PLoop Dictionary Object Iteration and Reduction Examples Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Lua examples demonstrating advanced iteration and reduction techniques for PLoop Dictionary objects. This includes retrieving, sorting, and printing all keys from the global environment _G and calculating the sum of all values in a dictionary using the Reduce method. ```lua require "PLoop" PLoop(function(_ENV) -- 获取_G的所有键,转换为List后,排序,再打印 Dictionary(_G).Keys:ToList():Sort():Each(print) -- 计算所有值的总和 print(Dictionary{ A = 1, B = 2, C = 3}:Reduce(function(k, v, init) return init + v end, 0)) end) ``` -------------------------------- ### Example: Accessing Scorpio Module Properties and Registering Events Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This Lua code demonstrates how to access properties like _Parent and _Addon from within a Scorpio module. It also shows an example of registering a system event, although this method is noted as not recommended for general use in Scorpio. ```lua Scorpio "ScorpioTest.ModuleA" "1.0.0" -- Display the parent module's name print(_Parent._Name) -- ScorpioTest print(_Parent == _Addon) -- true -- The module also provided several methods like other addon libs -- but it's not recommended in the Scorpio _M:RegisterEvent("PLAYER_LOGIN", function() print("Player logined") end) ``` -------------------------------- ### PLoop List Extend Method with XList Example Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Illustrates how to use the `Extend` method of `System.Collections.List` to append elements from an `XList` (dynamic list) object. The example then concatenates and prints the resulting list, showcasing method chaining. ```Lua require "PLoop" PLoop (function(_ENV) -- 1,2,3,4,5,6,7,8,9 print(table.concat(List{1, 2, 3, 4}:Extend(XList(5, 9)), ",")) end) ``` -------------------------------- ### Install PLoop in Lua Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README.md Demonstrates how to load the PLoop library in Lua by modifying the package path or using `require`. ```Lua package.path = package.path .. ";PATH TO PLOOP PARENT FOLDER/?/init.lua;PATH TO PLOOP PARENT FOLDER/?.lua" require "PLoop" ``` -------------------------------- ### Scorpio Module System Initialization Pattern Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This pattern defines the general syntax for initializing any module within the Scorpio framework. It specifies the full module path, which can include nested sub-modules, and an optional version string. ```Lua Scorpio "AddonName[.ModuleName[.SubModuleName...]]" "[version]" ``` -------------------------------- ### Lua: PLoop Module and Class Documentation Example Source: https://github.com/kurapica/scorpio/blob/master/PLoop/PLDoc.md Demonstrates how PLoop organizes code into nested environments and namespaces, and how documented comments are associated with features like modules, classes, structs, properties, and methods. The example shows a 'Test' module containing a 'Test.Model' namespace with a 'Unit' class, including its properties and methods, and an inner 'Location' struct. ```Lua --- The Test module Module "Test" "v1.0.0" namespace "Test.Model" --- The Unit class class "Unit" (function(_ENV) --- The unit's location type struct "Location" (function(_ENV) x = Number y = Number end) --- The unit's name property "Name" { Type = String } --- The unit's location property "Location" { Type = Location } __Arguments__{ Location } function SetLocation(self, loc) end end) ``` -------------------------------- ### Defining Slash Commands for Module Control Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Provides examples of defining slash commands (`__SlashCmd__`) to enable or disable a module. Multiple command aliases can be mapped to a single handler function. ```Lua -- enable the module -- /sct enable -- /scptest enable __SlashCmd__ "scptest" "enable" __SlashCmd__ "sct" "enable" function EnableModule(info) -- _Enabled is a property of the module, it only recevei the boolean value, -- it can be used to enable/disable the module, if the module is disabled, -- all system event handlers, secure hook handlers are disabled so won't be called _Enabled = true end -- disable the module -- /sct disable -- /scptest disable __SlashCmd__ "scptest" "disable" __SlashCmd__ "sct" "disable" function DisableModule(info) _Enabled = false end ``` -------------------------------- ### Slash Commands with Localized Descriptions Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Demonstrates how to use localization for slash command descriptions, allowing the help text to be displayed in different languages based on the `L` (localization) table. ```Lua __SlashCmd__("sct", "enable", L["- enable the module"]) function enableModule() end ``` -------------------------------- ### Secure Hooking with Owner Object Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Illustrates how to specify the owner object of the target function when using `__SecureHook__`, such as hooking `math.min` by providing the `math` table. ```Lua __SecureHook__(math, "min") function Hook_math_min(...) print("Call the math.min", ...) end ``` -------------------------------- ### PLoop Custom Object Creation with __new Metamethod Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Illustrates the use of the `__new` metamethod in PLoop to customize the creation of the underlying table that will be encapsulated as an object. This example shows how to efficiently initialize an object with multiple arguments, like a list. ```Lua require "PLoop" PLoop(function(_ENV) class "List" (function(_ENV) function __new(cls, ...) return { ... }, true end end) v = List(1, 2, 3, 4, 5, 6) end) ``` -------------------------------- ### Slash Commands with Descriptions for Auto-Generated Help Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Illustrates how to include a description with `__SlashCmd__` definitions. The system can then automatically generate a formatted list of commands when the base command is entered. ```Lua Scorpio "ScorpioTest" "" __SlashCmd__ "sct" "enable" "- enable the module" function enableModule() end __SlashCmd__ "sct" "disable" "- disable the module" function disableModule() end ``` -------------------------------- ### Defining Slash Command for Help Display Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Shows how to define a simple slash command (e.g., `/sct` or `/scptest`) without options, typically used to display a help message or list available commands. ```Lua __SlashCmd__ "scptest" __SlashCmd__ "sct" function Help() print("/sct(scptest) enable -- enable the addon") print("/sct(scptest) disable -- disable the addon") end ``` -------------------------------- ### Lua: PLoop Dictionary Object Update Example Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md This Lua example demonstrates how to use the Update method of a PLoop Dictionary object. It initializes a dictionary and then updates specific key-value pairs using a standard Lua table, followed by iterating and printing the updated contents. ```lua require "PLoop" PLoop(function(_ENV) v = Dictionary(List(5), List(5)) v:Update{ [3] = 9, [4] = 16 } -- 1 1 -- 2 2 -- 3 9 -- 4 16 -- 5 5 v:Each(print) end) ``` -------------------------------- ### Initialize Scorpio Addon Main File Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This code snippet shows the required first line for the main file of a Scorpio-based addon. It initializes the root module of the addon, specifying its name and an optional version string. ```Lua Scorpio "ScorpioTest" "1.0.0" ``` -------------------------------- ### Lua: Initial Scorpio Event Handler with Cube Source: https://github.com/kurapica/scorpio/blob/master/Docs/002.async.md This snippet demonstrates how to use the Cube tool to run Lua code directly in the game for quick testing. It shows a basic Scorpio setup for handling the `UNIT_SPELLCAST_START` system event. ```Lua Scorpio "ScorpioTest" "" __SystemEvent__() function UNIT_SPELLCAST_START(...) print(...) end ``` -------------------------------- ### Implementing Core Module Lifecycle Events in ScorpioTest.lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This Lua example demonstrates how to implement various lifecycle event handlers (OnLoad, OnEnable, OnDisable, OnQuit) within a main Scorpio addon module. It includes logic for managing saved variables, setting default values, and handling slash commands for enabling/disabling the module. ```lua Scorpio "ScorpioTest" "1.0.0" function OnLoad(self) -- SavedVariables Manager, explained later _SVDB = SVManager("ScorpioTest_DB", "ScorpioTest_DB_Char") _SVDB:SetDefault{ Enable = true } if _SVDB.Char.LastPlayed then print("The character is last played at " .. _SVDB.Char.LastPlayed) end _Enabled = _SVDB.Enable end function OnEnable(self) _SVDB.Enable = true end function OnDisable(self) _SVDB.Enable = false end function OnQuit(self) -- Save the last played time for the character _SVDB.Char.LastPlayed = date("%c") end -- The slash command to enable/disable __SlashCmd__ "sct" "enable" function EnableModule() _Enabled = true end __SlashCmd__ "sct" "disable" function DisableModule() _Enabled = false end ``` -------------------------------- ### JSON Serialization and Deserialization with PLoop System.Serialization Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md A complete example demonstrating how to serialize Lua tables to JSON strings and deserialize JSON strings back into Lua tables using `System.Serialization.JsonFormatProvider` and `System.Serialization.StringFormatProvider`. ```Lua require "PLoop" (function(_ENV) import "System.Serialization" json = [==[ { "debug": "on\toff", "nums" : [1,7,89,4,5,6,9,3,2,1,1,9,3,0,11] }]==] -- Deserialize json data to lua table data = Serialization.Deserialize(JsonFormatProvider(), json) -- Serialize lua table to string, with indent -- { -- debug = "on\toff", -- nums = { -- [1] = 1, -- [2] = 7, -- [3] = 89, -- [4] = 4, -- [5] = 5, -- [6] = 6, -- [7] = 9, -- [8] = 3, -- [9] = 2, -- [10] = 1, -- [11] = 1, -- [12] = 9, -- [13] = 3, -- [14] = 0, -- [15] = 11 -- } -- } print(Serialization.Serialize(StringFormatProvider{Indent = true}, data)) end) ``` -------------------------------- ### Example PLDoc Class Documentation in Lua Source: https://github.com/kurapica/scorpio/blob/master/PLoop/PLDoc.md This Lua code snippet demonstrates how to document a class, its properties, and its type using PLDoc comment tags such as `@prototype`, `@type`, and `@property-type` to provide explicit metadata. ```Lua import "System" --- A unit class -- @prototype class -- @type TestProject.Unit class "Unit" (function(_ENV) --- Unit's name -- @property-type System.String property "Name" { Type = String } end) ``` -------------------------------- ### Get User Input in Lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/005.widget.md Shows how to use the 'Input' API within a 'Continue' coroutine to prompt the user for their name and then print the result. ```Lua Scorpio "Test" "" Continue(function() print("Hello " .. Input("Please input your name")) end) ``` -------------------------------- ### Scorpio Message Framework Example Source: https://github.com/kurapica/scorpio/blob/master/Docs/007.message.md Demonstrates how to register a message handler (`TEST_REQUEST`), send an addon message (`SendAddonMessage`), and wait for a reply (`NextMessage`) using Scorpio's asynchronous message framework. It shows a full request-reply cycle for exchanging data between players. ```Lua Scorpio "MessageTest" "" TEST_REQUEST = nil -- Reset if you want re-run -- Register a message handler for message with TEST_REQUEST as prefix __Message__() function TEST_REQUEST(message, channel, sender, target) print("[REQUEST]", message.request) -- Send the Addon message, this is not the C_ChatInfo.SendAddonMessage -- It's a Scorpio version and can only be used in Scorpio's modules -- It use the same arguments as the C_ChatInfo.SendAddonMessage -- but the message could be any lua datas -- -- So here we send a reply back to the client SendAddonMessage("TEST_REPLY", { result = GetTime() }, channel, sender) end -- Run an async function to send and receive the result Continue(function() -- Send the request (this tested in the classic client, so we can use SAY as the channel) SendAddonMessage("TEST_REQUEST", { request = "time" }, "WHISPER", GetUnitName("player")) -- Wait the replay message, works like NextEvent local reply = NextMessage("TEST_REPLY") print("[REPLY]", reply.result) end) ``` -------------------------------- ### Create and Handle UIPanelButton Click in Lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/005.widget.md Illustrates the creation of a `Scorpio.Widget.UIPanelButton` and how to handle its `OnClick` event. The example shows setting button text and location via the `Style` system, and using `__Async__()` for asynchronous event handling with user input. ```Lua Scorpio "Test" "" button = UIPanelButton("Button", GameMenuFrame) Style[button] = { location = { Anchor("BOTTOM", 0, 18) }, text = "Hello", } __Async__() -- We can mark the script event handler as async function button:OnClick() Alert("Hello " .. Input("Please input your name")) end ``` -------------------------------- ### Handle Individual WoW System Events with Scorpio Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Demonstrates using `__SystemEvent__()` to register separate Lua functions for distinct WoW system events like `UNIT_SPELLCAST_START` and `UNIT_SPELLCAST_CHANNEL_START`. Each function acts as a dedicated handler, printing event details. ```lua Scorpio "ScorpioTest" "1.0.0" -- keep this as the first line __SystemEvent__() function UNIT_SPELLCAST_START(unit, spell) print(unit .. " cast " .. spell) end __SystemEvent__() function UNIT_SPELLCAST_CHANNEL_START(unit, spell) print(unit .. " cast " .. spell) end ``` -------------------------------- ### Attach Resizer Widget to a Frame in Lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/005.widget.md Demonstrates how to attach a `Scorpio.Widget.Resizer` to a frame to enable resizing. The example also shows how to adjust the resizer's location using the `Style` system or direct API calls for precise positioning. ```Lua Scorpio "Test" "" resizer = Resizer("Resizer", GameMenuFrame) GameMenuFrame:SetResizable(true) Style[resizer].location = { Anchor("BOTTOMRIGHT", -8, 8)} ``` ```Lua resizer:ClearAllPoints() resizer:SetPoint("BOTTOMRIGHT", -8, 8) ``` -------------------------------- ### Lua: Firing Custom System Events with `FireSystemEvent` Source: https://github.com/kurapica/scorpio/blob/master/Docs/002.async.md This example demonstrates how to define and fire custom system events using `FireSystemEvent`. It shows an `OnEnable` function waiting for an addon to load and then notifying other modules, and a `__SystemEvent__` handler for the custom event. ```Lua Scorpio "ScorpioTest" "" __Async__() function OnEnable(self) if not IsAddOnLoaded("Blizzard_BattlefieldMap") then while NextEvent("ADDON_LOADED") ~= "Blizzard_BattlefieldMap" do end end -- Notify the other modules that the BattlefieldMapFrame is preapred FireSystemEvent("EBFM_ZONEMAP_INITED", BattlefieldMapFrame) end __SystemEvent__() function EBFM_ZONEMAP_INITED(self) -- Add quest data to the BattlefieldMapFrame self:AddDataProvider(CreateFromMixins(QuestBlobDataProviderMixin)) end ``` -------------------------------- ### SVManager Constructor Reference Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Details the constructor for the SVManager, explaining its two parameters: the required account saved variable name and the optional character saved variable name. If the character variable name is omitted, the account variable handles character data. ```APIDOC SVManager(account_var_name: string, char_var_name: string = nil) ``` -------------------------------- ### Lua: Countdown Timer with C_Timer Callback Source: https://github.com/kurapica/scorpio/blob/master/Docs/002.async.md This example illustrates a traditional approach to creating a countdown timer using Lua's `C_Timer.After` function. It demonstrates a callback-based asynchronous operation, where `countDown` calls itself after a delay, and integrates with a slash command. ```Lua Scorpio "ScorpioTest" "" local function countDown(cnt) print(cnt) if cnt > 1 then C_Timer.After(1, function() countDown(cnt - 1) end) -- use the callback end end __SlashCmd__ "sct" "cd" -- /sct cd 10 count down from 10 to 1 per sec function CountDown(cnt) countDown(floor(cnt)) end ``` -------------------------------- ### Implementing Additive Event Handlers in PLoop Lua Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md This example illustrates the use of additive event handlers, which allow multiple handlers to be chained and executed sequentially. It shows how a subclass can add its own handler to an inherited event, typically used in constructors or initialization methods. ```Lua require "PLoop" PLoop(function(_ENV) class "Person" (function(_ENV) -- 为Person类申明一个事件 event "OnNameChanged" field { name = "anonymous" } function SetName(self, name) if name ~= self.name then -- 发起事件通知外界 OnNameChanged(self, name, self.name) self.name = name end end end) -- 定义子类 class "Student" (function(_ENV) inherit "Person" local function onNameChanged(self, name, old) print(("Student %s renamed to %s"):format(old, name)) end function Student(self, name) self:SetName(name) self.OnNameChanged = self.OnNameChanged + onNameChanged end end) o = Student("Ann") function o:OnNameChanged(name) print("My new name is " .. name) end -- Student Ann renamed to Ammy -- My new name is Ammy o:SetName("Ammy") end) ``` -------------------------------- ### Implementing Sub-Module Lifecycle Events in ScorpioTestMdl.lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This Lua example illustrates how a sub-module within the Scorpio framework can define its own lifecycle event handlers (OnLoad, OnEnable, OnDisable). It shows how sub-modules can initialize their own saved variable data and respond to enable/disable events independently. ```lua Scorpio "ScorpioTest.ModuleA" "1.0.0" -- The sub modules can have their own handlers for those module events function OnLoad(self) _SVDB.Char:SetDefault{ ModuleA = { Key = 1 } } end function OnEnable(self) print("The sub module is enabled") end function OnDisable(self) print("The sub module is disabled") end ``` -------------------------------- ### PLoop List Object Creation Examples Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Illustrates various ways to construct `System.Collections.List` objects in PLoop, including from tables, by count, with a generator function, and from variable arguments. It also demonstrates the effect of `PLoop(function(_ENV) end)` on variable scope and how `import` makes types accessible. ```Lua require "PLoop" PLoop(function(_ENV) -- List(table) o = {1, 2, 3} print(o == List(o)) -- true -- List(count) v = List(10) -- {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} -- List(count, func) v = List(10, function(i) return math.random(100) end) -- {46, 41, 85, 80, 62, 37, 29, 91, 62, 37} -- List(...) v = List(1, 5, 4) -- {1, 5, 4} end) print(v) -- nil print(List) -- nil import "System.Collections" print(List) -- System.Collections.List ``` -------------------------------- ### Scorpio Addon TOC for Complex Config Example Source: https://github.com/kurapica/scorpio/blob/master/Docs/008.config.md Defines the table of contents (TOC) structure for a more advanced Scorpio addon, specifying interface version, dependencies, a global saved variable, and an additional per-character saved variable, indicating a more complex configuration setup. ```toc ## Interface: 110107 ## Dependencies: Scorpio ## SavedVariables: TestAddonSave ## SavedVariablesPerCharacter: TestAddonCharSave ``` -------------------------------- ### Apply Property Get/Set Behavior Modifiers in PLoop Lua Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Demonstrates how to use '__Set__' and '__Get__' attributes with 'System.PropertySet' and 'System.PropertyGet' flags to modify property assignment and retrieval. This example shows cloning on set and get, and automatic disposal of old objects when a new value is assigned. ```Lua require "PLoop" PLoop(function(_ENV) class "Data" (function(_ENV) extend "ICloneable" -- 可复制类必须扩展这个接口 local _Cnt = 0 -- 实现Clone方法 function Clone(self) return Data() -- for test, just return a new one end function Dispose(self) print("Dispose Data " .. self.Index) end function __ctor(self) _Cnt = _Cnt + 1 self.Index = _Cnt end end) class "A" (function(_ENV) __Set__(PropertySet.Clone + PropertySet.Retain) __Get__(PropertySet.Clone) property "Data" { type = Data } end) o = A() dt = Data() o.Data = dt print(dt.Index, o.Data.Index) -- 1 3 o.Data = nil -- Dispose Data 2 end) ``` -------------------------------- ### Accessing Localization Strings in Lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This Lua snippet illustrates how to access the defined localization strings within application code. It demonstrates direct access via the `_Locale` global table and also by assigning `_Locale` to a local variable for convenience. The example prints localized messages to the console. ```lua Scorpio "ScorpioTest" "1.0.0" -- You can assign it to a new variable for easy using L = _Locale function OnLoad(self) print(_Locale["A test message"]) print(_Locale[1]) print(L["A test message"]) end ``` -------------------------------- ### Basic Usage of PLoop System.Module Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Introduces the `System.Module` class in PLoop, which provides a private environment for code isolation and project management. It demonstrates how to create a module and set it as the current environment using `_ENV = Module "ModuleName" "Version"`. ```Lua require "PLoop" _ENV = Module "TestMDL" "1.0.0" namespace "Test" __Async__() function dotask() print(coroutine.running()) end ``` -------------------------------- ### Lua: Traditional Combat Timer with Callbacks and Events Source: https://github.com/kurapica/scorpio/blob/master/Docs/002.async.md This example demonstrates a more complex scenario of tracking combat time using traditional Lua methods. It involves splitting logic across multiple functions, using `C_Timer.After` for callbacks, and creating a `Frame` to register and handle system events like `PLAYER_REGEN_DISABLED` and `PLAYER_REGEN_ENABLED`. ```Lua -- We make a combat time count local inCombat = false local count = 0 local function countCombat() if inCombat then count = count + 1 print("The combat still going for " .. count .. " sec") C_Timer.After(1, countCombat) else print("The combat is done, last for " .. count .. "sec") end end local frame = CreateFrame("Frame") frame:RegisterEvent("PLAYER_REGEN_DISABLED") frame:RegisterEvent("PLAYER_REGEN_ENABLED") frame:SetScript("OnEvent", function(event) if event == "PLAYER_REGEN_DISABLED" then -- Start the combat inCombat = true count = 0 C_Timer.After(1, countCombat) else -- The combat is stopped inCombat = false end end) ``` -------------------------------- ### Lua Example: Saved Variable File Structure for Config Node Source: https://github.com/kurapica/scorpio/blob/master/Docs/008.config.md Illustrates the content of a saved variable file (`TestAddonSave.lua`) generated by the Scorpio config node system. This example shows how a boolean config field, such as 'enable', is persisted within the saved data structure. ```lua TestAddonSave = { enable = false, } ``` -------------------------------- ### PLoop Custom Struct Type Validation Example Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README.md Demonstrates the usage of a custom struct type, Number, in PLoop for value validation. The example shows how attempting to assign a non-numeric value to a variable declared as Number results in an error, enforcing type correctness. ```Lua require "PLoop" (function(_ENV) v = Number(true) -- Error : the value must be number, got boolean end) ``` -------------------------------- ### Creating and Using a Subject Observable Source: https://github.com/kurapica/scorpio/blob/master/Docs/003.observable.md Illustrates how to create a custom `Subject` observable, import the `System.Reactive` namespace, and use `OnNext` to manually push data sequences. This is useful when data cannot be directly generated from events, demonstrating delayed emission and subject completion. ```Lua Scorpio "Test" "" import "System.Reactive" -- Need import the namespace subject = Subject() subject:Dump() -- For test only Continue(function() for i = 1, 10 do -- the OnNext can send multi-data subject:OnNext(i, i^2, i^3) Delay(1) end subject:OnCompleted() -- Finish the subject, normally don't needed in the Wow end) ``` -------------------------------- ### Pick Opacity in Lua Source: https://github.com/kurapica/scorpio/blob/master/Docs/005.widget.md Demonstrates using the 'PickOpacity' API within a 'Continue' coroutine to allow the user to select an opacity value, initialized to 0.5, and then print the result. ```Lua Scorpio "Test" "" Continue(function() print("The Opacity is " .. PickOpacity(0.5)) end) ``` -------------------------------- ### Get Registered Event Handler API Source: https://github.com/kurapica/scorpio/blob/master/changelog.txt Adds the `GetRegisteredEventHandler` API for the Scorpio module, allowing retrieval of registered event handlers. ```APIDOC GetRegisteredEventHandler ``` -------------------------------- ### PLoop Serialization Toolset Shortcuts for JSON and String Formatting Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Documents convenient shortcut functions provided by `Toolset` for common JSON and string serialization/deserialization tasks, simplifying the use of `JsonFormatProvider` and `StringFormatProvider`. ```APIDOC Toolset.json(data[,type]) -- Convert object/data to JSON data package Toolset.parsejson(json[, type]) -- Convert JSON data to Lua data or PLoop object Toolset.tostring(data[, type[, pretty]]) -- Serialize object/data to string Toolset.parsestring(str[, type]) -- Convert string to Lua data or PLoop object ``` -------------------------------- ### Create a JSON Web Service with PLoop System.Web in Lua Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README.md This Lua code illustrates how to create a simple web application (`TestWebApp`) using `PLoop.System.Web`. It defines a GET route (`/jsonhandler`) that automatically converts the returned Lua table into a JSON response, showcasing how to build web services with a declarative approach. ```Lua require "PLoop.System.Web" -- Create a web application Application "TestWebApp" (function(_ENV) __Route__("/jsonhandler", HttpMethod.GET) -- bind the route __Json__() -- the return value will be converted to JSON format as response function JsonHandler(context) return { Data = { { Name = "Ann", Age = 12}, { Name = "King", Age = 32}, { Name = "July", Age = 22}, { Name = "Sam", Age = 30}, } } end end) ``` -------------------------------- ### PLoop List RemoveByIndex Method Example Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Demonstrates the usage of the `RemoveByIndex` method on a `System.Collections.List` object. It shows how the method removes and returns the last element by default when no index is specified. ```Lua require "PLoop" PLoop(function(_ENV) obj = List(10) print(obj:RemoveByIndex()) -- 10 end) ``` -------------------------------- ### PLoop Object Construction Flow Simulation Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md A pseudo-code representation of the internal object construction process in PLoop, detailing the sequence of calls to `__exist`, `__new`, field copying, metatable setting, and `__ctor` invocation. ```Lua -- 检查对象是否存在,存在就返回该对象 local object = __exist(cls, ...) if object then return object end -- 获得一个将被封装为对象的table object = __new(cls, ...) or {} -- 复制字段 field:Copyto(object) -- 封装table为对象 setmetatable(object, objMeta) -- 调用构造体方法 __ctor(object, ...) -- 返回对象 return object ``` -------------------------------- ### Lua hooksecurefunc Usage Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Illustrates the use of `hooksecurefunc` to add a handler that executes after the original function, as recommended by Blizzard for WoW addon development. This method does not replace the original function. ```Lua hooksecurefunc(math, "min", function(...) print("Call math.min", ...) end) local m = math.min(1, 2, 3) -- call the original one ``` -------------------------------- ### Lua PLoop Collection: Dictionary Operations Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README.md Example of using PLoop's `XDictionary` to filter global variables, extract keys, sort them, and join the results into a string. ```Lua require "PLoop" -- Get all the keys from the _G whose value is a table, sort them and join them by "," -- The result is "_G,arg,coroutine,debug,io,math,os,package,string,table" print( PLoop.System.Collections.XDictionary(_G):Filter("k,v=>type(v)=='table'").Keys:ToList():Sort():Join(",") ) ``` -------------------------------- ### Lua: Fade Out Animation with Next() Source: https://github.com/kurapica/scorpio/blob/master/Docs/002.async.md Demonstrates how to create a smooth fade-out animation for a UI texture over 4 seconds using `Next()` to yield and resume execution in the next phase, ensuring a consistent frame rate and preventing UI freezes. ```Lua Scorpio "ScorpioTest" "" local txt = UIParent:CreateTexture("ARTWORK") txt:SetPoint("CENTER") txt:SetSize(100, 100) txt:SetColorTexture(1, 1, 1) __Async__() function FadeOut(self) local total = 60 * 4 -- 60FPS * 4 sec local count = total repeat count = count - 1 self:SetAlpha(count / total) Next() -- Wait next phase until count == 0 end FadeOut(txt) ``` -------------------------------- ### PLoop Class Metamethods and Metadata Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README-zh.md Documentation for PLoop's extended metamethods and metadata keys used for class and object construction, including standard Lua metamethods and PLoop-specific lifecycle hooks like `__exist`, `__new`, `__ctor`, `__dtor`, and `__field`. ```APIDOC Key |Description :--------------|:-------------- `__add` |Class object addition: a + b `__sub` |Class object subtraction: a - b `__mul` |Class object multiplication: a * b `__div` |Class object division: a / b `__mod` |Class object modulo: a % b `__pow` |Class object exponentiation: a ^ b `__unm` |Class object unary minus: - a `__idiv` |Class object floor division: a // b `__band` |Class object bitwise AND: a & b `__bor` |Class object bitwise OR: a | b `__bxor` |Class object bitwise XOR: a ~ b `__bnot` |Class object bitwise NOT: ~a `__shl` |Class object left shift: a << b `__shr` |Class object right shift: a >> b `__concat` |Class object concatenation: a .. b `__len` |Class object length calculation: #a `__eq` |Class object equality check: a == b `__lt` |Class object less than check: a < b `__le` |Class object less than or equal to check: a <= b `__index` |Class object field lookup: return a[k] `__newindex` |Class object new value handling: a[k] = v `__call` |Class object call: a(...) `__gc` |Class object GC handling, currently not very useful `__tostring` |Class object string conversion: tostring(a) `__ipairs` |Placeholder, not usable, please use collection processing instead `__pairs` |Placeholder, not usable, please use collection processing instead `__exist` |Used when a class constructs an object to check if an existing object can be reused based on parameters. `__field` |Object's initialization fields and values. `__new` |Method for a class to construct an object, generating the table that will be encapsulated as an object. `__ctor` |Class object constructor method. `__dtor` |Class object destructor method. ``` -------------------------------- ### PLoop Toolset Helpers for JSON and String Serialization Source: https://github.com/kurapica/scorpio/blob/master/PLoop/README.md Describes convenience functions available in PLoop's 'Toolset' for simplified JSON serialization ('Toolset.json', 'Toolset.parsejson') and general string serialization ('Toolset.tostring', 'Toolset.parsestring') of data or objects. ```APIDOC Toolset.json(data[, type]) data: The data or object to serialize. type: Optional, specifies the type for serialization. Returns: JSON string representation of the data. Toolset.parsejson(json[, type]) json: The JSON string to deserialize. type: Optional, specifies the target type for deserialization. Returns: Lua table or object parsed from JSON. Toolset.tostring(data[, type[, pretty]]) data: The data or object to serialize. type: Optional, specifies the type for serialization. pretty: Optional boolean, if true, formats the output for readability. Returns: String representation of the data. Toolset.parsestring(str[, type]) str: The string to deserialize. type: Optional, specifies the target type for deserialization. Returns: Lua table or object parsed from the string. ``` -------------------------------- ### Addon Secure Hooking (Implicit Function Name) Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Shows how to use `__AddonSecureHook__` with only the addon name. The system will automatically hook the function with the same name as the handler function once the specified addon is loaded. ```Lua __AddonSecureHook__ "Blizzard_AuctionUI" function AuctionFrameTab_OnClick(self, button, down, index) print("Click " .. self:GetName() .. " Auction tab") end ``` -------------------------------- ### API Reference: Useful Observable Generators Source: https://github.com/kurapica/scorpio/blob/master/Docs/003.observable.md Describes alternative methods to create observable data sources beyond `Wow.FromEvent`, including time-based emissions and custom data streams using `Observable.Interval`, `Observable.Timer`, and `Subject`. ```APIDOC Observable.Interval(interval: number, max?: number) Description: Emits a sequence of integers spaced by a given time interval. Parameters: interval: Time interval in seconds. max (optional): Maximum number of emissions. Observable.Timer(delay: number) Description: Emits a particular item after a given delay, similar to C_Timer.After. Parameters: delay: Delay in seconds. Subject Description: A type of observable that allows values to be multicasted to many Observers. It's useful when data sequences cannot be generated directly from events. Methods: OnNext(...data: any): Sends multi-data to observers. OnCompleted(): Finishes the subject (normally not needed in Wow). Usage: Requires import "System.Reactive". ``` -------------------------------- ### Lua: Wait for System Event with NextEvent() Source: https://github.com/kurapica/scorpio/blob/master/Docs/002.async.md Demonstrates how to pause execution until a specific system event, such as `ADDON_LOADED`, is fired. This pattern is useful for ensuring that external dependencies or specific game modules are fully loaded before proceeding with an addon's initialization logic. ```Lua Scorpio "ScorpioTest" "" __Async__() function OnEnable(self) if not IsAddOnLoaded("Blizzard_BattlefieldMap") then -- Waiting the target addon is loaded -- The ADDON_LOADED's argument is the addon name that loaded while NextEvent("ADDON_LOADED") ~= "Blizzard_BattlefieldMap" do end end -- start init the addon end ``` -------------------------------- ### Secure Hooking with Custom Handler Name Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md Demonstrates using `__SecureHook__` with a string argument to specify the target function name, allowing the handler function to have a different name (e.g., `Hook_ChatEdit_OnEditFocusGained`). ```Lua __SecureHook__ "ChatEdit_OnEditFocusGained" function Hook_ChatEdit_OnEditFocusGained(self) print("Start input text") end ``` -------------------------------- ### Scorpio Deeply Nested Module Initialization Source: https://github.com/kurapica/scorpio/blob/master/Docs/001.addon.md This snippet showcases the flexibility of the Scorpio module system to create deeply nested module structures. There is no practical limit to the depth of module nesting. ```Lua Scorpio "ScorpioTest.ModuleA.SubModuleA.SubModuleB.SubModuleC" "1.0.0" ```