[v.69] SimpleSignal | Very Simple & Silly Fast Script Signal

Yea I can’t seem to find it, that’s the point

This here hjhjhjhjhjjh//30charlimit//

1 Like

My bad, probably, I used old version

I think with my own benchmark I actually found a really bad bug in your module:

--!optimize 2
--!strict

-- yield test
local BadSignal = require(script.BadSignal)
local SimpleSignal = require(script.SimpleSignal)

local loops = 100

local Signal1 = BadSignal:new(1) -- 1 is to tell to not allocate a lot of slots
local Signal2 = SimpleSignal.new()

local t = os.clock()
for i = 1,loops do
	Signal1:Push(true,function(b:any) -- true because we call task.wait()
		local a = i*b::number
		task.wait()
		print("Fired1") -- to detect if all functions ran
	end)
end
print("Bad signal connect: ",os.clock()-t)
t = os.clock()
for i = 1,loops do
	Signal2:Connect(function(b:any)
		local a = i*b::number
		task.wait()
		print("Fired2") -- to detect if all functions ran
	end)
end
print("Simple signal connect: ",os.clock()-t)

local t = os.clock()
for i = 1,10 do
	Signal1:Fire(2)
end
print("Bad signal fire: ",os.clock()-t)
local t = os.clock()
for i = 1,10 do
	Signal2:Fire(2)
end
print("Simple signal fire: ",os.clock()-t)

I know this is a crude benchmark, but the point is that Simple Signal refuses to run functions that were suspended. Out of 10 fire calls, it will run only once per connection. I guess fix it and it will be a lot more fair comparison

1 Like

Can you elaborate on your bug report? I can’t seem to grasp what exactly the issue is.

Functions can’t be suspended, only coroutines, and there are no coroutines in the provided code. :confused:

1 Like

In crude terms, out of 1000 intended prints, only 100 printed. If you run the code you can see that

Hi, unfortunately I can’t replicate the issue :confused: It’s most likely just the output overloading from the sheer amount of prints lol

Try this one:

--!optimize 2
--!strict

-- yield test
local BadSignal = require(script.BadSignal)
local SimpleSignal = require(script.SimpleSignal)

local loops = 1 

local Signal1 = BadSignal:new(1) -- 1 is to tell to not allocate a lot of slots
local Signal2 = SimpleSignal.new()

local t = os.clock()
for i = 1,loops do
	Signal1:Push(true,function(b:any) -- true because we call task.wait()
		local a = i*b::number
		task.wait()
		print("Fired1") -- to detect if all functions ran
	end)
end
print("Bad signal connect: ",os.clock()-t)
t = os.clock()
for i = 1,loops do
	Signal2:Connect(function(b:any)
		local a = i*b::number
		task.wait()
		print("Fired2") -- to detect if all functions ran
	end)
end
print("Simple signal connect: ",os.clock()-t)

local t = os.clock()
for i = 1,10 do
	Signal1:Fire(2)
end
print("Bad signal fire: ",os.clock()-t)
local t = os.clock()
for i = 1,10 do
	Signal2:Fire(2)
end
print("Simple signal fire: ",os.clock()-t)

there should be 10 Fired1 and 1 Fired2

1 Like

He might be onto something.

I think it’s due to the fact that your method only has one thread for each connection, and if that connection callback is not done before firing again, when you resume the non-suspended thread, nothing happens (hence the error cannot resume non-suspended thread).

1 Like

Ahh yeah, I do think this is unfortunately just a limit of using 1 thread per connection; however I do have an idea on how to fix it :slight_smile: Gimme like a few minutes

1 Like

Hm sure, but I think the best solution is just usual thread recycling, like what Signal+ used to have.

1 Like

Package Version 63:

  • Removed the method of 1-thread-per-connection in favor of a more robust thread recycling method which is able to achieve around the same fire times as the old method, without all the issues :slight_smile:

  • Added SimpleSignal.setCleaningInterval(n: number) to set the interval for cleaning up unused threads

  • *Fixed n being subtracted in the deallocateThreads loop instead of i … this is what you get for abbreviating variables kids :frowning:

Note that this update introduces alot of possibilities for things to go wrong, so if you encounter something report it to me asap :slight_smile:

1 Like

How does this compare to other signals, FastSignal etc…

It is multiple times faster for :Fire() because it caches and reuses threads alot more, and around the same speed for :Connect() and :Disconnect(), with the only downside being that it needs its own dedicated loop to deallocate unused threads; which isn’t really a big problem :V

2 Likes

I see, pretty smart
Most likely will give it a try in thbe future

1 Like

I donated 80 Robux since I can clearly tell that you’ve put a LOT of work into this module from reading all the replies!

But I would love to ask, what does a Signal module even do? I’ve seen the term thrown around so much I feel like it’s lost all meaning, could you just break it down for me? Thanks!

1 Like

Thanks for donating! All support not only goes into making SimpleSignal, but also all my other stuff like SImpleZone to SimpleComplete :slight_smile:

A signal module is basically a fancy way to store a bunch of functions, and fire them all at once; running each one in its own thread so they can safely yield

It’s very, very similar to Roblox’s RBXScriptSignals like Part.Touched, just custom-made so you can use them for your own events.

Change this
image
To something like this
image
because the license should belong to a person, not a module.

1 Like

I noticed this too.

Another thing is that you can’t really modify the MIT license I believe. Although he hasn’t even done that, even though he says so, which is extremely weird?

1 Like

Ahh yes, I’ll fix it in 64

I did modify it, and it is legal (even though the precedence is kinda small)