esi-class

Base class for object oriented programming in lua This library shall be used for each library where object orientation makes sense.

Basic Concept

This library incorportes different concepts required for object oriented Programming, while still keeping memory foodprint and performance in mind.

Inheritance

Inheritance is currently limited to simple direct inheritance, there is currently no possibility to inherit from more than one class. Creating a new class is done by calling the "__EXTEND__" methode on a CLASS. This methods requires a name and may take a property template (the class declaration). But it is also possible to add class members after the definition of the class itself.

Example

-- create an new class, whith only class varaibles and default __INIT__ function
local ESI_CLASS = require("esi-class")
local myClass = ESI_CLASS:__EXTEND__("myClass", {
propertyA = "a", -- class varibale
propertyB = "b"  -- class variable
})
function myClass:GET_A()
return self.propertyA
end
function myClass:GET_B()
return self.propertyB
end
local instance1 = myClass() -- create an instance
local instance2 = myClass() -- create an instance
local a1 = instance1:GET_A()
local a2 = instance2:GET_A()
local b1 = instance1:GET_B()
local b2 = instance2:GET_B()
local aClass = myClass:GET_A()
local bClass = myClass:GET_B()
return {aClass= aClass, bClass= bClass, a1=a1,a2=a2, b1=b1, b2=b2 }

Example

-- create an new class, whith it's own init funtion
local ESI_CLASS = require("esi-class")
local SUBTYPE = require("esi-subtype")
local TOOL = require("esi-tool")
local myClass = ESI_CLASS:__EXTEND__("myClass", {
    __INIT__ = function(class, template)
        -- copy constructor
        if SUBTYPE.get(template) == class:__GET_CLASSNAME__() then
            return TOOL:DEEPCOPY(template, 0)
        else
            -- regular constructor
            -- declaration ( with default value )
            local obj = {
                a = "unknown",
                b = "unknown"
            }
            -- initialization by template input.
            obj.a= template.a or obj.a
            obj.b= template.a or obj.b
            return obj
        end
    end
})
function myClass:GET_A()
    return self.a
end
function myClass:GET_B()
    return self.b
end

-- create some instances of myClass
local instance1 = myClass({a=1, b=2})  -- create an 1st instance
local instance2 = myClass({a=3, b=4})  -- create an 2nd instance
local instance3 = myClass(instance1)   -- copy constructor

return { instance1, instance2, instance3 }

Objects

Object are created by calling the CLASS object. Internally this first calls the "__INIT__" methode and then the "__SET_CLASS__ methode. As "__SET_CLASS__" should be suitable for most classe, only the "__INIT__" methode has to be defined for a new class. The name ase well as the behaviour are inspired by python, and should be used in a similar way.

HINT: Don’t define function or any other lua object, which is not JSON serializable in the object which is returned by the __INIT__ function. Functions shall always be defined as a property of the class ( either as input to the __EXTEND__ method or defined later).

Underlying Architecture: The idea of this whole inheritance is, that each object is a LuaTable on it’s own rights. All class specific content like "__className", "__parent" and all functions on can call on this object are in the metatable. This is achieved, by assigning the class of an object to the __index entry. So the __index of each object points to it’s class and thus allows to access everything which was defined on that class. But the class is a object on it’s own rights as well, which also has an metatable and also has an __index entry, but this points to the parent class. That way inheritance is realised, by following the chain of __index calls automatically done by lua. In oder to create (inherit) a new class the __EXTEND__ function must be called on the base class. As part of this extention, an __INIT__ function should be defined for that class ( similar to python ), this function actually initializes the objects and defines all object specific data. The object defined in the __INIT__ function should be JSON serializable (no functions). In additiona to the __INIT__ function, a __SET_CLASS__ function exists, but this is inherited from esi-class automatically and should not be touched. ( exceptions exist ) If an new object is instanciated, the __INIT__ function of the class is called to create the LuaTable (content) which is not a "object" yet, and then the __SET_CLASS__ function is called to initialize all metatable related entries, which form the "object" character. That happens automatically behind the scenes by the __call function. ( this was added to the metatable of the newly created class by the __EXTEND__() function )

Dependencies

library version inmation core library

debug

1.0.0

yes

rapidjson

0.6.0

yes

esi-tool

1.0.0

yes

esi-subtype

1.0.0

yes

Available functions

All functions have to be called according to the ESI standard, using colons, e.g. lib:FUNCTIONNAME(params)

Documentation

VERSION()

VERSION returns the version of the library / class

Returns

returns the version of the library / class

Usage

local version = CLASS:VERSION()

MODULE()

MODULE returns the modulename of the library / class

Returns

returns the modulename of the library / class

Usage

local version = CLASS:MODULE()

SET_DEBUG(on)

SET_DEBUG sets or resets the _debug flag

Parameters

on

set to on, when true

Returns

sets or resets the _debug flag

Usage

local version = CALSS:SET_DEBUG(true)

SET_LOG(on)

SET_LOG sets or resets the _log flag

Parameters

on

set to on, when true

Returns

sets or resets the _log flag

Usage

local version = CALSS:SET_LOG(true)

_LOG_ERROR(topic,detail)

Log error message

creates an error entry via syslib.log if logging is enabled by SET_LOG(true).

Parameters

topic

the current scope / topic

detail

details for the log message

traceOn

if true or nil, enabled the traceback in the error message.

Returns

returns nothing

Usage

local esi_lib = require "esi-class"
local myClass = esi_lib:__EXTEND__("myClass")
local object = myClass()
object:SET_LOG(true)
object:_LOG_ERROR("Current Area", "Something went wrong ...") -- with traceback
object:_LOG_ERROR("Current Area", "Something went wrong ...", false) -- without traceback

_LOG_WARN(topic,detail) \{#LOG_WARN}

Log warn message

creates an warn entry via syslib.log if logging is enabled by SET_LOG(true).

Parameters

topic

the current scope / topic

detail

details for the log message

Returns

returns nothing, but creates log entry.

Usage

object:_LOG_WARN("Current Area", "Warning: something is wrong ...")

_LOG_INFO(topic,detail)

Log info message

creates an info entry via syslib.log if logging is enabled by SET_LOG(true).

Parameters

topic

the current scope / topic

detail

details for the log essage

Returns

returns nothing, but creates log entry.

Usage

object:_LOG_INFO("Current Area", "Info: something is wrong ...")

_LOG_DEBUG(topic,detail)

Log debug messages

creates an debug entry via syslib.log if logging is enabled by SET_LOG(true) and debug is enabled via SET_DEBUG(true).

Parameters

topic

the current scope / topic

detail

details for the log essage

Returns

returns nothing, but creates log entry.

Usage

object:_LOG_DEBUG("Current Area", "Debug: started activity ...")

_ASSERT(condition,error_message)

ASSERT

this is an local assert function, calls a assert if debugging was enabled via SET_DEBUG(true). otherwise it only checks the assertion and creates an error entry if the assertion is false.

Parameters

condition

value or condition which is evaluated

error_message

message shown if condition is false

Returns

nothing

Usage

object:_ASSERT(false, "this is never true")
initObj

static initialisation object

Returns

initializes object

__SET_CLASS__(class)

Set the class related properties if the object (self)

only used during construction of objects

Parameters

class

the class the object shall belong to.

Returns

object with metatable entries

__GET_CLASS__()

Get Class object of a member object

Returns

class object linked to an object.

__SUPER__()

Get the super class

get the super class of a class. to get the super class of an object you have to call GET_CLASS() first.

Returns

super class

__EXTEND__(parent,name,classProperties)

Extend an existing class definitions

this should be called on a CLASS object, or inherited from a class.

Parameters

name

name of the new class

classProperties

Returns

new class of type

Usage

local newClass = CLASS:__EXTEND__("MyNewClass", {NewProperty1= 1})

__GET_CLASSNAME__()

Get classname of an object or a class

Returns

Classname or ""

Usage

CLASS:__GET_CLASSNAME__()