Currently the developers are putting their own money into JC2-MP to keep the servers online.

Please take a few seconds of your time and disable your AdBlock plugin for our website.

Ad revenue is not going to developers, it is used purely for covering our hosting costs.

 

You are also free to donate, which removes all ads from our website!

Patch 0.3 was just released! Full changelog here: https://t.co/4A50m6IKen

7 months ago

December 15, 2017, 01:40:54 am

Author Topic: [Release] Timer Extension (for timed, delayed, or repetitive events)  (Read 2033 times)

SinisterRectus

  • JC2-MP Betatester
  • Sr. Member
  • *****
  • Posts: 448
    • View Profile
Timer Extension

Just a few utility functions modeled after Node.js timers. These are wrappers for timed event subscriptions that can easily be scripted manually, but might be more easily used with shortcuts.

Download from GitHub Here

Features

Timer.SetImmediate(callback) - Schedules a callback to be called once on the next tick.
Timer.SetTimeout(delay, callback) - Schedules a callback to be called once following a delay in milliseconds.
Timer.SetInterval(delay, callback) - Schedules a callback to be called repeatedly, with an interval equal to delay.
Timer.Clear(timer) - Aborts a scheduled callback according to the timer handle returned by the above functions.
Timer.Sleep(delay) - Sleeps a coroutine for the given amount of milliseconds.
Timer.Tick() - Calls all waiting callbacks if their delays have elapsed. Automatically subscribed to PreTick.



Examples

Print "tick" every one second:
Code: Lua
  1. Timer.SetInterval(1000, function()
  2.     print('tick')
  3. end)

Alternate implementation using a coroutine:
Code: Lua
  1. coroutine.wrap(function()
  2.     while true do
  3.         Timer.Sleep(1000)
  4.         print('tick')
  5.     end
  6. end)()

Print the true time elapsed by the timer every second:
Code: Lua
  1. Timer.SetInterval(1000, function(args)
  2.     print(args.delta)
  3. end)

Alternate implementation using a coroutine:
Code: Lua
  1. coroutine.wrap(function()
  2.     while true do
  3.         local args = Timer.Sleep(1000)
  4.         print(args.delta)
  5.     end
  6. end)()

Print "tick" every second for 5 seconds:
Code: Lua
  1. for i = 1, 5 do
  2.     Timer.SetTimeout(1000 * i, function()
  3.         print('tick')
  4.     end)
  5. end

Alternate implementation using a coroutine:
Code: Lua
  1. coroutine.wrap(function()
  2.     for i = 1, 5 do
  3.         Timer.Sleep(1000)
  4.         print('tick')
  5.     end
  6. end)()

Start a self-destruct sequence any time a player enters a vehicle:
Code: Lua
  1. Events:Subscribe("PlayerEnterVehicle", function(args)
  2.  
  3.     local player = args.player
  4.     local vehicle = args.vehicle
  5.     local color = Color.Red
  6.     local countdown = 10
  7.     local str = "Vehicle will self-destruct in: %i seconds!"
  8.  
  9.     Chat:Send(player, string.format(str, countdown), color)
  10.  
  11.     local timer = Timer.SetInterval(1000, function()
  12.         countdown = countdown - 1
  13.         Chat:Send(player, string.format(str, countdown), color)
  14.     end)
  15.  
  16.     Timer.SetTimeout(countdown * 1000, function()
  17.         Timer.Clear(timer)
  18.         vehicle:SetHealth(0)
  19.     end)
  20.  
  21. end)

Alternate implementation using a coroutine:
Code: Lua
  1. Events:Subscribe("PlayerEnterVehicle", function(args)
  2.  
  3.     local player = args.player
  4.     local vehicle = args.vehicle
  5.     local color = Color.Red
  6.     local countdown = 10
  7.     local str = "Vehicle will self-destruct in: %i seconds!"
  8.  
  9.     coroutine.wrap(function()
  10.         local n = countdown
  11.         for i = 1, n do
  12.             Chat:Send(player, string.format(str, countdown), color)
  13.             Timer.Sleep(1000)
  14.             countdown = countdown - 1
  15.         end
  16.         vehicle:SetHealth(0)
  17.     end)()
  18.  
  19. end)


Usage

- This works on both the client and server from the shared folder. It must be placed in every module with which you wish to use it, or in your Lua autorun folder.
- The default delay unit is in milliseconds. If you want to use a unit other than milliseconds, change the GetTime definition at the top of the script.
- Time.Tick() is, by default, automatically subscribed to PreTick. You may disable this and manually call it from your own custom loop.
- At 100 ticks per second, a tick length is 10 ms and at 50 ticks per second, a tick length is 20 ms. Accuracy is not guaranteed if your timer delay is less than a normal tick length.



Download from GitHub Here
« Last Edit: April 11, 2016, 11:00:54 pm by SinisterRectus »

Dev_34

  • Full Member
  • ***
  • Posts: 150
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #1 on: April 11, 2016, 10:05:32 pm »
Nice, this seems far superior than delaying code with variables with the traditional events.

SinisterRectus

  • JC2-MP Betatester
  • Sr. Member
  • *****
  • Posts: 448
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #2 on: October 21, 2016, 03:43:52 am »
If anyone if using this, grab the latest copy. I made a few minor optimizations. No breaking changes.

Urik

  • Donator
  • Full Member
  • *****
  • Posts: 119
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #3 on: January 23, 2017, 03:12:52 pm »
It seems that I can't use class function as callback argument unless (I guess) I make timerextension a class as well an init within that class (I hope I described it well)?

SinisterRectus

  • JC2-MP Betatester
  • Sr. Member
  • *****
  • Posts: 448
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #4 on: January 23, 2017, 03:39:46 pm »
Can you give an example of what you are trying to do?

Urik

  • Donator
  • Full Member
  • *****
  • Posts: 119
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #5 on: January 24, 2017, 03:40:50 pm »
Sorry for late reply, I mean I tried providing it with a class function as argument, like
Code: [Select]
Timer.SetTimeout(1000 , myclass:myfunction())(this line is located within another function of same class, and class is running of course)
Judging by the error reading, the function argument that the timer extension receives is nil so it can't act and errors.
It's not like I'm in any trouble really, I was just trying out different tools posted here that potentially could make it easier without having to create sub/unsub ticks and timers.

SinisterRectus

  • JC2-MP Betatester
  • Sr. Member
  • *****
  • Posts: 448
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #6 on: January 24, 2017, 08:24:17 pm »
Without changing the timer code, you can make this work by wrapping the class method call with another function:

Code: [Select]
Timer.SetTimeout(1000, function()
  myclass:myfunction()
end)

Urik

  • Donator
  • Full Member
  • *****
  • Posts: 119
    • View Profile
Re: [Release] Timer Extension (for timed, delayed, or repetitive events)
« Reply #7 on: January 24, 2017, 11:24:34 pm »
Thanks!