1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use super::ffi;
/// Debug context property
///
/// This can be used to give a module additional context for debugging panics and crashes by describing key module state by
/// instantiating properties that describe different types of state. For example which level is loaded in a module.
///
/// If there are any panics or crashes in the module during the lifetime of this object then this
/// context will be included in those panic / crash reports.
///
/// Note that this is intended for debugging purposes also and should only be select important state, not describe tons of state in
/// the module. So recommendation is to use max 10 properties or so and update them when they change, not many times per frame / module call.
///
/// # Example
///
/// In this example we load a level, and there can only be a single level active at the time so we can put the debug context property directly inside
/// the object so it the debug context property is active while the level is active.
///
/// ```
/// struct Level {
/// name: String,
/// _debug_prop: DebugContextProperty
/// }
///
/// impl Level {
/// pub fn new(name: String) -> Self {
/// let _debug_prop = DebugContextProperty::new("level", &name)
/// Self {
/// name,
/// _debug_prop
/// }
/// }
/// }
// ```
#[must_use]
#[derive(Debug)]
pub struct DebugContextProperty {
name: &'static str,
}
impl DebugContextProperty {
/// Creates a new debug context property
///
/// The name of the property is global and unique to the module, supposed to be brief and is required to be static.
/// The value of the property can be any string but generally single-line strings are preferred.
///
/// Name and value strings may be capped by the host.
pub fn new(name: &'static str, value: impl std::fmt::Display) -> Self {
let mut scope = Self { name };
scope.push(value);
scope
}
/// Push a new value for an existing debug context property in the same stack.
pub fn push(&mut self, value: impl std::fmt::Display) {
let value = value.to_string();
unsafe {
ffi::core_v4::core__add_debug_context(
self.name.as_ptr(),
self.name.len() as u32,
value.as_ptr(),
value.len() as u32,
);
}
}
/// Pop a value of an existing debug context property stack.
///
/// Does nothing if the property stack was already empty.
pub fn pop(&mut self) {
unsafe {
ffi::core_v4::core__remove_debug_context(self.name.as_ptr(), self.name.len() as u32);
}
}
/// Replace the current value of an existing debug context property (equivalent to pop and
/// push).
pub fn reset(&mut self, value: impl std::fmt::Display) {
self.pop();
self.push(value);
}
}
impl Drop for DebugContextProperty {
fn drop(&mut self) {
self.pop();
}
}