Wire Expression2 Extension Tutorial
From GMod Wiki
| This article describes how to make extensions for Wiremod's Expression 2 Gate. | |
| TomyLobo | |
| | 2009-06-13 |
Contents |
Introduction
The Wire Expression 2 Gate (E2 from now on) comes with a mechanism to load custom extensions, which can provide new functions and data types to the user.
E2 loads those extensions from the following folders:
-
garrysmod/addons/wire/lua/entities/gmod_wire_expression2/core/custom -
garrysmod/addons/<your_addon>/lua/entities/gmod_wire_expression2/core/custom -
garrysmod/lua/entities/gmod_wire_expression2/core/custom
It doesn't matter into which one you put it, but you probably shouldn't pick #3.
Extensions starting with "cl_", like "cl_renderer.lua", will be executed on the client instead of the server.
Your first function
The first, and easiest thing you'll probably do is add a new function to E2.
As a first example, we'll make a function that takes no arguments, returns nothing and does nothing:
e2function void doNothing() -- do nothing end
Now what does all this mean?
-
e2function- This tells it that this is an E2 function and should be treated accordingly. -
void- This is the return type of the function. In this case, it's a special type called "void", which means it doesn't return anything. More... -
doNothing- The function can be called from E2 by exactly that name:doNothing() -
()- An argument list. It's empty for now, but it could also contain a list of arguments you expect for your function. More... -
end- The end of the function.
Return values
Such a function is of course pretty boring, so we might want it to do more in it than just nothing.
A function can return any of the types registered by any other E2 extension. A list of types registered by the extensions that come with wiresvn can be found below.
The return type is put between "e2function" and the name of the function, in place of the "void" in the previous example.
To demonstrate this we'll make a function that will return the square root of π:
e2function number sqrtPi() return math.sqrt(math.pi) end
What's new here is that our function now has a return type, number.
We also return the result of sqrt(pi), just like we would in Lua.
Arguments
Of course you might want to make functions that take arguments as well.
Arguments are written as a comma-separated list or pairs of data type and argument name.
This time we write a function that sets the position and orientation of an entity:
e2function void setPosAng(entity foo, vector bar, angle baz) if not validEntity(foo) then return end bar = Vector(bar[1], bar[2], bar[3]) baz = Angle(baz[1], baz[2], baz[3]) foo:SetPos(bar) foo:SetAngles(baz) end
Now this does a bit more:
- The first line is the function signature again. This time the argument list is not empty, but contains 3 arguments:
- An
entitynamed "foo" - A
vectornamed "bar" - An
anglenamed "baz"
- An
- The next 3 lines check the entity validity and translate the arguments into gmod-compatible format. See below for details.
- The final 2 lines do the actual work.
Methods
In some cases, you might want to signal that your function retrieves a property of a value does something with that value, instead of merely taking it as input.
In that case, you might prefer making your function a method of that value's data type.
It will then be called like this: E:setPosAng(Pos, Ang)
You can define such a method by prefixing the data type, followed by a colon(:) to the function name:
e2function void entity:setPosAng(vector bar, angle baz) if not validEntity(this) then return end bar = Vector(bar[1], bar[2], bar[3]) baz = Angle(baz[1], baz[2], baz[3]) this:SetPos(bar) this:SetAngles(baz) end
The only thing that changed from the previous version is that the entity is now passed before the method operator(:).
An argument passed that way is implicitly named "this". You can use it just like any other function argument.
Overloading
In E2, every function has 3 important properties:
- a name
- a list of arguments, including the one before the method operator (
:) - a return type
E2 allows function overloading. This means that you can have multiple functions with the same name as long as they dont have the same set of argument types.
This makes functions like signalClk() possible, which accept many kinds of arguments.
Examples
(none yet, see bone.lua for some examples.)
Reference
Types
None of them can be nil, unless noted otherwise. Examples: entity, bone, wirelink, ranger
Type name Type ID Description Example number N Numbers, lots of them... This is the default type for arguments if the type is left out. 123string S A string of characters, a piece of text. "abc"array R A Lua table with only numeric indexes. { 1, "b", 3, 4, Entity(5) }table T A Lua table with only string indexes. Keys are prefixed with the element's typeid in lowercase. { ["sHello"] = "World" }entity E An entity. Can be nil and should be checked with the "validEntity" function. ents.GetByIndex(1)angle A A Lua table consisting of 3 numeric indexes representing pitch, yaw and roll. { 90, 60, 90 }vector2 XV2 A numeric Lua table representing a 2D vector. { 1, 2 }vector V Either a numeric Lua table representing a 3D vector or a GMod Lua Vector. { 1, 2, 3 }Vector(1, 2, 3)vector4 XV4 A numeric Lua table representing a 4D vector. { 1, 2, 3, 4 }matrix2 XM2 A numeric Lua table representing a 2x2 matrix in row-major order { 11, 12, 21, 22 }matrix M Like matrix2, just 3x3. Like matrix2, just 9 elements. matrix4 XM4 Like matrix2, just 4x4. Like matrix2, just 16 elements. bone B A PhysObj. Can be nil and should be checked with the "isInvalidBone" ents.GetByIndex(1):GetPhysicsObject()wirelink XWL An entity. Can be nil and should be checked with the "validEntity" function.
You should also check whether it has a non-nil member named "extended".ents.GetByIndex(123)ranger XRD A TraceRes structure or nil ents.GetByIndex(1):GetEyeTrace()complex C A numeric Lua table representing a complex number. { 1, 2 }quaternion Q A numeric Lua table representing a quaternion. { 1, 2, 3, 4 }
