开源软件名称(OpenSource Name):Olivine-Labs/mediator_lua开源软件地址(OpenSource Url):https://github.com/Olivine-Labs/mediator_lua开源编程语言(OpenSource Language):Lua 92.0%开源软件介绍(OpenSource Introduction):mediator_luaVersion 1.1.2 For more information, please see If you have luarocks, install it with A utility class to help you manage events.mediator_lua is a simple class that allows you to listen to events by subscribing to
and sending data to channels. Its purpose is to help you decouple code where you
might otherwise have functions calling functions calling functions, and instead
simply call Why?My specific use case: manage HTTP routes called in OpenResty. There's an excellent article that talks about the Mediator pattern (in Javascript) in more in detail by Addy Osmani (that made me go back and refactor this code a bit.) UsageYou can register events with the mediator two ways: using channels, or with a predicate to perform more complex matching (a predicate is a function that returns a true/false value that determines if mediator should run the callback.) Instantiate a new mediator, and then you can being subscribing, removing, and publishing. Example: Mediator = require "mediator_lua"
mediator = Mediator() -- instantiate a new mediator
mediator:publish(channel, <data, data, ... >)
mediator:remove(<channel>) Subscription signature: (channel, callback, <options>, <context>); Callback signature: function(<data, data ...>, channel); Mediator:subscribe {
predicate = function(arg1, arg2) return arg1 == arg2 end
priority = 0|1|... (array index; max of callback array length, min of 0)
} When you call {
id, -- unique identifier
fn, -- function you passed in
options, -- options
context, -- context for fn to be called within
channel, -- provides a pointer back to its channel
update(options) -- function that accepts { fn, options, context }
} Examples: Mediator = require("mediator_lua")
local mediator = Mediator()
-- Print data when the "message" channel is published to
-- Subscribe returns a "Subscriber" object
mediator:subscribe({ "message" }, function(data) print(data) end);
mediator:publish({ "message" }, "Hello, world");
>> Hello, world
-- Print the message when the predicate function returns true
local predicate = function(data)
return data.From == "Jack"
end
mediator.Subscribe({ "channel" }, function(data) print(data.Message) end, { predicate = predicate });
mediator.Publish({ "channel" }, { Message = "Hey!", From = "Jack" })
mediator.Publish({ "channel" }, { Message = "Hey!", From = "Drew" })
>> Hey! You can remove events by passing in a type or predicate, and optionally the function to remove. -- removes all methods bound to a channel
mediator:remove({ "channel" })
-- unregisters MethodFN, a named function we defined elsewhere, from "channel"
mediator:remove({ "channel" }, MethodFN) You can call the registered functions with the mediator:publish({ "channel" }, "argument", "another one", { etc: true }); # args go on forever You can namespace your subscribing / removing / publishing. This will recurisevely call children, and also subscribers to direct parents. mediator:subscribe({ "application:chat:receiveMessage" }, function(data){ ... })
-- will recursively call anything in the appllication:chat:receiveMessage namespace
-- will also call thins directly subscribed to application and application:chat,
-- but not their children
mediator:publish({ "application", "chat", "receiveMessage" }, "Jack Lawson", "Hey")
-- will recursively remove everything under application:chat
mediator:remove({ "application", "chat" }) You can update Subscriber priority: local sub = mediator:subscribe({ "application", "chat" }, function(data){ ... })
local sub2 = mediator:subscribe({ "application", "chat" }, function(data){ ... })
-- have sub2 executed first
mediator.GetChannel({ "application", "chat" }).SetPriority(sub2.id, 0); You can update Subscriber callback, context, and/or options: sub:update({ fn: ..., context = { }, options = { ... }) You can stop the chain of execution by calling channel:stopPropagation() -- for example, let's not post the message if the `from` and `to` are the same
mediator.Subscribe({ "application", "chat" }, function(data, channel)
-- throw an error message or something
channel:stopPropagation()
end, options = {
predicate = function(data) return data.From == data.To end,
priority = 0
}) TestingUses lunit for testing; you can install it through luarocks. ContributingBuild stuff, run the tests, then submit a pull request with comments and a description of what you've done, and why. LicenseThis code and its accompanying README and are MIT licensed. In ClosingHave fun, and please submit suggestions and improvements! You can leave any issues here, or contact me on Twitter (@ajacksified). |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论