Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Custom Variables #201

Merged
merged 3 commits into from
Jan 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions capi/bind_gen/src/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,11 +658,41 @@ export interface RunMetadataJson {
*/
region_name: string,
/**
* Stores all the variables. A variable is an arbitrary key value pair
* storing additional information about the category. An example of this
* may be whether Amiibos are used in this category.
* Stores all the speedrun.com variables. A variable is an arbitrary key
* value pair storing additional information about the category. An example
* of this may be whether Amiibos are used in this category.
*/
variables: { [key: string]: string },
speedrun_com_variables: { [key: string]: string | undefined },
/**
* Stores all the custom variables. A custom variable is a key value pair
* storing additional information about a run. Unlike the speedrun.com
* variables, these can be fully custom and don't need to correspond to
* anything on speedrun.com. Permanent custom variables can be specified by
* the runner. Additionally auto splitters or other sources may provide
* temporary custom variables that are not stored in the splits files.
*/
custom_variables: { [key: string]: CustomVariableJson | undefined },
}
/**
* A custom variable is a key value pair storing additional information about a
* run. Unlike the speedrun.com variables, these can be fully custom and don't
* need to correspond to anything on speedrun.com. Permanent custom variables
* can be specified by the runner. Additionally auto splitters or other sources
* may provide temporary custom variables that are not stored in the splits
* files.
*/
export interface CustomVariableJson {
/**
* The current value of the custom variable. This may be provided by the
* runner in the run editor or it may be provided through other means such
* as an auto splitter.
*/
value: string,
/**
* States whether the variable is permanent. Temporary variables don't get
* stored in splits files. They also don't get shown in the run editor.
*/
is_permanent: boolean,
}

/**
Expand Down
12 changes: 8 additions & 4 deletions capi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ pub mod previous_segment_component;
pub mod run;
pub mod run_editor;
pub mod run_metadata;
pub mod run_metadata_variable;
pub mod run_metadata_variables_iter;
pub mod run_metadata_custom_variable;
pub mod run_metadata_custom_variables_iter;
pub mod run_metadata_speedrun_com_variable;
pub mod run_metadata_speedrun_com_variables_iter;
pub mod segment;
pub mod segment_history;
pub mod segment_history_element;
Expand All @@ -64,7 +66,8 @@ pub mod title_component;
pub mod title_component_state;
pub mod total_playtime_component;

use crate::run_metadata_variable::RunMetadataVariable;
use crate::run_metadata_custom_variable::RunMetadataCustomVariable;
use crate::run_metadata_speedrun_com_variable::RunMetadataSpeedrunComVariable;
use crate::segment_history_element::SegmentHistoryElement;
use livesplit_core::{Time, TimeSpan};

Expand All @@ -78,7 +81,8 @@ thread_local! {
static TIME_SPAN: Cell<TimeSpan> = Cell::default();
static TIME: Cell<Time> = Cell::default();
static SEGMENT_HISTORY_ELEMENT: Cell<SegmentHistoryElement> = Cell::default();
static RUN_METADATA_VARIABLE: Cell<RunMetadataVariable> = Cell::new((ptr::null(), ptr::null()));
static RUN_METADATA_SPEEDRUN_COM_VARIABLE: Cell<RunMetadataSpeedrunComVariable> = Cell::new((ptr::null(), ptr::null()));
static RUN_METADATA_CUSTOM_VARIABLE: Cell<RunMetadataCustomVariable> = Cell::new((ptr::null(), ptr::null()));
}

fn output_time_span(time_span: TimeSpan) -> *const TimeSpan {
Expand Down
44 changes: 38 additions & 6 deletions capi/src/run_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,24 +158,56 @@ pub extern "C" fn RunEditor_set_emulator_usage(this: &mut RunEditor, uses_emulat
this.set_emulator_usage(uses_emulator);
}

/// Sets the variable with the name specified to the value specified. A
/// Sets the speedrun.com variable with the name specified to the value specified. A
/// variable is an arbitrary key value pair storing additional information
/// about the category. An example of this may be whether Amiibos are used
/// in this category. If the variable doesn't exist yet, it is being
/// inserted.
#[no_mangle]
pub unsafe extern "C" fn RunEditor_set_variable(
pub unsafe extern "C" fn RunEditor_set_speedrun_com_variable(
this: &mut RunEditor,
name: *const c_char,
value: *const c_char,
) {
this.set_variable(str(name), str(value));
this.set_speedrun_com_variable(str(name), str(value));
}

/// Removes the variable with the name specified.
/// Removes the speedrun.com variable with the name specified.
#[no_mangle]
pub unsafe extern "C" fn RunEditor_remove_variable(this: &mut RunEditor, name: *const c_char) {
this.remove_variable(str(name));
pub unsafe extern "C" fn RunEditor_remove_speedrun_com_variable(
this: &mut RunEditor,
name: *const c_char,
) {
this.remove_speedrun_com_variable(str(name));
}

/// Adds a new permanent custom variable. If there's a temporary variable with
/// the same name, it gets turned into a permanent variable and its value stays.
/// If a permanent variable with the name already exists, nothing happens.
#[no_mangle]
pub unsafe extern "C" fn RunEditor_add_custom_variable(this: &mut RunEditor, name: *const c_char) {
this.add_custom_variable(str(name));
}

/// Sets the value of a custom variable with the name specified. If the custom
/// variable does not exist, or is not a permanent variable, nothing happens.
#[no_mangle]
pub unsafe extern "C" fn RunEditor_set_custom_variable(
this: &mut RunEditor,
name: *const c_char,
value: *const c_char,
) {
this.set_custom_variable(str(name), str(value));
}

/// Removes the custom variable with the name specified. If the custom variable
/// does not exist, or is not a permanent variable, nothing happens.
#[no_mangle]
pub unsafe extern "C" fn RunEditor_remove_custom_variable(
this: &mut RunEditor,
name: *const c_char,
) {
this.remove_custom_variable(str(name));
}

/// Resets all the Metadata Information.
Expand Down
22 changes: 16 additions & 6 deletions capi/src/run_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
//! platform and region of the game. All of this information is optional.

use super::output_str;
use crate::run_metadata_variables_iter::OwnedRunMetadataVariablesIter;
use crate::run_metadata_custom_variables_iter::OwnedRunMetadataCustomVariablesIter;
use crate::run_metadata_speedrun_com_variables_iter::OwnedRunMetadataSpeedrunComVariablesIter;
use livesplit_core::RunMetadata;
use std::os::raw::c_char;

Expand Down Expand Up @@ -39,11 +40,20 @@ pub extern "C" fn RunMetadata_region_name(this: &RunMetadata) -> *const c_char {
output_str(this.region_name())
}

/// Returns an iterator iterating over all the variables and their values
/// that have been specified.
/// Returns an iterator iterating over all the speedrun.com variables and their
/// values that have been specified.
#[no_mangle]
pub extern "C" fn RunMetadata_variables(
pub extern "C" fn RunMetadata_speedrun_com_variables(
this: &'static RunMetadata,
) -> OwnedRunMetadataVariablesIter {
Box::new(this.variables())
) -> OwnedRunMetadataSpeedrunComVariablesIter {
Box::new(this.speedrun_com_variables())
}

/// Returns an iterator iterating over all the custom variables and their
/// values. This includes both temporary and permanent variables.
#[no_mangle]
pub extern "C" fn RunMetadata_custom_variables(
this: &'static RunMetadata,
) -> OwnedRunMetadataCustomVariablesIter {
Box::new(this.custom_variables())
}
49 changes: 49 additions & 0 deletions capi/src/run_metadata_custom_variable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! A custom variable is a key value pair storing additional information about a
//! run. Unlike the speedrun.com variables, these can be fully custom and don't
//! need to correspond to anything on speedrun.com. Permanent custom variables
//! can be specified by the runner. Additionally auto splitters or other sources
//! may provide temporary custom variables that are not stored in the splits
//! files.

use super::output_str;
use livesplit_core::run::CustomVariable;
use std::os::raw::c_char;

/// type
pub type RunMetadataCustomVariable = (*const String, *const CustomVariable);
/// type
pub type NullableRunMetadataCustomVariable = RunMetadataCustomVariable;
/// type
pub type OwnedRunMetadataCustomVariable = Box<RunMetadataCustomVariable>;

/// drop
#[no_mangle]
pub extern "C" fn RunMetadataCustomVariable_drop(this: OwnedRunMetadataCustomVariable) {
drop(this);
}

/// Accesses the name of this custom variable.
#[no_mangle]
pub unsafe extern "C" fn RunMetadataCustomVariable_name(
this: &RunMetadataCustomVariable,
) -> *const c_char {
output_str(&*this.0)
}

/// Accesses the value of this custom variable.
#[no_mangle]
pub unsafe extern "C" fn RunMetadataCustomVariable_value(
this: &RunMetadataCustomVariable,
) -> *const c_char {
output_str(&(*this.1).value)
}

/// Returns <TRUE> if the custom variable is permanent. Permanent variables get
/// stored in the splits file and are visible in the run editor. Temporary
/// variables are not.
#[no_mangle]
pub unsafe extern "C" fn RunMetadataCustomVariable_is_permanent(
this: &RunMetadataCustomVariable,
) -> bool {
(*this.1).is_permanent
}
36 changes: 36 additions & 0 deletions capi/src/run_metadata_custom_variables_iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! An iterator iterating over all the custom variables and their values
//! that have been specified.

use super::RUN_METADATA_CUSTOM_VARIABLE;
use crate::run_metadata_custom_variable::{
NullableRunMetadataCustomVariable, RunMetadataCustomVariable,
};
use livesplit_core::{indexmap, run::CustomVariable};
use std::ptr;

/// type
pub type RunMetadataCustomVariablesIter = indexmap::map::Iter<'static, String, CustomVariable>;
/// type
pub type OwnedRunMetadataCustomVariablesIter = Box<RunMetadataCustomVariablesIter>;

/// drop
#[no_mangle]
pub extern "C" fn RunMetadataCustomVariablesIter_drop(this: OwnedRunMetadataCustomVariablesIter) {
drop(this);
}

/// Accesses the next custom variable. Returns <NULL> if there are no more
/// variables.
#[no_mangle]
pub extern "C" fn RunMetadataCustomVariablesIter_next(
this: &mut RunMetadataCustomVariablesIter,
) -> *const NullableRunMetadataCustomVariable {
if let Some((name, value)) = this.next() {
RUN_METADATA_CUSTOM_VARIABLE.with(|output| {
output.set((name, value));
output.as_ptr() as *const RunMetadataCustomVariable
})
} else {
ptr::null()
}
}
35 changes: 35 additions & 0 deletions capi/src/run_metadata_speedrun_com_variable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! A speedrun.com variable is an arbitrary key value pair storing additional
//! information about the category. An example of this may be whether Amiibos
//! are used in the category.

use super::output_str;
use std::os::raw::c_char;

/// type
pub type RunMetadataSpeedrunComVariable = (*const String, *const String);
/// type
pub type NullableRunMetadataSpeedrunComVariable = RunMetadataSpeedrunComVariable;
/// type
pub type OwnedRunMetadataSpeedrunComVariable = Box<RunMetadataSpeedrunComVariable>;

/// drop
#[no_mangle]
pub extern "C" fn RunMetadataSpeedrunComVariable_drop(this: OwnedRunMetadataSpeedrunComVariable) {
drop(this);
}

/// Accesses the name of this speedrun.com variable.
#[no_mangle]
pub unsafe extern "C" fn RunMetadataSpeedrunComVariable_name(
this: &RunMetadataSpeedrunComVariable,
) -> *const c_char {
output_str(&*this.0)
}

/// Accesses the value of this speedrun.com variable.
#[no_mangle]
pub unsafe extern "C" fn RunMetadataSpeedrunComVariable_value(
this: &RunMetadataSpeedrunComVariable,
) -> *const c_char {
output_str(&*this.1)
}
38 changes: 38 additions & 0 deletions capi/src/run_metadata_speedrun_com_variables_iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//! An iterator iterating over all the speedrun.com variables and their values
//! that have been specified.

use super::RUN_METADATA_SPEEDRUN_COM_VARIABLE;
use crate::run_metadata_speedrun_com_variable::{
NullableRunMetadataSpeedrunComVariable, RunMetadataSpeedrunComVariable,
};
use livesplit_core::indexmap;
use std::ptr;

/// type
pub type RunMetadataSpeedrunComVariablesIter = indexmap::map::Iter<'static, String, String>;
/// type
pub type OwnedRunMetadataSpeedrunComVariablesIter = Box<RunMetadataSpeedrunComVariablesIter>;

/// drop
#[no_mangle]
pub extern "C" fn RunMetadataSpeedrunComVariablesIter_drop(
this: OwnedRunMetadataSpeedrunComVariablesIter,
) {
drop(this);
}

/// Accesses the next speedrun.com variable. Returns <NULL> if there are no more
/// variables.
#[no_mangle]
pub extern "C" fn RunMetadataSpeedrunComVariablesIter_next(
this: &mut RunMetadataSpeedrunComVariablesIter,
) -> *const NullableRunMetadataSpeedrunComVariable {
if let Some((name, value)) = this.next() {
RUN_METADATA_SPEEDRUN_COM_VARIABLE.with(|output| {
output.set((name, value));
output.as_ptr() as *const RunMetadataSpeedrunComVariable
})
} else {
ptr::null()
}
}
31 changes: 0 additions & 31 deletions capi/src/run_metadata_variable.rs

This file was deleted.

Loading