Skip to content

Commit

Permalink
update wiki
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaktushose committed Jan 16, 2025
1 parent 61c2043 commit b273fa6
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/wiki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: 3.x
- run: pip install mkdocs-material
- run: pip install -r requirements.txt
- run: mkdocs build
- name: Deploy Wiki
uses: JamesIves/github-pages-deploy-action@v4
Expand Down
Binary file added docs/assets/cookie-clicker.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/plugin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/runtime.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 30 additions & 20 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,45 @@
A declarative, annotation driven interaction framework for JDA. Our goal is to remove any boilerplate code, so
you can focus solely on the business logic of your bot - writing bots has never been easier:

## Example
```java
@Interaction
public class CookieClicker {
=== "Code"
```java
@Interaction
public class CookieClicker {

private int counter;//(1)!

@SlashCommand(value = "cookie clicker", desc = "Play cookie clicker")
public void onClicker(CommandEvent event) {
event.with().components("onCookie").reply("You've got %s cookie(s)!", counter);
}

@Button(value = "Collect", emoji = "🍪", style = ButtonStyle.SUCCESS)
public void onCookie(ComponentEvent event) {
event.reply("You've got %s cookie(s)!", ++counter);//(2)!
}
}
```

private int count;
1. Yes, that's right! We can store the `counter` as a class variable. JDA-Commands will create a new instance of
`CookieClicker` for every command execution, so you don't need to worry about state. You can read more about
it [here](./start/runtime.md).
2. This will edit the original message and will also keep the `🍪 Collect` button attached. You can find find more
about building replies [here](./interactions/reply.md).

@SlashCommand(value = "cookie clicker", desc = "Play cookie clicker")
public void onClicker(CommandEvent event) {
event.with().components("onCookie").reply("You've got %s cookie(s)!", count);
}
=== "Execution"
![Cookie Clicker](./assets/cookie-clicker.gif)

@Button(value = "Collect", emoji = "🍪", style = ButtonStyle.SUCCESS)
public void onCookie(ComponentEvent event) {
event.reply("You've got %s cookie(s)!", ++count);
}
}
```
## Dependency
## Adding to your Project
=== "Maven"
```xml
```xml title="pom.xml"
<dependency>
<groupId>io.github.kaktushose</groupId>
<artifactId>jda-commands</artifactId>
<version>v4.0.0-beta.4</version>
</dependency>
```
=== "Gradle (Kotlin DSL)"
```kotlin
```kotlin title="build.gradle.kts"
repositories {
mavenCentral()
}
Expand All @@ -40,7 +50,7 @@ public class CookieClicker {
}
```
=== "Gradle (Groovy DSL)"
```groovy
```groovy title="build.gradle"
repositories {
mavenCentral()
}
Expand All @@ -49,7 +59,7 @@ public class CookieClicker {
}
```

## Resources
## Additional Resources

You might also find the following resources helpful:

Expand Down
22 changes: 15 additions & 7 deletions docs/start/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@

- Java 23 or later
- [JDA 5.x](https://github.com/discord-jda/JDA)
- <a href="https://jda.wiki/setup/logging/" target="_blank">SLF4J Implementation</a> _(not mandatory, but recommended)_
- [SLF4J Implementation](https://jda.wiki/setup/logging/) _(not mandatory, but recommended)_

## Configuration
JDA-Commands is distributed through Maven Central, or alternately you can download the latest version
[here](https://github.com/Kaktushose/jda-commands/releases/latest)
JDA-Commands is distributed through Maven Central. Alternatively you can download the latest version
[here](https://github.com/Kaktushose/jda-commands/releases/latest).

=== "Maven"
```xml
```xml title="pom.xml"
<dependency>
<groupId>io.github.kaktushose</groupId>
<artifactId>jda-commands</artifactId>
<version>v4.0.0-beta.4</version>
</dependency>
```
=== "Gradle (Kotlin DSL)"
```kotlin
```kotlin title="build.gradle.kts"
repositories {
mavenCentral()
}
Expand All @@ -28,11 +28,19 @@ JDA-Commands is distributed through Maven Central, or alternately you can downlo
}
```
=== "Gradle (Groovy DSL)"
```groovy
```groovy title="build.gradle"
repositories {
mavenCentral()
}
dependencies {
implementation 'io.github.kaktushose:jda-commands:v4.0.0-beta.4"'
}
```
```

## IntelliJ Plugin

We also provide an IntelliJ Plugin that performs some Code Inspection. It validates method references, which are
commonly used in jda-commands. You can find it [here](https://plugins.jetbrains.com/plugin/25977-jda-commands-inspection).

![Plugin Example](../assets/plugin.png)

2 changes: 1 addition & 1 deletion docs/start/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class Main {

public static void main(String[] args) {
JDA jda = yourJDABuilding();
JDACommands jdaCommands = JDACommands.start(jda, Main.class);
JDACommands.start(jda, Main.class);
}
}
```
Expand Down
101 changes: 101 additions & 0 deletions docs/start/runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Runtime Concept

## Overview

One of the core concepts in JDA-Commands is the so-called `Runtime`. It will be mentioned frequently here and in the
[Javadocs](https://kaktushose.github.io/jda-commands/javadocs/latest/). A `Runtime` delegates the JDA events to their
corresponding `EventHandlers` and manages the used virtual threads.

A new `Runtime` is created each time a:

- [`SlashCommandInteractionEvent`](https://javadoc.io/doc/net.dv8tion/JDA/latest/net/dv8tion/jda/api/events/interaction/command/SlashCommandInteractionEvent.html)
- [`GenericContextInteractionEvent`](https://javadoc.io/doc/net.dv8tion/JDA/latest/net/dv8tion/jda/api/events/interaction/command/GenericContextInteractionEvent.html)
- [`CommandAutoCompleteInteractionEvent`](https://javadoc.io/doc/net.dv8tion/JDA/latest/net/dv8tion/jda/api/events/interaction/command/CommandAutoCompleteInteractionEvent.html)

is provided by JDA or if an interaction is marked as [*independent*](#components).

Runtimes are executed in parallel, but events are processed sequentially by each `Runtime`.
Every `EventHandler` called by a `Runtime` is executed in its own virtual thread, isolated from the runtime one.

See [`Lifetime`](#Lifetime) for
details when a `Runtime` will close.

## Threading Model

JDA-Commands will listen for incoming events on the `JDA MainWS-ReadThread`. It will then create a new `Runtime`
or use an existing one, depending on the type of event _(see the flowchart below for details)._ The incoming event is
then passed to the corresponding `Runtime`.

Each `Runtime` will run in its own virtual thread, called `JDAC Runtime-Thread <UUID>`. The `Runtime` will wait for new
incoming events and then delegate them to the correct `EventHandler`. For instance, a
[`SlashCommandInteractionEvent`](https://javadoc.io/doc/net.dv8tion/JDA/latest/net/dv8tion/jda/api/events/interaction/command/SlashCommandInteractionEvent.html)
will be passed to the `SlashCommandHandler`.

The `EventHandler` will _again_ run in its own virtual thread, named `JDAC EventHandler-Thread <UUID>`, isolated from
the runtime one. Other incoming events are only executed when the previous one has finished.

!!! tip "Blocking Methods"
Because each event has its own virtual thread, you can call blocking methods like JDAs `RestAction#complete` safely
without blocking the `JDA MainWS-ReadThread`.

![Runtime Flowchart](../assets/runtime.png)

## Lifetime

By default, JDA-Commands will handle the lifetime of Runtimes for you. Every `Runtime` will be closed **15 minutes**
after its creation. This time span is oriented towards the lifespan of the
[`InteractionHook`](https://javadoc.io/doc/net.dv8tion/JDA/latest/net/dv8tion/jda/api/interactions/InteractionHook.html).

### Explicit

You can disable the default behaviour by setting the
[`ExpirationStrategy`](https://kaktushose.github.io/jda-commands/javadocs/latest/jda.commands/com/github/kaktushose/jda/commands/dispatching/expiration/ExpirationStrategy.html) to
[`EXPLICIT`](https://kaktushose.github.io/jda-commands/javadocs/latest/jda.commands/com/github/kaktushose/jda/commands/dispatching/expiration/ExpirationStrategy.Explicit.html).


```java title="Main.java"
JDACommands.builder(jda, Main.class)
.expirationStrategy(ExpirationStrategy.EXPLICIT)
.start();
```

This will prevent any `Runtime` from closing until [`closeRuntime`](https://kaktushose.github.io/jda-commands/javadocs/latest/jda.commands/com/github/kaktushose/jda/commands/dispatching/events/Event.html#closeRuntime())
is explicitly called.

!!! example
```java title="GreetCommand.java" hl_lines="4"
@SlashCommand("greet")
public void onCommand(CommandEvent event) {
event.reply("Hello World!");
event.closeRuntime();
}
```

### Inactivity
You can also adjust the time frame until a `Runtime` gets closed.

!!! example
```java title="Main.java" hl_lines="2"
JDACommands.builder(jda, Main.class)
.expirationStrategy(new ExpirationStrategy.Inactivity(20))//(1)!
.start();
```

1. Note: the duration is always passed as minutes.

## Components and Modals

### Runtime-bound

By default, Buttons, SelectMenus and Modals are `runtime-bound`. This means that any incoming event will use the same
`Runtime` as the interaction that replied with them.

However, this also means that they cannot be executed anymore after the `Runtime` is closed. JDA-Commands will handle
that case and remove the component in question. It will also send an ephemeral reply to the user, saying that the
component is no longer available.


### Independent

!!! info
Modals cannot be independent because they always need a parent interaction that triggers them!
6 changes: 5 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ extra:

copyright: Copyright &copy; 2025 Kaktushose

plugins:
- open-in-new-tab

markdown_extensions:
- admonition
- pymdownx.details
Expand All @@ -67,7 +70,8 @@ nav:
- Getting Started:
- Installation: start/installation.md
- Quick Start Guide: start/quick-start.md
- Interactions: interactions.d
- Runtime Concept: start/runtime.md
- Interactions: interactions.md
- Middlewares: middlewares.md
- Dependency Injection: di.md
- Misc: misc.md
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mkdocs-material
mkdocs-open-in-new-tab

0 comments on commit b273fa6

Please sign in to comment.