What's new

-Łatwy Metatables

Dantez

Moim sekretem jest ciasto
Joined
May 22, 2008
Messages
1,206
Reaction score
202
Autor: Dantez

Rozdzia? 1 - Metamethods

Metamethod to funkcja, kt?ra zostaje wywo?ana, kiedy okre?lona operacja zostaje wykonana na tabeli. Ich dodatkow? specjaln? w?a?ciwo?ci? jest to, ?e wszystkie zaczynaj? si? od dw?ch znak?w "_". Istnieje kilka metamethod, kt?re mo?emy wykorzysta? do modyfikowania dzia?ania tabel, ich dzia?anie mo?emy znale?? np. .

  • __index
  • __newindex
  • __add
  • __sub
  • __mul
  • __div
  • __mod
  • __pow
  • __unm
  • __eq
  • __lt
  • __lt
  • __le
  • __le
  • __call
  • __concat
  • __tostring
  • __len
  • __mode
  • __metatable
  • __gc


Rozdzia? 2 - Metatable
Metatable to nic innego, jak tabela, kt?ra zawiera metamethody. W takiej postaci mo?emy j? zaaplikowa? do tabeli poprzez funkcj? setmetatable.

[LUA]Position = {}
PositionMT = {}

setmetatable(Position, PositionMT)[/LUA]

Mo?emy r?wnie? uzyska? dost?p do metatable danej tabeli poprzez funkcj? getmetatable.

[LUA]Position = {}
PositionMT = {}

setmetatable(Position, PositionMT)
local mt = getmetatable(Position)

-- mt zawiera teraz tabel? PositionMT[/LUA]


Rozdzia? 3 - __index i __newindex

Napiszmy teraz przyk?adowy kod, w kt?rym wykorzystamy metametody __index i __newindex. Pierwszy z nich jest wykonywany, gdy pr?bujemy odwo?a? si? do elementu tabeli, drugi za? podczas, gdy pr?bujemy nowy element stworzy?.

[LUA]Position = {}
PositionMT = {}

PositionMT.__newindex = function(self, index, value)
print("__newindex:", index, value)
end

PositionMT.__index = function(self, index)
print("__index:", index)
return true
end

setmetatable(Position, PositionMT)

Position.x = 10

local a = Position.x
local b = Position[4]
local c = Position["Dantez"]

print(type(a))[/LUA]
Code:
__newindex:	x	10
__index:	x
__index:	4
__index:	Dantez
boolean


Dziej? si? dwie ciekawe rzeczy:
1) Position.x = 10 nie zmienia warto?ci w tabeli
2) Position.x, Position[4] i Position["Dantez"] zwracaj? true

Problem z __index i __newindex polega na tym, ?e gdyby?my chcieli zwr?ci? lub zmieni? realne warto?ci dla tabeli poprzez "." (kropk?) lub "[]" (nawiasy kwadratowe) to spowodujemy zap?tlenie owych funkcji. Z pomoc? przychodz? funkcje rawset i rawget, kt?re niejako omijaj? ponowne wykonywanie __index i __newindex.

[LUA]Position = {}
PositionMT = {}

PositionMT.__newindex = function(self, index, value)
rawset(self, index, value)
end

PositionMT.__index = function(self, index)
return rawget(self, index)
end

setmetatable(Position, PositionMT)

Position.x = 10
local a = Position.x

print(a) -- -> 10[/LUA]


Rozdzia? 4 - __tostring i __concat
Metametoda __tostring wykonywana jest, gdy u?ywamy funkcji tostring(), natomiast __concat wykonywane jest podczas pr?by przy??czenia tabeli do stringu poprzez "..". Przejd?my od razu do przyk?adu.

[LUA]Position = {x = 0, y = 0, z = 0, stackpos = 0}
PositionMT = {}

PositionMT.__tostring = function(self)
return "{x= " .. self.x .. ", y= " .. self.y .. ", z= " .. self.z .. ", stackpos= " .. self.stackpos .. "}"
end

PositionMT.__concat = function(self, value)
if(self.stackpos ~= nil) then
return tostring(self) .. value
else
return self .. tostring(value)
end
end

setmetatable(Position, PositionMT)

print(Position .. " to moja pozycja")
print("Moja pozycja to: " .. Position)
print("Pozycja: " .. tostring(Position))[/LUA]
Code:
{x= 0, y= 0, z= 0, stackpos= 1} to moja pozycja
Moja pozycja to: {x= 0, y= 0, z= 0, stackpos= 1}
Pozycja: {x= 0, y= 0, z= 0, stackpos= 1}

Sama funkcja __tostring powinna by? zrozumia?a, jednak w __concat dzieje si? troszk? wi?cej. Nie jeste?my w stanie okre?li? jakiego dok?adnie 'typu' b?dzie dany parametr, zawsze zwr?cone zostan? nam typy podstawowe jak np. string, czy table. Funkcja __concat zak?ada, ?e pierwszym parametrem b?dzie tabela, do kt?rej jest przypisana. Aby ??czenie string?w dzia?a?o w obie strony, mo?na sprawdza?, czy dany parametr to tabela lub czy posiada kt?ry?/wszystkie z element?w Position. Nie jest to dok?adne, w pewnych przypadkach nie zadzia?a, ale zawsze mo?na u?ywa? tostring().


Rozdzia? 5 - Podsumowanie
Metatables bardzo u?atwiaj? prace nad skryptami, poniewa? mo?na ich potem u?ywa? wielokrotnie. Oto prosty przyk?ad, jak mo?na je wykorzysta?:

[LUA]Position = {}
Position.__index = Position;

function Position.new(x, y, z, stackpos)
return setmetatable({x = x or 0, y = y or 0, z = z or 0, stackpos = stackpos or 0}, Position)
end

function Position.__add(self, other)
if(type(other) == "table") then
return Position.new(self.x + (other.x or 0), self.y + (other.y or 0), self.z + (other.z or 0), self.stackpos)
else
return self
end
end

function Position.__sub(self, other)
if(type(other) == "table") then
return Position.new(self.x - (other.x or 0), self.y - (other.y or 0), self.z - (other.z or 0), self.stackpos)
else
return self
end
end

function Position.__tostring(self)
return "{x=" .. self.x .. ", y=" .. self.y .. ", z=" .. self.z .. ", stackpos=" .. self.stackpos .. "}"
end

function Position.__concat(self, value)
if(self.stackpos ~= nil) then
return tostring(self) .. value
else
return self .. tostring(value)
end
end

setmetatable(Position, { __call = function(_, ...) return Position.new(...) end })

-- Testing

local pos1 = Position(30, 50, 60, 1)
local pos2 = Position.new(90, 10, 80, 55)

print(pos1, pos2)

pos1 = pos1 + {x=40, y=90}
pos2 = pos2 - {x=1, z=2}

print(pos1, pos2)[/LUA]
 

Arkam

Forum friend
Joined
Dec 20, 2008
Messages
1,980
Reaction score
180
Odp: TFS 1.0 scripting

Odp: TFS 1.0 scripting

Chocia? w?tpi?, ?e przekonasz kogo? tym na przeskok do 1.0 to i tak ogromny + za wk?ad :)
 

Skleja

Advanced User
Joined
Oct 22, 2009
Messages
355
Reaction score
4
Odp: TFS 1.0 scripting

Odp: TFS 1.0 scripting

Oj przyda si? Przyda.. Wielki + za Wprowadzenie
 

Govern

Advanced User
Joined
Jun 6, 2011
Messages
308
Reaction score
35
Odp: TFS 1.0 scripting

Odp: TFS 1.0 scripting

Przydatne, osobi?cie pracuj? na TFS 1.0 i jestem bardzo zadowolony, wszystko ?miga nale?ycie. Kilka zmian jest, ale nie a? takich aby rezygnowa? z ca?ego projektu Marka.
 

Govern

Advanced User
Joined
Jun 6, 2011
Messages
308
Reaction score
35
Odp: TFS 1.0 scripting

Odp: TFS 1.0 scripting

Czy du?o bardziej czytelniejszy to nie wiem, nie zag??bia?em si? a? tak w kod. Dla os?b, kt?re potrafi?y zrobi? tylko download & run to jest on du?ym k?opotem, poniewa? trzeba nauczy? si? czego? nowego -.-
 

Gitu123

Senior User
Joined
Jun 25, 2009
Messages
700
Reaction score
22
Odp: TFS 1.0 scripting

Odp: TFS 1.0 scripting

Akurat mam serwer pod tfs 1.0. Skrypty praktycznie nie uleg?y zmianie, mo?na si? bardzo ?atwo przerzuci? z tfs 0.3.7 na tfs 0.1. I mog? nawet powiedzie?, ?e ten jest bardzoo stabilny :D

Chociaz nie ukrywam, jest pare ra??cych b?ed?w, ale mozna je latwo poprawic
 

Dantez

Moim sekretem jest ciasto
Joined
May 22, 2008
Messages
1,206
Reaction score
202
Odp: TFS 1.0 scripting

Odp: TFS 1.0 scripting

Akurat mam serwer pod tfs 1.0. Skrypty praktycznie nie uleg?y zmianie, mo?na si? bardzo ?atwo przerzuci? z tfs 0.3.7 na tfs 0.1. I mog? nawet powiedzie?, ?e ten jest bardzoo stabilny :D

Chociaz nie ukrywam, jest pare ra??cych b?ed?w, ale mozna je latwo poprawic
Skrypty uleg?y ogromnej zmianie, lecz dzi?ki plikowi compat.lua, TFS jest cz??ciowo kompatybilny wstecz i dla zwyk?ego amatora nie ma wielkiej r??nicy.
 
Last edited:

Dantez

Moim sekretem jest ciasto
Joined
May 22, 2008
Messages
1,206
Reaction score
202
Odp: Metatables

Zmieni?em kilka rzeczy.
 

Uxi

Advanced User
Joined
Feb 9, 2015
Messages
291
Reaction score
6
Odp: Metatables

zrobi ktos tfs 1.0 64 bit na 8.6?
 

Dubler

Lua Factory =)
Joined
Apr 8, 2009
Messages
1,874
Reaction score
112
Odp: Metatables

Ca?o?? ma sens kiedy zrobimy sobie prototypowe tablice obiektowo i potem mo?na z tego korzysta? => niesamowite przyspieszenie pracy i zwi?kszenie czytelno?ci. Dobrze wykonany poradnik :) Tego w starych tfsach 0.4 nie ma, nie? Niby metadane s? od lua 5.0
 
Last edited:

Dantez

Moim sekretem jest ciasto
Joined
May 22, 2008
Messages
1,206
Reaction score
202
Odp: Metatables

Tego w starych tfsach 0.4 nie ma, nie? Niby metadane s? od lua 5.0

S?, dobrym przyk?adem jest NpcHandler.

[LUA]function NpcHandler:new(keywordHandler)
local obj = {}
obj.callbackFunctions = {}
obj.modules = {}
if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
obj.focuses = {}
obj.talkStart = {}
else
obj.queue = Queue:new(obj)
obj.focuses = 0
obj.talkStart = 0
end
obj.talkDelay = {}
obj.keywordHandler = keywordHandler
obj.messages = {}
obj.shopItems = {}

setmetatable(obj.messages, self.messages)
self.messages.__index = self.messages

setmetatable(obj, self)
self.__index = self
return obj
end[/LUA]
 

Dubler

Lua Factory =)
Joined
Apr 8, 2009
Messages
1,874
Reaction score
112
Odp: Metatables

O, to super :) dzieki

Wytapane Z2 tapatalka
 
Top