Skip to content

Commit 5ceb974

Browse files
committed
wip: work on probe crate
1 parent a7d307c commit 5ceb974

29 files changed

Lines changed: 2252 additions & 193 deletions

File tree

Cargo.lock

Lines changed: 34 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ futures = "0.3.30"
4646
futures-util = "0.3.31"
4747
headers = "0.4.1"
4848
image = "0.25.5"
49+
macaddr = { version = "1", features = ["serde"] }
4950
native_db = { git = "https://github.com/vincent-herlemont/native_db", features = [
5051
"tokio",
5152
] }

sandpolis-client/src/gui/layer_ext.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use bevy::prelude::*;
88
use bevy_egui::egui;
9-
use sandpolis_core::{InstanceId, LayerName};
9+
use sandpolis_core::{InstanceId, InstanceType, LayerName};
1010

1111
/// Trait for layer-specific GUI extensions.
1212
///
@@ -56,6 +56,22 @@ pub trait LayerGuiExtension: Send + Sync + 'static {
5656
fn register_systems(&self, app: &mut App) {
5757
let _ = app;
5858
}
59+
60+
/// Returns which instance types should be visible when this layer is active.
61+
///
62+
/// By default, all instance types are visible. Layers can override this
63+
/// to filter which nodes appear in the world view.
64+
fn visible_instance_types(&self) -> &'static [InstanceType] {
65+
&[InstanceType::Server, InstanceType::Agent, InstanceType::Client]
66+
}
67+
68+
/// Returns whether probe nodes should be visible when this layer is active.
69+
///
70+
/// Probes are special nodes that are attached to agents. By default, probes
71+
/// are not visible. Only the Probe layer should return true.
72+
fn show_probe_nodes(&self) -> bool {
73+
false
74+
}
5975
}
6076

6177
/// Information about an activity type that can be visualized.

sandpolis-client/src/gui/layer_visuals.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::gui::input::CurrentLayer;
2+
use crate::gui::layer_ext::get_extension_for_layer;
23
use crate::gui::node::{NeedsScaling, NodeEntity, NodeSvg};
34
use crate::gui::queries;
45
use bevy::prelude::*;
56
use bevy_svg::prelude::{Origin, Svg2d};
6-
use sandpolis_core::LayerName;
7+
use sandpolis_core::{InstanceType, LayerName};
78

89
/// Update node SVG images when layer changes or for newly spawned nodes
910
pub fn update_node_svgs_for_layer(
@@ -208,3 +209,71 @@ fn get_layer_color_tint(
208209
_ => Color::WHITE, // No tint for other layers
209210
}
210211
}
212+
213+
/// Update node visibility based on the current layer's visible instance types.
214+
///
215+
/// Each layer can specify which instance types (Server, Agent, Client) should be
216+
/// visible when that layer is active. This system hides nodes that don't match
217+
/// the current layer's filter criteria.
218+
pub fn update_node_visibility_for_layer(
219+
current_layer: Res<CurrentLayer>,
220+
mut node_query: Query<(&NodeEntity, &mut Visibility)>,
221+
) {
222+
// Only update when layer changes
223+
if !current_layer.is_changed() {
224+
return;
225+
}
226+
227+
// Get the visible instance types for the current layer
228+
let visible_types = get_visible_instance_types_for_layer(&current_layer);
229+
230+
for (node_entity, mut visibility) in node_query.iter_mut() {
231+
let instance_id = node_entity.instance_id;
232+
233+
// Check if this node's instance type matches any of the visible types
234+
let should_be_visible = visible_types.iter().any(|instance_type| {
235+
instance_id.is_type(*instance_type)
236+
});
237+
238+
*visibility = if should_be_visible {
239+
Visibility::Inherited
240+
} else {
241+
Visibility::Hidden
242+
};
243+
}
244+
}
245+
246+
/// Get the visible instance types for a layer.
247+
///
248+
/// This checks if there's a LayerGuiExtension for the layer and uses its
249+
/// visible_instance_types() method. If no extension exists, falls back to
250+
/// default behavior based on layer name.
251+
fn get_visible_instance_types_for_layer(layer: &LayerName) -> &'static [InstanceType] {
252+
// First, check if there's a registered extension for this layer
253+
if let Some(ext) = get_extension_for_layer(layer) {
254+
return ext.visible_instance_types();
255+
}
256+
257+
// Fall back to default behavior based on layer name
258+
match layer.name() {
259+
// Network layer shows all instance types
260+
"Network" => &[InstanceType::Server, InstanceType::Agent, InstanceType::Client],
261+
262+
// Agent-focused layers only show servers and agents
263+
"Inventory" | "Filesystem" | "Shell" | "Desktop" | "Probe" => {
264+
&[InstanceType::Server, InstanceType::Agent]
265+
}
266+
267+
// Client layer only shows servers and clients
268+
"Client" => &[InstanceType::Server, InstanceType::Client],
269+
270+
// Server layer only shows servers
271+
"Server" => &[InstanceType::Server],
272+
273+
// Agent layer only shows servers and agents
274+
"Agent" => &[InstanceType::Server, InstanceType::Agent],
275+
276+
// Default: show all
277+
_ => &[InstanceType::Server, InstanceType::Agent, InstanceType::Client],
278+
}
279+
}

sandpolis-core/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ pub enum InstanceType {
194194
/// Sandpolis network. All networks include at least one server
195195
/// instance.
196196
Server,
197+
// Probes are not technically instances, but they can connect to proper
198+
// agents/server instances and appear like standalone instances.
197199
}
198200

199201
impl InstanceType {

sandpolis-desktop/src/client/gui.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ impl LayerGuiExtension for DesktopGuiExtension {
142142
size: 10.0,
143143
}]
144144
}
145+
146+
fn visible_instance_types(&self) -> &'static [sandpolis_core::InstanceType] {
147+
// Desktop layer shows servers and agents (not clients)
148+
&[sandpolis_core::InstanceType::Server, sandpolis_core::InstanceType::Agent]
149+
}
145150
}
146151

147152
/// Static instance of the desktop GUI extension.

sandpolis-filesystem/src/client/gui.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ impl LayerGuiExtension for FilesystemGuiExtension {
323323
size: 8.0,
324324
}]
325325
}
326+
327+
fn visible_instance_types(&self) -> &'static [sandpolis_core::InstanceType] {
328+
// Filesystem layer shows servers and agents (not clients)
329+
&[sandpolis_core::InstanceType::Server, sandpolis_core::InstanceType::Agent]
330+
}
326331
}
327332

328333
/// Static instance of the filesystem GUI extension.

sandpolis-inventory/src/client/gui.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,11 @@ impl LayerGuiExtension for InventoryGuiExtension {
356356
size: 7.0,
357357
}]
358358
}
359+
360+
fn visible_instance_types(&self) -> &'static [sandpolis_core::InstanceType] {
361+
// Inventory layer shows servers and agents (not clients)
362+
&[sandpolis_core::InstanceType::Server, sandpolis_core::InstanceType::Agent]
363+
}
359364
}
360365

361366
/// Static instance of the inventory GUI extension.

sandpolis-network/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use url::Url;
4848
pub mod cli;
4949
pub mod config;
5050
pub mod messages;
51-
pub mod routes;
51+
pub mod ping;
5252
pub mod stream;
5353

5454
#[cfg(feature = "server")]

sandpolis-network/src/messages.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
use sandpolis_core::InstanceId;
22
use serde::{Deserialize, Serialize};
33

4-
#[derive(Serialize, Deserialize)]
5-
pub struct PingRequest {
6-
pub id: InstanceId,
7-
}
8-
9-
#[derive(Serialize, Deserialize)]
10-
pub struct PingResponse {
11-
pub time: u64,
12-
pub id: InstanceId,
13-
pub from: Option<Box<PingResponse>>,
14-
}
15-
16-
#[derive(Serialize, Deserialize)]
17-
pub struct PollRequest;
18-
19-
#[derive(Serialize, Deserialize)]
20-
pub struct PollResponse(Vec<u8>);
21-
224
/// Request the server for a new direct connection to an agent.
235
#[cfg(any(feature = "server", feature = "client"))]
246
#[derive(Serialize, Deserialize)]

0 commit comments

Comments
 (0)