Skip to content

Commit

Permalink
Switch to call_default
Browse files Browse the repository at this point in the history
  • Loading branch information
Ketasaja committed Sep 26, 2024
1 parent 2f940f6 commit 560998f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
8 changes: 1 addition & 7 deletions docs/config/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ This field determines the type of event. It can be either `Reliable` or `Unrelia
- Reliable events are guaranteed to arrive at their destination in the order they were sent.
- Unreliable events are not guaranteed to arrive at their destination, and they are not guaranteed to arrive in the order they were sent. Unreliable events also have a maximum size of 900 bytes.

### `handling`

Overrides the `event_handling` option, determining how your code receives Zap events.

- `Polling` events store data they receive in queues, and you must pull from them when you want it.
- `Signal` events push data to your listener functions as it's received.

### `call`

This field determines how the event is listened to on the receiving side.
Expand All @@ -50,6 +43,7 @@ This field determines how the event is listened to on the receiving side.
- `ManySync` events can be listened to by many functions, and they are called synchronously.
- `SingleAsync` events can be listened to by one function, and they are called asynchronously.
- `SingleSync` events can be listened to by one function, and they are called synchronously.
- `Polling` events are received by iterating through the event.

::: danger
Synchronous events are not recommended, and should only be used when performance is critical.
Expand Down
14 changes: 5 additions & 9 deletions docs/config/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,17 @@ The paths are relative to the configuration file and should point to a lua(u) fi

<CodeBlock :code="outputExample" />

## `event_handling`
## `call_default`

Determines the default way your code receives events from Zap. With signals, Zap pushes events as it receives them to your listener functions. With polling, Zap stores events in queues when they're received, and you pull events from those queues when you want them.
Determines the default `call` field for events. See [here](events.html#call) for possible options.

### Default

<CodeBlock code = 'opt event_handling = "signal"' />
None, all event declarations will need a `call` field.

### Example
<script setup lang="luau">
-- Example of using a Zap polling event on the server.
for player, payload in zap.my_event do
print(player, payload)
end
</script>

<CodeBlock code = 'opt call_default = "ManySync"' />

## `remote_scope`

Expand Down
45 changes: 34 additions & 11 deletions zap/src/parser/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,19 +195,39 @@ impl<'src> Converter<'src> {
}
}

fn event_handling_opt(&mut self, opts: &[SyntaxOpt<'src>]) -> EventHandling {
match self.str_opt("event_handling", "signal", opts) {
("polling", ..) => EventHandling::Polling,
("signal", ..) => EventHandling::Signal,
fn call_default_opt(&mut self, opts: &[SyntaxOpt<'src>]) -> Option<EvCall> {
let mut value: Option<&str> = None;
let mut span = None;

for opt in opts.iter().filter(|opt| opt.name.name == "call_default") {
if let SyntaxOptValueKind::Str(opt_value) = &opt.value.kind {
value = Some(self.str(opt_value));
span = Some(opt_value.span());
} else {
self.report(Report::AnalyzeInvalidOptValue {
span: opt.value.span(),
expected: "`SingleSync`, `ManySync`, `SingleAsync`, `ManyAsync`, or `Polling`",
});
}
}

match (value, span) {
(Some("SingleSync"), ..) => Some(EvCall::SingleSync),
(Some("ManySync"), ..) => Some(EvCall::ManySync),
(Some("SingleAsync"), ..) => Some(EvCall::SingleAsync),
(Some("ManyAsync"), ..) => Some(EvCall::ManyAsync),
(Some("Polling"), ..) => Some(EvCall::Polling),

(_, Some(span)) => {
self.report(Report::AnalyzeInvalidOptValue {
span: span,
expected: "`polling` or `signal`",
span,
expected: "`SingleSync`, `ManySync`, `SingleAsync`, `ManyAsync`, or `Polling`",
});

EventHandling::Signal
None
}
_ => unreachable!(),

_ => None,
}
}

Expand Down Expand Up @@ -341,10 +361,13 @@ impl<'src> Converter<'src> {
let from = evdecl.from;
let evty = evdecl.evty;
let call = evdecl.call.unwrap_or_else(|| {
if let EventHandling::Polling = self.event_handling_opt(&self.config.opts.clone()) {
EvCall::Polling
if let Some(default) = self.call_default_opt(&self.config.opts.clone()) {
default
} else {
panic!();
self.report(Report::AnalyzeMissingEvDeclCall { ev_span: evdecl.span() });

// This value is meaningless and not a default, it's used to allow the program to run until error reporting.
EvCall::ManySync
}
});
let data = evdecl.data.as_ref().map(|ty| self.ty(ty));
Expand Down
12 changes: 12 additions & 0 deletions zap/src/parser/reports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ pub enum Report<'src> {

AnalyzeEmptyEvDecls,

AnalyzeMissingEvDeclCall {
ev_span: Span,
},

AnalyzeOversizeUnreliable {
ev_span: Span,
ty_span: Span,
Expand Down Expand Up @@ -122,6 +126,7 @@ impl<'src> Report<'src> {
Self::AnalyzeUnboundedRecursiveType { .. } => Severity::Error,
Self::AnalyzeMissingOptValue { .. } => Severity::Error,
Self::AnalyzeDuplicateDecl { .. } => Severity::Error,
Self::AnalyzeMissingEvDeclCall { .. } => Severity::Error,
}
}

Expand Down Expand Up @@ -151,6 +156,9 @@ impl<'src> Report<'src> {
Self::AnalyzeUnboundedRecursiveType { .. } => "unbounded recursive type".to_string(),
Self::AnalyzeMissingOptValue { .. } => "missing option expected".to_string(),
Self::AnalyzeDuplicateDecl { name, .. } => format!("duplicate declaration '{}'", name),
Self::AnalyzeMissingEvDeclCall { .. } => {
"missing `call` field without defining `call_default` option".to_string()
}
}
}

Expand All @@ -177,6 +185,7 @@ impl<'src> Report<'src> {
Self::AnalyzeUnboundedRecursiveType { .. } => "3012",
Self::AnalyzeMissingOptValue { .. } => "3013",
Self::AnalyzeDuplicateDecl { .. } => "3014",
Self::AnalyzeMissingEvDeclCall { .. } => "3015",
}
}

Expand Down Expand Up @@ -272,6 +281,8 @@ impl<'src> Report<'src> {
Label::primary((), dup_span.clone()).with_message("duplicate declaration"),
]
}

Self::AnalyzeMissingEvDeclCall { ev_span } => vec![Label::primary((), ev_span.clone())],
}
}

Expand Down Expand Up @@ -335,6 +346,7 @@ impl<'src> Report<'src> {
"the {expected} option should not be empty if {required_when}"
)]),
Self::AnalyzeDuplicateDecl { .. } => None,
Self::AnalyzeMissingEvDeclCall { .. } => None,
}
}

Expand Down

0 comments on commit 560998f

Please sign in to comment.