Skip to content

Commit

Permalink
Merge pull request #201 from ldubos/timeline-api
Browse files Browse the repository at this point in the history
Add ISteamTimeline supports
  • Loading branch information
Noxime authored Sep 5, 2024
2 parents 3cdd5a6 + 5abbe12 commit 60f9535
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub use crate::networking::*;
pub use crate::remote_play::*;
pub use crate::remote_storage::*;
pub use crate::server::*;
pub use crate::timeline::*;
pub use crate::ugc::*;
pub use crate::user::*;
pub use crate::user_stats::*;
Expand All @@ -55,6 +56,7 @@ mod remote_play;
mod remote_storage;
pub mod screenshots;
mod server;
pub mod timeline;
mod ugc;
mod user;
mod user_stats;
Expand Down Expand Up @@ -426,6 +428,19 @@ where
}
}

/// Returns an accessor to the steam timeline interface
pub fn timeline(&self) -> Timeline<Manager> {
unsafe {
let timeline = sys::SteamAPI_SteamTimeline_v001();

Timeline {
timeline,
disabled: timeline.is_null(),
_inner: self.inner.clone(),
}
}
}

pub fn networking_messages(&self) -> networking_messages::NetworkingMessages<Manager> {
unsafe {
let net = sys::SteamAPI_SteamNetworkingMessages_SteamAPI_v002();
Expand Down
141 changes: 141 additions & 0 deletions src/timeline.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use super::*;
use std::time::Duration;

pub struct Timeline<Manager> {
pub(crate) timeline: *mut sys::ISteamTimeline,
/// Whether the client's steam API is not recent enough.
pub(crate) disabled: bool,
pub(crate) _inner: Arc<Inner<Manager>>,
}

pub enum TimelineGameMode {
/// The player is fully loaded into the game and playing.
Playing,
/// The player is in a multiplayer lobby.
Staging,
/// The player is in the game's main menu or a pause menu.
Menus,
/// The player is waiting for a loading screen.
LoadingScreen,
}

impl From<TimelineGameMode> for sys::ETimelineGameMode {
fn from(mode: TimelineGameMode) -> Self {
match mode {
TimelineGameMode::Playing => sys::ETimelineGameMode::k_ETimelineGameMode_Playing,
TimelineGameMode::Staging => sys::ETimelineGameMode::k_ETimelineGameMode_Staging,
TimelineGameMode::Menus => sys::ETimelineGameMode::k_ETimelineGameMode_Menus,
TimelineGameMode::LoadingScreen => {
sys::ETimelineGameMode::k_ETimelineGameMode_LoadingScreen
}
}
}
}

pub enum TimelineEventClipPriority {
/// This event is not appropriate as a clip.
None,
/// The user may want to make a clip around this event.
Standard,
/// The player will be likely to want a clip around event,
/// and those clips should be promoted more prominently than clips with the [TimelineEventClipPriority::Standard] priority.
Featured,
}

impl From<TimelineEventClipPriority> for sys::ETimelineEventClipPriority {
fn from(priority: TimelineEventClipPriority) -> Self {
match priority {
TimelineEventClipPriority::None => {
sys::ETimelineEventClipPriority::k_ETimelineEventClipPriority_None
}
TimelineEventClipPriority::Standard => {
sys::ETimelineEventClipPriority::k_ETimelineEventClipPriority_Standard
}
TimelineEventClipPriority::Featured => {
sys::ETimelineEventClipPriority::k_ETimelineEventClipPriority_Featured
}
}
}
}

impl<Manager> Timeline<Manager> {
/// Changes the color of the timeline bar.
pub fn set_timeline_game_mode(&self, mode: TimelineGameMode) {
if self.disabled {
return;
}

unsafe {
sys::SteamAPI_ISteamTimeline_SetTimelineGameMode(self.timeline, mode.into());
}
}

/// Sets a description for the current game state in the timeline.
/// These help the user to find specific moments in the timeline when saving clips.
/// Setting a new state description replaces any previous description.
pub fn set_timeline_state_description(&self, description: &str, duration: Duration) {
if self.disabled {
return;
}

let description = CString::new(description).unwrap();

unsafe {
sys::SteamAPI_ISteamTimeline_SetTimelineStateDescription(
self.timeline,
description.as_ptr(),
duration.as_secs_f32(),
)
}
}

/// Clears the previous set game state in the timeline.
pub fn clear_timeline_state_description(&self, duration: Duration) {
if self.disabled {
return;
}

unsafe {
sys::SteamAPI_ISteamTimeline_ClearTimelineStateDescription(
self.timeline,
duration.as_secs_f32(),
)
}
}

/// Use this to mark an event on the Timeline.
/// The event can be instantaneous or take some amount of time to complete,
/// depending on the value passed in `duration`.
pub fn add_timeline_event(
&self,
icon: &str,
title: &str,
description: &str,
priority: u32,
start_offset_seconds: f32,
duration: Duration,
clip_priority: TimelineEventClipPriority,
) {
if self.disabled {
return;
}

let icon = CString::new(icon).unwrap();
let title = CString::new(title).unwrap();
let description = CString::new(description).unwrap();
let duration = duration.as_secs_f32();

unsafe {
sys::SteamAPI_ISteamTimeline_AddTimelineEvent(
self.timeline,
icon.as_ptr(),
title.as_ptr(),
description.as_ptr(),
priority,
start_offset_seconds,
duration,
clip_priority.into(),
)
}
}
}

0 comments on commit 60f9535

Please sign in to comment.