From 9dafba50157086ff952bff9cbba774334caf190a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 9 Oct 2013 15:10:25 +0200 Subject: [PATCH] APIDump: Implemented basic hook documentation. --- MCServer/Plugins/APIDump/APIDesc.lua | 34 ++++++- MCServer/Plugins/APIDump/main.lua | 129 +++++++++++++++++++++++++-- 2 files changed, 152 insertions(+), 11 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c41cac51b..33e1da976 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2055,6 +2055,33 @@ World:ForEachEntity( }, }, + + Hooks = + { + HOOK_CHAT = + { + CalledWhen = "Player sends a chat message", + DefaultFnName = "OnChat", -- also used as pagename + Desc = [[ + A plugin may implement an OnChat() function and register it as a Hook to process chat messages from + the players. The function is then called for every in-game message sent from any player. Note that + commands are handled separately using a command framework API. + ]], + Params = { + { Name = "Player", Type = "{{cPlayer}}", Notes = "The player who sent the message" }, + { Name = "Message", Type = "string", Notes = "The message" }, + }, + Returns = [[ + The plugin may return 2 values. The first is a boolean specifying whether the hook handling is to be + stopped or not. If it is false, the message is broadcast to all players in the world. If it is true, + no message is broadcast and no further action is taken.

+

+ The second value is specifies the message to broadcast. This way, plugins may modify the message. If + the second value is not provided, the original message is used. + ]], + }, -- HOOK_CHAT + }, -- Hooks[] + IgnoreClasses = { @@ -2080,12 +2107,15 @@ World:ForEachEntity( "%a+.delete", -- AnyClass.delete -- Functions global in the APIDump plugin: - "Initialize", - "DumpAPITxt", "CreateAPITables", "DumpAPIHtml", + "DumpAPITxt", + "Initialize", + "LinkifyString", "ReadDescriptions", + "ReadHooks", "WriteHtmlClass", + "WriteHtmlHook", }, ExtraPages = diff --git a/MCServer/Plugins/APIDump/main.lua b/MCServer/Plugins/APIDump/main.lua index 5dd6c6f9e..6d4ac3d04 100644 --- a/MCServer/Plugins/APIDump/main.lua +++ b/MCServer/Plugins/APIDump/main.lua @@ -164,6 +164,8 @@ function DumpAPIHtml() LOG("Dumping all available functions and constants to API subfolder..."); local API, Globals = CreateAPITables(); + local Hooks = {}; + local UndocumentedHooks = {}; -- Sort the classes by name: table.sort(API, @@ -176,8 +178,21 @@ function DumpAPIHtml() Globals.Name = "Globals"; table.insert(API, Globals); + -- Extract hook constants: + for name, obj in pairs(cPluginManager) do + if (type(obj) == "number") and (name:match("HOOK_.*")) then + table.insert(Hooks, { Name = name }); + end + end + table.sort(Hooks, + function(Hook1, Hook2) + return (Hook1.Name < Hook2.Name); + end + ); + -- Read in the descriptions: ReadDescriptions(API); + ReadHooks(Hooks); -- Create the output folder if not(cFile:IsFolder("API")) then @@ -220,7 +235,16 @@ function DumpAPIHtml() for the event). See each hook's details to see the exact behavior.

]]); - -- TODO: Write out the hooks into a table + for i, hook in ipairs(Hooks) do + if (hook.DefaultFnName == nil) then + -- The hook is not documented yet + f:write("\n"); + table.insert(UndocumentedHooks, hook.Name); + else + f:write("\n"); + WriteHtmlHook(hook); + end + end f:write([[
Hook nameCalled when
" .. hook.Name .. "(No documentation yet)
" .. hook.Name .. "" .. hook.CalledWhen .. "

Extra pages

The following pages provide various extra information

@@ -286,6 +310,24 @@ function DumpAPIHtml() f:write("\t\t},\n\n"); end end -- for i, cls - API[] + f:write("\t},\n"); + + if (#UndocumentedHooks > 0) then + f:write("\n\tHooks =\n\t{\n"); + for i, hook in ipairs(UndocumentedHooks) do + if (i > 1) then + f:write("\n"); + end + f:write("\t\t" .. hook .. " =\n\t\t{\n"); + f:write("\t\t\tCalledWhen = \"\",\n"); + f:write("\t\t\tDefaultFnName = \"On\", -- also used as pagename\n"); + f:write("\t\t\tDesc = [[]],\n"); + f:write("\t\t\tParams =\n\t\t\t{\n"); + f:write("\t\t\t\t{ Name = \"\", Type = \"\", Notes = \"\" },\n\t\t\t},\n"); + f:write("\t\t\tReturns = [[]],\n"); + f:write("\t\t}, -- " .. hook .. "\n"); + end + end f:close(); end @@ -531,19 +573,46 @@ end +function ReadHooks(a_Hooks) + --[[ + a_Hooks = { + { Name = "HOOK_1"}, + { Name = "HOOK_2"}, + ... + }; + We want to add hook descriptions to each hook in this array + --]] + for i, hook in ipairs(a_Hooks) do + local HookDesc = g_APIDesc.Hooks[hook.Name]; + if (HookDesc ~= nil) then + for key, val in pairs(HookDesc) do + hook[key] = val; + end + end + end -- for i, hook - a_Hooks[] +end + + + + + +-- Make a link out of anything with the special linkifying syntax {{link|title}} +function LinkifyString(a_String) + local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", "%2") -- {{link|title}} + txt = txt:gsub("{{([^|}]*)}}", "%1") -- {{LinkAndTitle}} + return txt; +end + + + + + function WriteHtmlClass(a_ClassAPI, a_AllAPI) local cf, err = io.open("API/" .. a_ClassAPI.Name .. ".html", "w"); if (cf == nil) then return; end - -- Make a link out of anything with the special linkifying syntax {{link|title}} - local function LinkifyString(a_String) - local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", "%2") -- {{link|title}} - txt = txt:gsub("{{([^|}]*)}}", "%1") -- {{LinkAndTitle}} - return txt; - end - -- Writes a table containing all functions in the specified list, with an optional "inherited from" header when a_InheritedName is valid local function WriteFunctions(a_Functions, a_InheritedName) if (#a_Functions == 0) then @@ -584,7 +653,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI) CurrInheritance = CurrInheritance.Inherits; end - cf:write([[MCServer API - ]] .. a_ClassAPI.Name .. [[ + cf:write([[MCServer API - ]] .. a_ClassAPI.Name .. [[ class

Contents

@@ -664,3 +733,45 @@ end +function WriteHtmlHook(a_Hook) + local fnam = "API/" .. a_Hook.DefaultFnName .. ".html"; + local f, error = io.open(fnam, "w"); + if (f == nil) then + LOG("Cannot write \"" .. fnam .. "\": \"" .. error .. "\"."); + return; + end + f:write([[MCServer API - ]] .. a_Hook.DefaultFnName .. [[ hook + + +

]] .. a_Hook.Name .. [[ hook

+

+ ]]); + f:write(LinkifyString(a_Hook.Desc)); + f:write("

Callback function

function " .. a_Hook.DefaultFnName .. "(");
+	if (a_Hook.Params == nil) then
+		a_Hook.Params = {};
+	end
+	for i, param in ipairs(a_Hook.Params) do
+		if (i > 1) then
+			f:write(", ");
+		end
+		f:write(param.Name);
+	end
+	f:write(")

Parameters:\n\n"); + for i, param in ipairs(a_Hook.Params) do + f:write("\n"); + end + f:write("
NameTypeNotes
" .. param.Name .. "" .. LinkifyString(param.Type) .. "" .. LinkifyString(param.Notes) .. "

\n

" .. (a_Hook.Returns or "") .. "

\n"); + f:write([[

Code examples

+

Registering the callback

+
+cPluginManager.AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[);
+
+ ]]); + -- TODO: Other code examples + f:close(); +end + + + +