Wiki

Clone wiki

nota / doc / noe / NOE_module

NOE module rules


Purpose of modules

  • Each module adds some functionality in our framework
  • Allows us to easily add/remove functionality
  • Split work in smaller pieces, which are easy to maintain and improve
  • Can serve as config file

Header

Each module needs machine readable header, which provide some data about given module.

Mandatory items

  • name - suggested value some Lower-CamelCase name - e.g.: moduleName
    • if its part of some bigger technology (set of similar modules, family of related files), we add underscored prefix before module name - e.g.: newTech_moduleName
  • desc - description in human language what module does
  • author - name of person which did the implementation in this file, can contain more names
    • here should be listed just people doing the implementation, not fixers or rafactoring (those people can be added in comment after it)
  • date - date of creation of given item
    • sugested syntax is YYYY-MM-DD
  • license - always notAalicense

Example

local moduleInfo = {
    name     = "messageConvertor",
    desc     = "SpringExtra extension for sending messages of various types",
    author   = "PepeAmpere", -- refactored by Thor, fixes by a1983
    date     = "2015-05-12",
    license  = "notAlicense",
}

Includes (optional)

Other modules

You are allowed and encouraged to use other modules content.

include "LuaRules/Configs/noe/modules/core/noe_string.lua"

Local functions in module

There can be also some local helping functions, which are part of module definitions, but they cannot be called outside of module. It is allowed, but you are encouraged to put anything which can be reused somewhere in own module.


Content

Content of module can be various, we have two basic groups of modules:

  • function libraries
  • configs

Which in real life works the same way because function is just another config data type for us in Lua ;).

Rules

  • Usually there is some list of items we want to provide in our module, e.g. functions - we do it be defining some local list of items with prefix new.
    • This helps us if we have more files adding items to same module, we can add new items or create variant definitions.
  • For definition of item we use syntax which put item name in quotation marks - so for example we use:
newModule["functionOne"] = function() .. end

instead of other (valid) option:

newModule.functionOne = function() .. end
  • Each item have to had description in comment - what given item does - usually longer = better.
  • Each item should have usually 5-20 lines, 50 lines is maximum and it is extraordinary.
    • If its hard to fit this rule, you should think about splitting item into smaller pieces.
  • Whole content of of module should have around 50-300 lines.
    • If module has more than 500 lines, PepeAmpere can be suspicious and may let your rework the module (again, split in smaller pieces).

Example

local newMathFunctions = {
    ["GetDistance2D"] = function(firstX,firstZ,secondX,secondZ)  
        -- returns 2D distance of two places
        return math.sqrt((firstX - secondX)*(firstX - secondX) + (firstZ - secondZ)*(firstZ - secondZ))
    end,
    ["ToBool"] = function(something)  
        -- converts different values input into bool if possible and returns it
        if (something == 0 or something == "false" or something == "0" or something == false or something == nil) then
            return false
        else
            return true
        end
    end,
}

Module loader

This piece of code save each item defined in some higher level library or config list.

Rules

  • We use local list of functions or configs (with prefix new) and save it to global structure without the prefix (which is used then for referencing given functionality or value)
  • There is check for each item addition to notify overwriting of items with same key values. This safety logging of overwrites is mandatory, but sometimes we can use it to rewrite some configs by new module for development or testing needs.

Example

So for items in example above i would have this loader:

-- update global tables 
if (MathFunctions == nil) then MathFunctions = {} end
for k,v in pairs(newMathFunctions) do
    if (MathFunctions[k] ~= nil) then Spring.Echo("NOTIFICATION: Attempt to rewrite global table in module [" .. moduleInfo.name ..  "] - key: " .. k) end
    MathFunctions[k] = v 
end

Final module file

Take as finished example our file messageConvertor expanding our SpringExtra library.

Updated