mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 23:04:52 +09:00
Use SubscriptionController
This commit is contained in:
1 parent
70ef8a60ad
commit
48437a5f6c
2 files changed
+74
-12
No files matched your search
@@ -98,6 +98,7 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
await fs.ensureDir(this.recipeTilesPath);
|
||||
await fs.ensureDir(this.playerPositionsPath);
|
||||
|
||||
// Handle incoming events from instances
|
||||
this.controller.handle(TileDataEvent, this.handleTileDataEvent.bind(this));
|
||||
this.controller.handle(ChartTagDataEvent, this.handleChartTagDataEvent.bind(this));
|
||||
this.controller.handle(GetRawTileRequest, this.handleGetRawTileRequest.bind(this));
|
||||
@@ -107,6 +108,12 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
this.controller.handle(PlayerPositionEvent, this.handlePlayerPositionEvent.bind(this));
|
||||
this.controller.handle(GetPlayerPathRequest, this.handleGetPlayerPathRequest.bind(this));
|
||||
|
||||
// Register events as subscribable for web clients
|
||||
this.controller.subscriptions.handle(TileDataEvent);
|
||||
this.controller.subscriptions.handle(ChartTagDataEvent);
|
||||
this.controller.subscriptions.handle(RecipeDataEvent);
|
||||
this.controller.subscriptions.handle(PlayerPositionEvent);
|
||||
|
||||
// Set up HTTP routes for serving tiles
|
||||
this.setupTileRoutes();
|
||||
|
||||
@@ -750,11 +757,10 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
// Queue for batch saving
|
||||
this.chartTagQueues.get(fileKey)!.push(enrichedTagData);
|
||||
|
||||
// Send live update to connected web clients
|
||||
const updateEvent = new ChartTagDataEvent(instance_id, tag_data);
|
||||
|
||||
// Broadcast to web clients
|
||||
this.controller.sendTo(new lib.Address(lib.Address.broadcast, lib.Address.control), updateEvent);
|
||||
// Broadcast to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(updateEvent);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing chart tag data: ${err}`);
|
||||
@@ -780,7 +786,6 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
}
|
||||
this.chunkSavingQueue.get(tileName)!.set(chunkName, { data: chunk, tick });
|
||||
|
||||
// Send live update to connected web clients
|
||||
const updateEvent = new TileDataEvent(
|
||||
instance_id,
|
||||
surface,
|
||||
@@ -791,8 +796,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
chunk
|
||||
);
|
||||
|
||||
// Broadcast to web clients
|
||||
this.controller.sendTo(new lib.Address(lib.Address.broadcast, lib.Address.control), updateEvent);
|
||||
// Broadcast to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(updateEvent);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing tile data: ${err}`);
|
||||
@@ -1009,8 +1014,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
}
|
||||
this.recipeSavingQueue.get(tileKey)!.push(...buffersToWrite);
|
||||
|
||||
// broadcast live update
|
||||
this.controller.sendTo(new lib.Address(lib.Address.broadcast, lib.Address.control), event);
|
||||
// Broadcast live update to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(event);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing recipe data: ${err}`);
|
||||
@@ -1078,11 +1083,10 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
// Queue for batch saving
|
||||
this.playerPositionQueues.get(fileKey)!.push(enrichedPlayerData);
|
||||
|
||||
// Send live update to connected web clients
|
||||
const updateEvent = new PlayerPositionEvent(instance_id, player_data);
|
||||
|
||||
// Broadcast to web clients
|
||||
this.controller.sendTo(new lib.Address(lib.Address.broadcast, lib.Address.control), updateEvent);
|
||||
// Broadcast to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(updateEvent);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing player position data: ${err}`);
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import React from "react";
|
||||
import { BaseWebPlugin } from "@clusterio/web_ui";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import CanvasMinimapPage from "./CanvasMinimapPage";
|
||||
import { TileDataEvent, ChartTagDataEvent, RecipeDataEvent, PlayerPositionEvent } from "../messages";
|
||||
|
||||
export class WebPlugin extends BaseWebPlugin {
|
||||
// Callback arrays for minimap updates
|
||||
tileUpdateCallbacks: Array<(event: TileDataEvent) => void> = [];
|
||||
chartTagUpdateCallbacks: Array<(event: ChartTagDataEvent) => void> = [];
|
||||
recipeUpdateCallbacks: Array<(event: RecipeDataEvent) => void> = [];
|
||||
playerPositionUpdateCallbacks: Array<(event: PlayerPositionEvent) => void> = [];
|
||||
|
||||
// Track subscription state
|
||||
private subscribed = false;
|
||||
|
||||
async init() {
|
||||
this.pages = [
|
||||
{
|
||||
@@ -19,13 +24,58 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
},
|
||||
];
|
||||
|
||||
// Handle tile update events from the controller
|
||||
// Handle minimap events from the controller
|
||||
this.control.handle(TileDataEvent, this.handleTileDataEvent.bind(this));
|
||||
this.control.handle(ChartTagDataEvent, this.handleChartTagDataEvent.bind(this));
|
||||
this.control.handle(RecipeDataEvent, this.handleRecipeDataEvent.bind(this));
|
||||
this.control.handle(PlayerPositionEvent, this.handlePlayerPositionEvent.bind(this));
|
||||
}
|
||||
|
||||
onControllerConnectionEvent(event: "connect" | "drop" | "resume" | "close") {
|
||||
if (event === "connect") {
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
private async updateSubscriptions() {
|
||||
if (!this.control.connector.connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldSubscribe = this.hasActiveCallbacks();
|
||||
|
||||
if (shouldSubscribe && !this.subscribed) {
|
||||
// Subscribe to all minimap events
|
||||
try {
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", true));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", true));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", true));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", true));
|
||||
this.subscribed = true;
|
||||
} catch (err) {
|
||||
this.logger.error(`Failed to subscribe to minimap events: ${err}`);
|
||||
}
|
||||
} else if (!shouldSubscribe && this.subscribed) {
|
||||
// Unsubscribe from all minimap events
|
||||
try {
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", false));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", false));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", false));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", false));
|
||||
this.subscribed = false;
|
||||
} catch (err) {
|
||||
this.logger.error(`Failed to unsubscribe from minimap events: ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private hasActiveCallbacks(): boolean {
|
||||
return this.tileUpdateCallbacks.length > 0
|
||||
|| this.chartTagUpdateCallbacks.length > 0
|
||||
|| this.recipeUpdateCallbacks.length > 0
|
||||
|| this.playerPositionUpdateCallbacks.length > 0;
|
||||
}
|
||||
|
||||
async handleTileDataEvent(event: TileDataEvent) {
|
||||
// Notify all registered callbacks
|
||||
for (let callback of this.tileUpdateCallbacks) {
|
||||
@@ -53,6 +103,7 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
|
||||
onTileUpdate(callback: (event: TileDataEvent) => void) {
|
||||
this.tileUpdateCallbacks.push(callback);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
offTileUpdate(callback: (event: TileDataEvent) => void) {
|
||||
@@ -61,10 +112,12 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
throw new Error("callback is not registered");
|
||||
}
|
||||
this.tileUpdateCallbacks.splice(index, 1);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
onChartTagUpdate(callback: (event: ChartTagDataEvent) => void) {
|
||||
this.chartTagUpdateCallbacks.push(callback);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
offChartTagUpdate(callback: (event: ChartTagDataEvent) => void) {
|
||||
@@ -73,10 +126,12 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
throw new Error("callback is not registered");
|
||||
}
|
||||
this.chartTagUpdateCallbacks.splice(index, 1);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
onRecipeUpdate(callback: (event: RecipeDataEvent) => void) {
|
||||
this.recipeUpdateCallbacks.push(callback);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
offRecipeUpdate(callback: (event: RecipeDataEvent) => void) {
|
||||
@@ -85,10 +140,12 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
throw new Error("callback is not registered");
|
||||
}
|
||||
this.recipeUpdateCallbacks.splice(index, 1);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
onPlayerPositionUpdate(callback: (event: PlayerPositionEvent) => void) {
|
||||
this.playerPositionUpdateCallbacks.push(callback);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
|
||||
offPlayerPositionUpdate(callback: (event: PlayerPositionEvent) => void) {
|
||||
@@ -97,5 +154,6 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
throw new Error("callback is not registered");
|
||||
}
|
||||
this.playerPositionUpdateCallbacks.splice(index, 1);
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user