mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
Use filtered subscriptions to save data
This commit is contained in:
1 parent
ea144863f9
commit
38d5fdfdba
4 files changed
+67
-16
No files matched your search
@@ -759,8 +759,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
|
||||
const updateEvent = new ChartTagDataEvent(instance_id, tag_data);
|
||||
|
||||
// Broadcast to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(updateEvent);
|
||||
// Broadcast to subscribed web clients only with instance/surface filter
|
||||
this.controller.subscriptions.broadcast(updateEvent, `${instance_id}:${tag_data.surface}`);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing chart tag data: ${err}`);
|
||||
@@ -796,8 +796,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
chunk
|
||||
);
|
||||
|
||||
// Broadcast to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(updateEvent);
|
||||
// Broadcast to subscribed web clients only with instance/surface filter
|
||||
this.controller.subscriptions.broadcast(updateEvent, `${instance_id}:${surface}`);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing tile data: ${err}`);
|
||||
@@ -1014,8 +1014,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
}
|
||||
this.recipeSavingQueue.get(tileKey)!.push(...buffersToWrite);
|
||||
|
||||
// Broadcast live update to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(event);
|
||||
// Broadcast live update to subscribed web clients only with instance/surface filter
|
||||
this.controller.subscriptions.broadcast(event, `${instance_id}:${event.recipe_data.surface}`);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing recipe data: ${err}`);
|
||||
@@ -1085,8 +1085,8 @@ export class ControllerPlugin extends BaseControllerPlugin {
|
||||
|
||||
const updateEvent = new PlayerPositionEvent(instance_id, player_data);
|
||||
|
||||
// Broadcast to subscribed web clients only
|
||||
this.controller.subscriptions.broadcast(updateEvent);
|
||||
// Broadcast to subscribed web clients only with instance/surface filter
|
||||
this.controller.subscriptions.broadcast(updateEvent, `${instance_id}:${player_data.surface}`);
|
||||
|
||||
} catch (err) {
|
||||
this.logger.error(`Error processing player position data: ${err}`);
|
||||
|
||||
@@ -852,6 +852,13 @@ export default function CanvasMinimapPage() {
|
||||
loadSurfaceForceData();
|
||||
}, []);
|
||||
|
||||
// Keep the minimap subscription filters in sync with current selection
|
||||
useEffect(() => {
|
||||
const plugin = control.plugins.get("minimap") as import("./index").WebPlugin;
|
||||
if (!plugin) { return; }
|
||||
plugin.setInstanceSurfaceFilter(selectedInstance, selectedSurface || null);
|
||||
}, [control, selectedInstance, selectedSurface]);
|
||||
|
||||
// Set up keyboard and mouse event listeners (one-time setup)
|
||||
useEffect(() => {
|
||||
const isTypingInInput = (): boolean => {
|
||||
|
||||
@@ -37,6 +37,13 @@ export default function MinimapPage() {
|
||||
loadSurfaceForceData();
|
||||
}, []);
|
||||
|
||||
// Keep subscription filters in sync with selection even on the legacy page
|
||||
useEffect(() => {
|
||||
const plugin = control.plugins.get("minimap") as import("./index").WebPlugin;
|
||||
if (!plugin) { return; }
|
||||
plugin.setInstanceSurfaceFilter(selectedInstance, selectedSurface || null);
|
||||
}, [control, selectedInstance, selectedSurface]);
|
||||
|
||||
const loadSurfaceForceData = async () => {
|
||||
const response = await fetch(`${window.location.origin}/api/minimap/surfaces`);
|
||||
const data = await response.json();
|
||||
|
||||
@@ -13,6 +13,7 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
|
||||
// Track subscription state
|
||||
private subscribed = false;
|
||||
private currentFilters: string[] | undefined = undefined;
|
||||
|
||||
async init() {
|
||||
this.pages = [
|
||||
@@ -32,11 +33,45 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
}
|
||||
|
||||
onControllerConnectionEvent(event: "connect" | "drop" | "resume" | "close") {
|
||||
if (event === "connect") {
|
||||
if (event === "connect" || event === "resume") {
|
||||
this.updateSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
// Update instance/surface filter used for subscriptions.
|
||||
async setInstanceSurfaceFilter(instanceId: number | null, surface: string | null) {
|
||||
const newFilters = (instanceId !== null && surface) ? [`${instanceId}:${surface}`] : undefined;
|
||||
|
||||
// No change
|
||||
const prev = this.currentFilters;
|
||||
const same = (
|
||||
(prev === undefined && newFilters === undefined)
|
||||
|| (Array.isArray(prev) && Array.isArray(newFilters)
|
||||
&& prev.length === newFilters.length
|
||||
&& prev.every((v, i) => v === newFilters[i]))
|
||||
);
|
||||
if (same) { return; }
|
||||
|
||||
// If we had previous filters and callbacks active, remove those filters first
|
||||
if (this.hasActiveCallbacks() && prev && prev.length > 0) {
|
||||
try {
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", false, 0, prev));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", false, 0, prev));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", false, 0, prev));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", false, 0, prev));
|
||||
} catch (err) {
|
||||
this.logger.error(`Failed to remove previous minimap filters: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.currentFilters = newFilters;
|
||||
|
||||
// Apply new filters if we have active callbacks
|
||||
if (this.hasActiveCallbacks()) {
|
||||
await this.updateSubscriptions();
|
||||
}
|
||||
}
|
||||
|
||||
private async updateSubscriptions() {
|
||||
if (!this.control.connector.connected) {
|
||||
return;
|
||||
@@ -44,18 +79,20 @@ export class WebPlugin extends BaseWebPlugin {
|
||||
|
||||
const shouldSubscribe = this.hasActiveCallbacks();
|
||||
|
||||
if (shouldSubscribe && !this.subscribed) {
|
||||
// Subscribe to all minimap events
|
||||
// Only subscribe if we both have active callbacks and a specific filter set
|
||||
if (shouldSubscribe && this.currentFilters && this.currentFilters.length > 0) {
|
||||
// Always (re)send with current filters when we have active callbacks
|
||||
const filters = this.currentFilters;
|
||||
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));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", true, 0, filters));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:ChartTagDataEvent", true, 0, filters));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:RecipeDataEvent", true, 0, filters));
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:PlayerPositionEvent", true, 0, filters));
|
||||
this.subscribed = true;
|
||||
} catch (err) {
|
||||
this.logger.error(`Failed to subscribe to minimap events: ${err}`);
|
||||
}
|
||||
} else if (!shouldSubscribe && this.subscribed) {
|
||||
} else if ((!shouldSubscribe || !this.currentFilters || this.currentFilters.length === 0) && this.subscribed) {
|
||||
// Unsubscribe from all minimap events
|
||||
try {
|
||||
await this.control.send(new lib.SubscriptionRequest("minimap:TileDataEvent", false));
|
||||
|
||||
Reference in new issue
Block a user