| Crates.io | lighty-event |
| lib.rs | lighty-event |
| version | 0.8.6 |
| created_at | 2025-12-14 03:13:02.066879+00 |
| updated_at | 2025-12-14 07:25:25.807986+00 |
| description | Event system for LightyLauncher |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1983706 |
| size | 29,695 |
Event system for LightyLauncher - A simple, efficient broadcast-based event system for tracking launcher operations.
AuthEvent)AuthenticationStarted - Authentication process beginsAuthenticationInProgress - Ongoing authentication with step infoAuthenticationSuccess - Authentication succeededAuthenticationFailed - Authentication failed with errorAlreadyAuthenticated - Valid session already existsJavaEvent)JavaNotFound - JRE not installedJavaAlreadyInstalled - JRE already presentJavaDownloadStarted - JRE download beginsJavaDownloadProgress - Download progress updatesJavaDownloadCompleted - Download finishedJavaExtractionStarted - Extraction beginsJavaExtractionProgress - Extraction progressJavaExtractionCompleted - Extraction finishedLaunchEvent)IsInstalled - Files already up-to-dateInstallStarted - Installation beginsInstallProgress - Installation progressInstallCompleted - Installation finishedLaunching - Game launch startingLaunched - Game process spawnedNotLaunched - Launch failedProcessOutput - Game process outputProcessExited - Game process exitedLoaderEvent)FetchingData - Fetching loader manifestDataFetched - Manifest retrievedManifestNotFound - Version not foundManifestCached - Using cached manifestMergingLoaderData - Merging loader dataDataMerged - Merge completedCoreEvent)ExtractionStarted - Archive extraction beginsExtractionProgress - Extraction progressExtractionCompleted - Extraction finishedAdd this to your Cargo.toml:
[dependencies]
lighty-event = "0.6"
use lighty_event::{EventBus, Event, LaunchEvent, EventReceiveError};
#[tokio::main]
async fn main() {
// Create event bus with buffer capacity
let event_bus = EventBus::new(1000);
// Subscribe to events
let mut receiver = event_bus.subscribe();
// Spawn listener task
tokio::spawn(async move {
loop {
match receiver.next().await {
Ok(event) => {
handle_event(event);
}
Err(EventReceiveError::BusDropped) => {
println!("Event bus closed");
break;
}
Err(EventReceiveError::Lagged { skipped }) => {
eprintln!("Warning: Missed {} events", skipped);
}
}
}
});
// Use the event bus with launcher operations...
}
fn handle_event(event: Event) {
match event {
Event::Launch(LaunchEvent::InstallStarted { version, total_bytes }) => {
println!("Installing {} ({} MB)", version, total_bytes / 1_000_000);
}
Event::Launch(LaunchEvent::InstallProgress { bytes }) => {
println!("Downloaded {} bytes", bytes);
}
Event::Java(JavaEvent::JavaDownloadStarted { distribution, version, total_bytes }) => {
println!("Downloading {} {} ({} MB)", distribution, version, total_bytes / 1_000_000);
}
_ => {}
}
}
use lighty_launcher::{JavaDistribution, Launch, Loader, VersionBuilder};
use lighty_auth::{offline::OfflineAuth, Authenticator};
use lighty_event::{EventBus, Event, LaunchEvent};
use directories::ProjectDirs;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let launcher_dir = ProjectDirs::from("fr", ".LightyLauncher", "")
.expect("Failed to get project directories");
// Create event bus
let event_bus = EventBus::new(1000);
let mut receiver = event_bus.subscribe();
// Spawn event listener
tokio::spawn(async move {
while let Ok(event) = receiver.next().await {
match event {
Event::Launch(LaunchEvent::InstallProgress { bytes }) => {
println!("Progress: {} bytes", bytes);
}
Event::Launch(LaunchEvent::InstallCompleted { version, .. }) => {
println!("Installation of {} completed!", version);
}
_ => {}
}
}
});
// Authenticate
let mut auth = OfflineAuth::new("Player");
let profile = auth.authenticate(Some(&event_bus)).await?;
// Build and launch
let mut version = VersionBuilder::new(
"my-instance",
Loader::Vanilla,
"",
"1.21.1",
&launcher_dir
);
version.launch(&profile, JavaDistribution::Temurin)
.with_event_bus(&event_bus)
.run()
.await?;
Ok(())
}
use lighty_event::{EventBus, Event, LaunchEvent, JavaEvent};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
#[tokio::main]
async fn main() {
let event_bus = EventBus::new(1000);
let mut receiver = event_bus.subscribe();
let total_bytes = Arc::new(AtomicU64::new(0));
let downloaded_bytes = Arc::new(AtomicU64::new(0));
tokio::spawn({
let total = Arc::clone(&total_bytes);
let downloaded = Arc::clone(&downloaded_bytes);
async move {
while let Ok(event) = receiver.next().await {
match event {
Event::Launch(LaunchEvent::InstallStarted { total_bytes: t, .. }) => {
total.store(t, Ordering::Relaxed);
downloaded.store(0, Ordering::Relaxed);
}
Event::Launch(LaunchEvent::InstallProgress { bytes }) => {
downloaded.fetch_add(bytes, Ordering::Relaxed);
let d = downloaded.load(Ordering::Relaxed);
let t = total.load(Ordering::Relaxed);
if t > 0 {
let percent = (d as f64 / t as f64) * 100.0;
print!("\rProgress: {:.1}%", percent);
std::io::Write::flush(&mut std::io::stdout()).ok();
}
}
Event::Launch(LaunchEvent::InstallCompleted { .. }) => {
println!("\nInstallation completed!");
}
_ => {}
}
}
}
});
// Use launcher...
}
use lighty_event::{EventBus, Event, LaunchEvent};
#[tokio::main]
async fn main() {
let event_bus = EventBus::new(1000);
// UI subscriber
let mut ui_receiver = event_bus.subscribe();
tokio::spawn(async move {
while let Ok(event) = ui_receiver.next().await {
// Update UI with event
update_ui(event);
}
});
// Logger subscriber
let mut log_receiver = event_bus.subscribe();
tokio::spawn(async move {
while let Ok(event) = log_receiver.next().await {
// Log event to file
log_event(&event);
}
});
// Analytics subscriber
let mut analytics_receiver = event_bus.subscribe();
tokio::spawn(async move {
while let Ok(event) = analytics_receiver.next().await {
// Send analytics
send_analytics(event);
}
});
// All subscribers receive the same events
// Use launcher with event_bus...
}
fn update_ui(event: Event) { /* ... */ }
fn log_event(event: &Event) { /* ... */ }
fn send_analytics(event: Event) { /* ... */ }
The event system provides custom error types:
EventReceiveErrorBusDropped - Event bus has been closedLagged { skipped } - Receiver fell behind, some events were missedEventTryReceiveErrorEmpty - No events available (non-blocking)BusDropped - Event bus has been closedLagged { skipped } - Receiver fell behindEventSendErrorNoReceivers - No active receivers (event not sent)Example with error handling:
use lighty_event::{EventReceiver, EventReceiveError};
async fn listen_events(mut receiver: EventReceiver) {
loop {
match receiver.next().await {
Ok(event) => {
// Handle event
println!("Received: {:?}", event);
}
Err(EventReceiveError::BusDropped) => {
eprintln!("Event bus closed, exiting listener");
break;
}
Err(EventReceiveError::Lagged { skipped }) => {
eprintln!("Warning: Receiver lagged, missed {} events", skipped);
// Continue listening, but some events were lost
}
}
}
}
The buffer size determines how many events can be buffered before older events are dropped:
// Small buffer for simple use cases
let event_bus = EventBus::new(100);
// Larger buffer for complex applications with slow receivers
let event_bus = EventBus::new(5000);
If receivers are too slow and the buffer fills up, the oldest events will be dropped and receivers will get a Lagged error.
For non-blocking event checking, use try_next():
use lighty_event::{EventReceiver, EventTryReceiveError};
fn poll_events(receiver: &mut EventReceiver) {
match receiver.try_next() {
Ok(event) => {
println!("Got event: {:?}", event);
}
Err(EventTryReceiveError::Empty) => {
// No events available right now
}
Err(EventTryReceiveError::BusDropped) => {
eprintln!("Event bus closed");
}
Err(EventTryReceiveError::Lagged { skipped }) => {
eprintln!("Missed {} events", skipped);
}
}
}
The event system is optional and can be disabled:
[dependencies]
lighty-launcher = { version = "0.6", features = ["events"] }
lighty-event = "0.6"
When the events feature is disabled, event-related code is compiled out with zero overhead.
All events implement Serialize and Deserialize (via serde), making them easy to:
use lighty_event::{Event, LaunchEvent};
use serde_json;
let event = Event::Launch(LaunchEvent::InstallStarted {
version: "1.21.1".to_string(),
total_bytes: 1000000,
});
// Serialize to JSON
let json = serde_json::to_string(&event).unwrap();
println!("{}", json);
// Deserialize from JSON
let deserialized: Event = serde_json::from_str(&json).unwrap();
lighty-event/
├── src/
│ ├── lib.rs # EventBus, EventReceiver
│ ├── errors.rs # Error types
│ └── module/ # Event definitions
│ ├── mod.rs # Module exports
│ ├── auth.rs # AuthEvent
│ ├── core.rs # CoreEvent
│ ├── java.rs # JavaEvent
│ ├── launch.rs # LaunchEvent
│ └── loader.rs # LoaderEvent
└── README.md
Contributions are welcome! Please feel free to submit a Pull Request.
Licensed under the MIT License. See LICENSE for details.
lighty-launcher - Main launcher cratelighty-auth - Authentication systemlighty-java - Java runtime managementlighty-core - Core utilities