Tener Signal, a usefull signal module

What is it?:

A simple and usefull module to create signals without use bindable events, with a lot of usefull features

Features:

Gonna list the extra features, Connect,Disconnect and Fire are already expected from a signal module.

  • ConnectMultiple: You can connect multiple functions at same time,
  • ConnectOnce: You can connect a function that will be auto disconnected after triggered, you can also have a Condition function on it, to avoid disconnect if the Condition is false.
  • DisconnectAll: Disconnect all functions on that signal
  • FireOnce: Wil fire the signal once than disconnect all functions
  • Destroy: Will completly remove signal from existence
  • GetSignal: You can get the signal you created from any local, making ez to connect functions from different modules / scripts

Why use it over others Signals modules?

It have extra usefull utilitys, its also almost fast as the fastest signal module right now (GoodSignal) loosing for few mileseconds

But with extra stuff and able to get the same signal on any place

Use example


local MySignal = Signal.GetSignal("Test")

local Connection = Signal.Connect(MySignal,function(String)
      print(String)
end)

Signal.FireAll(MySignal,"Hello world")

Code:

If have any problem or bug report for me please.

9 Likes

Hmmm, Pastebin, it’s published by a guest, why not a github gist? so you can edit the code instead of making a new one

though I do feel like using bindables over signal modules

1 Like

Cause i dont have github, also bindables are very bad, slowner and they dont reference the tables, they clone it

3 Likes

Implemention FastSpawn with FreeThread on Fire may be good

1 Like

then create a github account??? it’s not that hard, all you need is an email

well, what if you don’t want someone to fire the event when you get the signal from the module???

1 Like

Thanks for the suggestion, iam gonna take a look.

1 Like

Can you be clear? iam Brazilian

1 Like

hard to understand what ur saying about

1 Like

I’m saying that in case you have a signal, and you put it in your module, and you don’t want another script to fire it, so you don’t have false firing

1 Like

If you dont want other script fire it just dont call it on other script :confused:

1 Like

image
i made a test with x1000 (for i=1,1000) to FireAll with Connect

and i try to make my self signal with same option like above on test
image
the Finish is longer because i add :Wait function here

local oneSignal = {}
oneSignal.ClassName = "oneSignal"
oneSignal.__index = oneSignal

local Collections = {}

function oneSignal.new(identifier)
	assert(typeof(identifier) == "string", "[oneSignal]: Identifier must be string")
	assert(not Collections[identifier], string.format("[oneSignal]: %s already exist", identifier))
	Collections[identifier] = setmetatable({
		cb = nil,
		Connected = false,
		Identifier = identifier,
		_ping = nil,
	}, oneSignal)
	return Collections[identifier]
end

function oneSignal.get(identifier)
	assert(Collections[identifier], string.format("[oneSignal]: %s not exist", identifier))
	return Collections[identifier]
end

function oneSignal:Connect(callback)
	if self then
		assert(not self.Connected, string.format("[oneSignal]: %s already connected", self.Identifier))
		self.cb = callback
		self.Connected = true
	end
end

function oneSignal:Wait()
	if self then
		local thread = coroutine.running()
		local clock = os.clock()
		self._ping = function(x)
			task.spawn(thread, x - clock)
			self._ping = nil
		end
		return coroutine.yield()
	end
end

function oneSignal:Once(callback)
	if self and not self.Connected then
		self.cb = function(...)
			self:Disconnect()
			task.spawn(callback, ...)
		end
		self.Connected = true
	end
end

function oneSignal:Disconnect()
	if self and self.Connected then
		self.Connected = false
		self.cb = nil
	end
end

function oneSignal:Destroy()
	self:Disconnect()
	if self then
		Collections[self.Identifier] = nil
		self = nil
	end
end

function oneSignal:Fire(...)
	if self then
		if self.Connected then
			task.spawn(self.cb, ...)
		end
		if self._ping then
			task.spawn(self._ping, os.clock())
		end
	end
end

return table.freeze(oneSignal)
  • i use os.clock here for more precist and save the finish time estimate so no time loss here

ms is miliseconds (1e3)
µs is microseconds (1e6)
ns is nanoseconds (1e9)

2 Likes
local One = require(script.Parent:WaitForChild("oneSignal"))

local test1 = One.new("test")

test1:Once(function()
	print(test1:Wait()*1e6)
end)

task.wait(3)

test1:Fire()
test1:Fire()

Ouput:
1.600000359758269 µs

2 Likes

Seens like my one finished faster

1 Like

Wait you are just connection one function on the signal, Means you doenst need loop It, i connect multiple functions on same signal, Means i loop It, idk why you make one signal Just be able to have 1 connection, seens not reliable

1 Like

u finished the loop faster because in ur Fire function only do once callback, but in my funvtion does callback and ping, ping for :Wait function. but in Avg received ur later, avg receive is when the fire is reached to callback and received

1 Like

Yes but you dont have loop, your signal Just accept one connection, or iam being dumb idk

1 Like

ur loop just once because only 1connection so no affect to time, OOP is slower than normal (not much just like µs or ns) but OOP is more flexible

1 Like