Table of Contents
This articles covers in-depth usage of lambda timers. If you haven't already seen basic usage in the syntax guide, you should do so before reading ahead.
Before learning about lambda timers, we strongly suggest you to learn about lambda functions, if you haven't already.
Introduction
Lambda timers (or callback timers) are useful concept in programming. Mainly in frontend and game development.
You'll often want to do something after a delay or repeatedly at an interval in E2. This is where timers come in.
The lambda timers came as a replacement for old timer system, which previously executed the whole global scope of e2 chip on each execution. That is not the way it should be done 😏
Basic
Lambda timers are constructs, which essentially have only few parts.
- Name > Name of the timer, by which you, later on, can interact with (stop/start/restart/etc)
- Delay > Delay, (IN SECONDS) with which should the timer be executed. The delay can never be below the tick interval.
- Repetitions > How many repetitions should the timer do before destroying itself? If less then 0 - timer will run indefinitely.
- Lambda function > The part that makes the lambda timer shine. Instead of re-running the whole e2 - lambda timer executes the passed lambda function.
Explanation on examples
Timers have a few forms, so let's look over them briefly.
let MyAction = function() {
print("Hi!")
}
timer(1, MyAction) # number delay, function callback
timer("my timer", 2, MyAction) # string name, number delay, function callback
timer("my other timer", 3, 1, MyAction) # string name, number delay, number repetitions, function callback
The first form creates a one-use, "anonymous" timer, which doesn't have an identifier. This is good for one-offs where you aren't concerned too much about controlling the timer. The first argument is the delay in seconds, which the second is the function to run after the timer is up.
The second form creates a one-use timer with a name. This lets you stop the timer prematurely or overwrite it. Consider if we did,
timer("my timer", 1, function() {
print("Hello!")
})
timer("my timer", 3, function () {
print("Hello again!")
})
Only the second timer ("Hello Again!"
) would execute, since you're using the same identifier, which gets overwritten.
Note
You do not have to have completely unique names for every timer in all your E2s; timer names are limited to the E2 itself.
Lastly, the third form has a name, delay in seconds, and the amount of repetitions. By default, timers only execute once. This lets you specify them to execute 5, 100, or more times. You can create an infinite timer by putting the number of repetitions as 0.
@outputs Lights
Lights = 1
timer("strobe", 0.5, 0, function() { # half-second timer that runs an infinite amount of repetitions
Lights = !Lights # Invert the value of Lights
})
Important
Timers are executed every server tick. For most servers (66-tick), that means ever timer is executed every 0.0152 seconds, the tick interval. If you need a timer to execute before another one, make sure that your delay is long enough. If your delay is below the tick interval, your timer will execute the next tick. The following code demonstrates two timers that actually execute at the same time.
@strict let TimeA = 0 let TimeB = 0 timer(0.011, function() { TimeA = curtime() if(TimeB) { print(TimeA == TimeB ? "Same time!" : "Different time!", TimeA) } } timer(0.01, function() { TimeB = curtime() if(TimeA) { print(TimeB == TimeA ? "Same time!" : "Different time!", TimeB) } }
Why use them?
I'm already used to the old timer system. Why are you forcing me to use lambda timers?
- Great question! While it may feel better to use something you're familiar with - we, as wiremod team, always trying to bring the best practices to all our elements. E2 included.
Thus, the old timer system forced the e2 chips to execute the global scope repeatedly, which is not the way it should've worked. New timers, in pair with @strict and @trigger none directives allows for conventional global scope programming. Similar, how you would do that in any other language.
Expression 2 ⚙️
Getting Started 🕊
- Syntax 🔣
- Directives 🎛️
- Editor 🖥️
- Ops 📊
Guides (In learning order) 🎓
- Learning & Getting Help 📚
- Triggers ⏲️
- Events 🎬
- Find Functions 🔍
- Physics 🚀
- EGP Basics 📈
- Lambdas λ
- Lambda Timers λ⏲️
- Tips & Tricks 📘
Tools 🛠️
Click To Expand
Advanced
- 🟥 SPU
- 🟥 Address Bus
- 🟥 Extended Bus
- 🟥 Plug/Socket
- 🟥 Port
- 🟥 Transfer Bus
- 🟩 GPU
- 🟥 Dynamic Memory
- 🟥 Flash EEPROM
- 🟥 ROM
Beacon 💡
- 🟧 Beacon Sensor
- 🟧 Locator
- 🟧 Target Finder
- 🟧 Waypoint
- 🟥 XYZ Beacon
Control 🎛️
- 🟩 CPU
- 🟩 Expression 2
- 🟩 Gates
- 🟥 PID
Data 💿
- 🟧 CD Disk
- 🟥 CD Ray
- 🟧 DHDD
- 🟥 Keycard
- 🟥 RAM-card
- 🟧 Satellite Dish
- 🟧 Store
- 🟧 Transferer
- 🟥 Wired Wirer
Detection 👀
- 🟧 Adv Entity Marker
- 🟧 Damage Detector
- 🟧 Entity Marker
- 🟧 GPS
- 🟧 Gyroscope
- 🟥 HighSpeed Ranger
- 🟧 Laser Pointer Receiver
- 🟥 Microphone
- 🟧 Ranger
- 🟧 Speedometer
- 🟧 Water Sensor
Display 💻
- 🟧 7 Segment Display
- 🟥 Adv. Hud Indicator
- 🟧 Console Screen
- 🟧 Control Panel
- 🟧 Digital Screen
- 🟧 EGP v3
- 🟧 Fix RenderTargets
- 🟥 GPULib Switcher
- 🟧 Hud Indicator
- 🟧 Indicator
- 🟧 Lamp
- 🟧 Light
- 🟧 Oscilloscope
- 🟧 Pixel
- 🟧 Screen
- 🟧 Sound Emitter
- 🟧 Text Screen
Render 🖌
- 🟩 Cam Controller
- 🟧 Colorer
- 🟧 FX Emitter
- 🟧 HighSpeed Holoemitter
- 🟧 HoloEmitter
- 🟧 HoloGrid
- 🟥 Interactable Holography Emitter
- 🟥 Materializer
- 🟥 Painter
I/O 🔌
- 🟧 Adv. Input
- 🟧 Button
- 🟧 Constant Value
- 🟥 Door Controller
- 🟧 Dual Input
- 🟧 Dynamic Button
- 🟧 Eye Pod
- 🟧 Graphics Tablet
- 🟧 Keyboard
- 🟥 Lever
- 🟧 Numpad
- 🟧 Numpad Input
- 🟧 Numpad Output
- 🟧 Plug
- 🟧 Pod Controller
- 🟧 Radio
- 🟧 Relay
- 🟧 Text Receiver
- 🟧 Two-way Radio
- 🟧 Vehicle Controller
Physics 🚀
- 🟥 Door
- 🟥 Adv. Dupe. Teleporter
- 🟥 Buoyancy
- 🟧 Clutch
- 🟧 Detonator
- 🟧 Explosives
- 🟧 Explosives (Simple)
- 🟥 Forcer
- 🟩 Freezer
- 🟧 Gimbal (Facer)
- 🟧 Grabber
- 🟧 Hoverball
- 🟧 Hoverdrive Controller
- 🟥 Hydraulic
- 🟧 Igniter
- 🟧 Nailer
- 🟩 Prop Spawner
- 🟥 Servo
- 🟥 Simple Servo
- 🟧 Thruster
- 🟥 Touchplate
- 🟥 Trail
- 🟩 Turret
- 🟩 User
- 🟥 Vector Thruster
- 🟥 Vehicle Exit Point
- 🟧 Weight (Adjustable)
- 🟧 Weld/Constraint Latch
- 🟥 Wheel
- 🟥 Wire Magnet
- 🟥 Wired Npc Controller
Utilities 🛠️
- 🟧 Debugger
- 🟥 GUI Wiring
- 🟥 Multi Wire
- 🟧 Namer
- 🟥 Simulate Data
- 🟩 Wiring
RFID 💳
- 🟥 Beam Reader
- 🟥 Implanter
- 🟥 Reader
- 🟥 Target Filter
- 🟥 User Reader
Wireless 🛜
Gates 🚥
Click To Expand
TBD
Extras 🔭
Please do not alter the e2 docs ...
pages manually.
They are autogenerated from the E2Helper. In the future, this will hopefully be its own dedicated website or tool.
Default Extensions
Basic Features: core, debug, number, selfaware,
string, timer
🌎 World: angle, color, find, ranger, sound,
🔣 Math: bitwise, complex, matrix, quaternion, vector, vector2/4
📦 Entities: bone, constraint, egp, entity, hologram, npc
👨 Players: chat, console, player, weapon
📊 Data storage: array, files, globalvars, serialization, table
💬 Communication: datasignal, http, signal, wirelink,
❓ Informational: gametick, serverinfo, steamidconv, unitconv
Additional Extensions
Disabled by default: constraintcore, effects, propcore, remoteupload, wiring
Wire-Extras (repo): camera, ftrace, holoanim, light, stcontrol, tracesystem