Skip to content

Commit

Permalink
More comments to the throne of comment god!
Browse files Browse the repository at this point in the history
  • Loading branch information
Barafu committed Aug 25, 2024
1 parent 9f2ed20 commit a116647
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 46 deletions.
9 changes: 8 additions & 1 deletion src/app_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{
sync::{LazyLock, RwLock},
};

/// The one and only global settings object. Don't lock it for long.
pub static SETTINGS: LazyLock<RwLock<SettingsRaw>> = LazyLock::new(|| {
RwLock::new(SettingsRaw::read_from_file_default().unwrap())
});
Expand All @@ -26,8 +27,12 @@ pub struct SettingsRaw {
/// Show FPS statistics on primary screen.
pub show_fps: bool,

/// The dreams user selected to display.
pub selected_dreams: BTreeSet<String>,

/// Viewport mode, which is what viewport creation function of eframe
/// to use when creating secondary displays.
/// Has no meaning when there is only 1 display.
pub viewport_mode: ViewportMode,
}

Expand All @@ -44,12 +49,14 @@ impl Default for SettingsRaw {
}

impl SettingsRaw {
/// Read settings from default file location.
pub fn read_from_file_default() -> Result<Self> {
let path = Self::determine_settings_path()?;
log::info!("Reading settings from {}", path.display());
Self::read_from_file(&path)
}

/// Write settings to default file location.
pub fn write_to_file_default(&self) -> Result<()> {
let path = Self::determine_settings_path()?;
log::info!("Writing settings to {}", path.display());
Expand All @@ -68,7 +75,7 @@ impl SettingsRaw {
Ok(())
}

/// Finds the path to the settrings file. First tries if dream_settings.toml
/// Finds the path to the settings file. First tries if dream_settings.toml
/// exists in the same directory as the executable. If not, tries if it exists
/// in the user's settings directory. If not, creates it in the user
/// settings directory. If creation fails, returns error.
Expand Down
40 changes: 21 additions & 19 deletions src/dreamconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ enum ActivePanel {
Dream(DreamId), // Settings of a dream with given ID
}

/// The EGUI App object that provides selecting and configuring the dreams.
pub struct DreamConfigApp {
/// What tab is selected currently.
active_panel: ActivePanel,
/// A list of all dreams, to call their settings functions from.
zoo: BTreeMap<String, ADream>,
/// The state of the settings as they were saved last.
/// If current state differs from that, the save button will be enabled.
saved_settings: SettingsRaw,
}

impl eframe::App for DreamConfigApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// The status bar
egui::TopBottomPanel::bottom("bottom_panel").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.with_layout(
Expand All @@ -44,6 +50,7 @@ impl eframe::App for DreamConfigApp {
);
});
});
// The main contents: a list of tabs on the left and a panel on the right
egui::CentralPanel::default().show(ctx, |ui| {
ui.horizontal(|ui| {
ui.vertical(|ui| {
Expand Down Expand Up @@ -85,9 +92,6 @@ impl eframe::App for DreamConfigApp {
});
});
});
for dream in self.zoo.values() {
dream.read().unwrap().store();
}
}
}

Expand All @@ -113,6 +117,7 @@ impl DreamConfigApp {
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
}

/// Generic settings panel UI
fn draw_generic(&mut self, ui: &mut egui::Ui) {
let settings = &mut SETTINGS.write().unwrap();
ui.heading("Dream Spinner");
Expand All @@ -139,13 +144,14 @@ impl DreamConfigApp {
ViewportMode::Deferred.to_string(),
).on_hover_text("Fill all screens independently. Better FPS, but may cause problems.");
});
ui.label("Has no effect if there is only 1 screen");
}
}

/// UI panel to select which dreams to run.
fn draw_dream_select(&mut self, ui: &mut egui::Ui) {
// The list of selected dreams must never be completely empty.
// So the idea is not to save the change if the user
// So the solution is not to save the change if the user
// unchecks the last dream.
let settings = &mut SETTINGS.write().unwrap();

Expand All @@ -168,21 +174,17 @@ impl DreamConfigApp {
ui.vertical(|ui| {
ui.heading("Dream Spinner");
ui.separator();
self.powered_by_egui_and_eframe(ui);
});
}

fn powered_by_egui_and_eframe(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0;
ui.label("Powered by ");
ui.hyperlink_to("egui", "https://github.com/emilk/egui");
ui.label(" and ");
ui.hyperlink_to(
"eframe",
"https://github.com/emilk/egui/tree/master/crates/eframe",
);
ui.label(".");
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0;
ui.label("Powered by ");
ui.hyperlink_to("egui", "https://github.com/emilk/egui");
ui.label(" and ");
ui.hyperlink_to(
"eframe",
"https://github.com/emilk/egui/tree/master/crates/eframe",
);
ui.label(".");
});
});
}
}
8 changes: 5 additions & 3 deletions src/dreams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ pub trait Dream: Sync + Send {
fn name(&self) -> &'static str;

/// Prepare dream for rendering (load resources, initialize RNG etc.)
fn prepare(&mut self) {}
fn prepare_dream(&mut self) {}

/// Return true if prepare() takes noticeable time enough to warrant a loading screen
fn needs_loading(&self) -> bool {
fn require_load_screen(&self) -> bool {
false
}

Expand All @@ -52,7 +52,9 @@ pub trait Dream: Sync + Send {
fn preferred_update_rate(&self) -> DreamUpdateRate;

/// Dream type determines what kind of window to perpare for it.
fn get_type(&self) -> DreamType;
fn get_type(&self) -> DreamType {
DreamType::Egui
}

/// Draws the dream in egui. This function MUST be thread-safe.
fn dream_egui(&self, _ui: &mut egui::Ui) {
Expand Down
6 changes: 1 addition & 5 deletions src/dreams/dendraclock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,7 @@ impl Dream for DendraClockDream {
self.options_ui(ui);
}

fn prepare(&mut self) {}

fn needs_loading(&self) -> bool {
false
}
fn prepare_dream(&mut self) {}

fn store(&self) {
let txt = toml::to_string(&self.dream_settings).unwrap();
Expand Down
8 changes: 3 additions & 5 deletions src/dreams/monet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,13 @@ impl Dream for MonetDream {
DREAM_NAME
}

fn get_type(&self) -> super::DreamType {
return super::DreamType::Egui;
}

fn preferred_update_rate(&self) -> super::DreamUpdateRate {
super::DreamUpdateRate::Fixed(0.5)
}

fn dream_egui(&self, _ui: &mut egui::Ui) {}
fn dream_egui(&self, _ui: &mut egui::Ui) {
unimplemented!()
}

fn config_egui(&mut self, _ui: &mut egui::Ui) {}
}
17 changes: 8 additions & 9 deletions src/dreams/solid_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ pub const DREAM_NAME: &'static str = "Solid Color";
/// This dream is intended to be as primitive as possible to serve as example
/// of how to implement Dream trait.
///
/// This dream stores color separately from dream_settings, because Color32 is not serializable.
pub struct SolidColorDream {
dream_settings: SolidColorSettings,
}

#[derive(PartialEq, Debug, Clone, serde::Deserialize, serde::Serialize)]
#[serde(default)]
struct SolidColorSettings {
color: egui::Color32, // Stored as hex, because Color32 is not serializable
color: egui::Color32, // The color of the background
}

impl Default for SolidColorSettings {
Expand Down Expand Up @@ -44,20 +43,19 @@ impl Dream for SolidColorDream {
DREAM_NAME
}

fn get_type(&self) -> DreamType {
return DreamType::Egui;
}

fn preferred_update_rate(&self) -> DreamUpdateRate {
DreamUpdateRate::Fixed(5.0)
}

fn dream_egui(&self, ui: &mut egui::Ui) {
// This is how to create a painter that covers the whole screen.
// Most dreams should use that.
let painter = egui::Painter::new(
ui.ctx().clone(),
ui.layer_id(),
ui.available_rect_before_wrap(),
);
// Just fill the whole painter with color.
painter.rect_filled(
ui.available_rect_before_wrap(),
0.0,
Expand All @@ -66,11 +64,12 @@ impl Dream for SolidColorDream {
}

fn config_egui(&mut self, ui: &mut egui::Ui) {
ui.color_edit_button_srgba(&mut self.dream_settings.color);
ui.horizontal(|ui| {
ui.label("Color: ");
ui.color_edit_button_srgba(&mut self.dream_settings.color);
});
}

fn prepare(&mut self) {}

fn store(&self) {
let txt = toml::to_string(&self.dream_settings).unwrap();
SETTINGS
Expand Down
16 changes: 12 additions & 4 deletions src/dreamspinner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ use rand::Rng;
use crate::app_settings::{ViewportMode, SETTINGS};
use crate::dreams::*;

/// Update FPS measurements every given time in seconds
const FPS_MEASURE_UPDATE_SECONDS: f32 = 2.0;

/// Makes FPS measurements by accepting a timestamp once every frame.
struct FPSMeasureData {
avg: f32,
worst: f32,
Expand All @@ -25,7 +27,7 @@ impl FPSMeasureData {
fn new() -> Self {
Self { avg: -1.0, worst: -1.0, render_timestamps: Vec::new() }
}

/// Call this once per frame
fn record_timestamp(&mut self) {
self.render_timestamps.push(Instant::now());
let sum = self
Expand All @@ -51,9 +53,10 @@ impl FPSMeasureData {
}
}

/// The EGUI App object that provides selecting and displaying the dream
pub struct DreamSpinner {
first_frame: bool,
#[allow(dead_code)]
/// The dream chosen to be displayed.
dream: Arc<RwLock<dyn Dream>>,
primary_display: DisplayInfo,
secondary_displays: Vec<DisplayInfo>,
Expand Down Expand Up @@ -104,7 +107,7 @@ impl DreamSpinner {
let random_id =
selected_dreams.iter().nth(random_index).unwrap().to_string();
let dream = build_dream_by_id(&random_id);
dream.write().unwrap().prepare();
dream.write().unwrap().prepare_dream();
dream
}
}
Expand Down Expand Up @@ -200,6 +203,8 @@ impl eframe::App for DreamSpinner {
}

impl DreamSpinner {
/// Adds input handling to dream windows. Basically, makes the window close
/// on most inputs, according to settings.
fn set_input(ui: &mut egui::Ui) {
let mut need_quit = false;
ui.input(|input| {
Expand All @@ -209,6 +214,8 @@ impl DreamSpinner {
});
ui.output_mut(|o| o.cursor_icon = egui::CursorIcon::None);
if need_quit {
// Close the app by pressing close signal to every viewport and
// let egui handle the rest.
let mut ids: Vec<egui::ViewportId> = Vec::new();
ui.ctx().input(|i| {
ids = i.raw.viewports.keys().cloned().collect();
Expand All @@ -220,7 +227,8 @@ impl DreamSpinner {
}
}

// Detects all viewports and requests updates to all of them
/// Requests an update for the given viewport. Detects the appropriate time
/// to send with the update request.
fn request_updates(
ui: &mut egui::Ui,
is_primary_viewport: bool,
Expand Down

0 comments on commit a116647

Please sign in to comment.