CThread: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
mNo edit summary
Line 1: Line 1:
{{Useful Class}}
{{Useful Class}}
{{Needs_Example}}
<lowercasetitle/>
<lowercasetitle/>
__NOTOC__
__NOTOC__

Revision as of 18:37, 23 February 2015


This class implements the lua coroutines and can be used to limit method calls to a specific amount / second. This can be very useful when loading big amounts of data on gamemode startup to avoid an infinite running script and termination.

Requirements

Knowledge

Code

--
-- Created by IntelliJ IDEA.
-- User: Noneatme
-- Date: 25.01.2015
-- Time: 14:33
--

cThread = {}
cThread.__index     = cThread;


Threads     = {}


function cThread:new(...)
    local obj = setmetatable({}, {__index = self});
    if obj.constructor then
        obj:constructor(...);
    end
    return obj;
end

function cThread:constructor(sName, func, iAmmounts)
    assert(Threads[sName] == nil);
    self.name = sName
    self.func = func

    self.iAmmounts = iAmmounts or 1;
--  outputConsole("[TRHEAD: "..sName.."] Constructor");

    Threads[sName]  = self;
end

function cThread:start(iMS)
    self.thread = coroutine.create(self.func)
    self.yields = 0;

    self.lastTickCount  = getTickCount();

    self:resume()

    self.timer  = setTimer(function()
        if(self:status() == "suspended") then
            if(getTickCount()-self.lastTickCount > 5000) then
                self.lastTickCount = getTickCount();
 --             outputConsole("[THREAD: "..self.name.."] Current Yields: "..self.yields);
            end
            for i = 1, self.iAmmounts, 1 do
                self.yields = self.yields+1;
                self:resume();
            end
        end

        if(self:status() == "dead") then
            killTimer(self.timer);
            self:stop()
        end
    end, iMS, -1)
end

function cThread:resume()
    coroutine.resume(self.thread)
end

function cThread:stop()
    self.thread = nil

--  outputConsole("[THREAD: "..self.name.."] Completed, Yields: "..self.yields);
end

function cThread:status()
    return coroutine.status(self.thread)
end

Example

This example shows an UserVehicleManager class combined with a Thread which loads all vehicles from a specific database table on server startup.

Click to collapse [-]
Example
local CUserVehicleManager = inherit(cSingleton)

function CUserVehicleManager:createVehicles()
    local result = CDatabase:getInstance():query("SELECT * FROM user_vehicles;")           -- Big amount of data (> 10000 rows)
    if(result) and (#result > 0) then       -- Are there any vehicles?
        for index, row in pairs(result) do  -- Loop through the resultset
            Vehicle(unpack(row));           -- Create the Vehicle
            coroutine.yield()               -- Yield back to the thread manager, without the coroutine, the script will abort the loop (infinite running script)
        end
    end
end

function CUserVehicleManager:constructor()
    self.loadFunc		= function() self:createVehicles() end      -- The coroutine main loop function
    self.thread			= cThread:new("User Vehicle Loading Thread", self.loadFunc, 5) -- Limit to 5 yields / call
    self.thread:start(50);                                          -- Begin the loading process, limited to 5 yields / 50 miliseconds
end

See Also

  • Singleton » This class allows to restrict the instantiation of a specific class to one object.
  • CThread » This class represents a simple coroutine manager which can be used to limit method calls / loop.
  • Importer » This class make easy to use exported functions.
  • Observable » Observable variables. Call function on variable value change.
  • MatrixPOP » This class allows to use simple matrix without using MTA's OOP functions