Skip to content

Commit

Permalink
unreliable events and version bump
Browse files Browse the repository at this point in the history
  • Loading branch information
jackdotink committed Dec 20, 2023
1 parent 80e2a7e commit bd6467b
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 232 deletions.
6 changes: 4 additions & 2 deletions docs/2.0/Red.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ Creates a new [event](./Event/index) object.

```lua
<T...>(
Name: string, -- The name of the event
Name: string | { Name: string, Unreliable: boolean? }, -- Event config
Validate: (...unknown) -> T..., -- Validates event payloads
) -> Event<T...>
```

This will create an event with the passed name.
This will create an event with the passed config.

If you pass a string, it will be used as the event name and the event will be reliable. If you pass a table you have the option to make the event unreliable.

::: danger
The name of the event must be unique, using the same name twice will result in an error.
Expand Down
17 changes: 16 additions & 1 deletion docs/guide/events/declaring.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ return Red.Event("MostBasicEvent", function()
end)
```

This is the most basic event in Red. Here we've declared an event which has no payload. The event name is gathered from the module name.
This is the most basic event in Red. Here we've declared an event which has no payload. The event name is passed as the first argument to `Red.Event`.

::: danger
Make sure the event name is unique - using the same name multiple times will result in an error.
Expand Down Expand Up @@ -79,3 +79,18 @@ end)
::: warning
Ensure you follow rule 1 when using multiple payloads. The callback must return the arguments in the same order they were passed in.
:::

## Unreliable Events

Events can be unreliable. This means that the event will not be guaranteed to fire. This is useful for events that are not important, or are fired very frequently.

To make an event unreliable, pass a table as the first argument to `Red.Event`.

```lua
return Red.Event({
Name = "UnreliableEvent",
Unreliable = true,
}, function()
return
end)
```
12 changes: 10 additions & 2 deletions lib/Event/Client.luau
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ local Net = require(script.Parent.Parent.Net)
export type Client<T...> = {
Id: string,

Unreliable: boolean,

Fire: (self: Client<T...>, T...) -> (),
On: (self: Client<T...>, Callback: (T...) -> ()) -> (),
}

local function Fire<T...>(self: Client<T...>, ...: T...)
Net.Client.SendReliableEvent(self.Id, table.pack(...))
if self.Unreliable then
Net.Client.SendUnreliableEvent(self.Id, table.pack(...))
else
Net.Client.SendReliableEvent(self.Id, table.pack(...))
end
end

local function On<T...>(self: Client<T...>, Callback: (T...) -> ())
Expand All @@ -19,10 +25,12 @@ local function On<T...>(self: Client<T...>, Callback: (T...) -> ())
end)
end

local function Client<T...>(Id: string): Client<T...>
local function Client<T...>(Id: string, Unreliable: boolean): Client<T...>
return {
Id = Id,

Unreliable = Unreliable,

Fire = Fire,
On = On,
} :: any
Expand Down
36 changes: 30 additions & 6 deletions lib/Event/Server.luau
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export type Server<T...> = {
Id: string,
Validate: (...unknown) -> T...,

Unreliable: boolean,

Fire: (self: Server<T...>, Player: Player, T...) -> (),
FireAll: (self: Server<T...>, T...) -> (),
FireAllExcept: (self: Server<T...>, Except: Player, T...) -> (),
Expand All @@ -18,14 +20,22 @@ export type Server<T...> = {
}

local function Fire<T...>(self: Server<T...>, Player: Player, ...: T...)
Net.Server.SendReliableEvent(Player, self.Id, table.pack(...))
if self.Unreliable then
Net.Server.SendUnreliableEvent(Player, self.Id, table.pack(...))
else
Net.Server.SendReliableEvent(Player, self.Id, table.pack(...))
end
end

local function FireAll<T...>(self: Server<T...>, ...: T...)
local Args = table.pack(...)

for _, Player in Players:GetPlayers() do
Net.Server.SendReliableEvent(Player, self.Id, Args)
if self.Unreliable then
Net.Server.SendUnreliableEvent(Player, self.Id, Args)
else
Net.Server.SendReliableEvent(Player, self.Id, Args)
end
end
end

Expand All @@ -34,7 +44,11 @@ local function FireAllExcept<T...>(self: Server<T...>, Except: Player, ...: T...

for _, Player in Players:GetPlayers() do
if Player ~= Except then
Net.Server.SendReliableEvent(Player, self.Id, Args)
if self.Unreliable then
Net.Server.SendUnreliableEvent(Player, self.Id, Args)
else
Net.Server.SendReliableEvent(Player, self.Id, Args)
end
end
end
end
Expand All @@ -43,7 +57,11 @@ local function FireList<T...>(self: Server<T...>, List: { Player }, ...: T...)
local Args = table.pack(...)

for _, Player in List do
Net.Server.SendReliableEvent(Player, self.Id, Args)
if self.Unreliable then
Net.Server.SendUnreliableEvent(Player, self.Id, Args)
else
Net.Server.SendReliableEvent(Player, self.Id, Args)
end
end
end

Expand All @@ -52,7 +70,11 @@ local function FireWithFilter<T...>(self: Server<T...>, Filter: (Player) -> bool

for _, Player in Players:GetPlayers() do
if Filter(Player) then
Net.Server.SendReliableEvent(Player, self.Id, Args)
if self.Unreliable then
Net.Server.SendUnreliableEvent(Player, self.Id, Args)
else
Net.Server.SendReliableEvent(Player, self.Id, Args)
end
end
end
end
Expand All @@ -67,11 +89,13 @@ local function On<T...>(self: Server<T...>, Callback: (Player, T...) -> ())
end)
end

local function Server<T...>(Id: string, Validate: (...unknown) -> T...): Server<T...>
local function Server<T...>(Id: string, Validate: (...unknown) -> T..., Unreliable: boolean): Server<T...>
return {
Id = Id,
Validate = Validate,

Unreliable = Unreliable,

Fire = Fire,
FireAll = FireAll,
FireAllExcept = FireAllExcept,
Expand Down
25 changes: 22 additions & 3 deletions lib/Event/init.luau
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export type Event<T...> = {
Id: string,
Validate: (...unknown) -> T...,

Unreliable: boolean,

ServerEvent: ServerEvent.Server<T...>?,
ClientEvent: ClientEvent.Client<T...>?,

Expand All @@ -20,7 +22,7 @@ local function Server<T...>(self: Event<T...>): ServerEvent.Server<T...>
assert(RunService:IsServer(), "Server events can only be accessed from the server")

if not self.ServerEvent then
self.ServerEvent = ServerEvent(self.Id, self.Validate)
self.ServerEvent = ServerEvent(self.Id, self.Validate, self.Unreliable)
end

return self.ServerEvent :: any
Expand All @@ -30,19 +32,36 @@ local function Client<T...>(self: Event<T...>): ClientEvent.Client<T...>
assert(RunService:IsClient(), "Client events can only be accessed from the client")

if not self.ClientEvent then
self.ClientEvent = ClientEvent(self.Id) :: any
self.ClientEvent = ClientEvent(self.Id, self.Unreliable) :: any
end

return self.ClientEvent :: any
end

local function Event<T...>(Name: string, Validate: (...unknown) -> T...): Event<T...>
type EventOptions = {
Name: string,
Unreliable: boolean?,
}

local function Event<T...>(Config: string | EventOptions, Validate: (...unknown) -> T...): Event<T...>
local Name, Unreliable

if type(Config) == "string" then
Name = Config
Unreliable = false
else
Name = Config.Name
Unreliable = Config.Unreliable or false
end

assert(not Identifier.Exists(Name), "Cannot use same name twice")

return {
Id = Identifier.Shared(Name):Await(),
Validate = Validate,

Unreliable = Unreliable,

ServerEvent = nil,
ClientEvent = nil,

Expand Down
Loading

0 comments on commit bd6467b

Please sign in to comment.