screeps/
raw_memory.rs

1//! Interface for Screeps [`RawMemory`] global object.
2//!
3//! This is available as an alternative to the `Memory` object in the js heap,
4//! which itself is just a light wrapper around serializing into and
5//! deserializing JSON into [`RawMemory`]. String data stored can be retrieved
6//! after the running bot code is restarted (either by the server or by a new
7//! version of the code being uploaded) and decoded using serde or another
8//! option.
9//!
10//! Also contains functions for accessing memory segments and other
11//! players' active foreign segments.
12//!
13//! [`RawMemory`]: https://docs.screeps.com/api/#RawMemory
14use js_sys::{Array, JsString, Object};
15
16use wasm_bindgen::prelude::*;
17
18use crate::prelude::*;
19
20#[wasm_bindgen]
21extern "C" {
22    type RawMemory;
23
24    #[wasm_bindgen(static_method_of = RawMemory, getter = segments)]
25    fn segments() -> Object;
26
27    #[wasm_bindgen(static_method_of = RawMemory, getter = foreignSegment)]
28    fn foreign_segment() -> Option<ForeignSegment>;
29
30    #[wasm_bindgen(static_method_of = RawMemory)]
31    fn get() -> JsString;
32
33    #[wasm_bindgen(static_method_of = RawMemory)]
34    fn set(val: &JsString);
35
36    #[wasm_bindgen(static_method_of = RawMemory, js_name = setActiveSegments)]
37    fn set_active_segments(segment_ids: &Array);
38
39    #[wasm_bindgen(static_method_of = RawMemory, js_name = setActiveForeignSegment)]
40    fn set_active_foreign_segment(username: &JsString, segment_id: Option<u8>);
41
42    #[wasm_bindgen(static_method_of = RawMemory, js_name = setDefaultPublicSegment)]
43    fn set_default_public_segment(segment_id: JsValue);
44
45    #[wasm_bindgen(static_method_of = RawMemory, js_name = setPublicSegments)]
46    fn set_public_segments(segment_ids: &Array);
47}
48
49/// Get a [`JsHashMap<u8, String>`] with all of the segments requested on
50/// the previous tick, with segment numbers as keys and segment data in
51/// [`String`] form as values.
52///
53/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.segments)
54pub fn segments() -> JsHashMap<u8, String> {
55    RawMemory::segments().into()
56}
57
58/// Get a [`JsHashMap<u8, JsString>`] with all of the segments requested on
59/// the previous tick, with segment numbers as keys and segment data in
60/// [`JsString`] form as values.
61///
62/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.segments)
63pub fn segments_jsstring() -> JsHashMap<u8, JsString> {
64    RawMemory::segments().into()
65}
66
67/// Get the foreign memory segment belonging to another player requested
68/// last tick.
69///
70/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.foreignSegment)
71pub fn foreign_segment() -> Option<ForeignSegment> {
72    RawMemory::foreign_segment()
73}
74
75/// Get the stored serialized memory as a [`JsString`].
76///
77/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.get)
78pub fn get() -> JsString {
79    RawMemory::get()
80}
81
82/// Overwrite the stored memory with a new [`JsString`]. Maximum allowed
83/// size [`MEMORY_SIZE_LIMIT`] UTF-16 units.
84///
85/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.set)
86///
87/// [`MEMORY_SIZE_LIMIT`]: crate::constants::MEMORY_SIZE_LIMIT
88pub fn set(val: &JsString) {
89    RawMemory::set(val)
90}
91
92/// Sets available memory segments for the next tick, as an array of numbers
93/// from 0 to 99 (max of 10 segments allowed).
94///
95/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.setActiveSegments)
96pub fn set_active_segments(segment_ids: &[u8]) {
97    let segment_ids: Array = segment_ids
98        .iter()
99        .map(|s| *s as f64)
100        .map(JsValue::from_f64)
101        .collect();
102
103    RawMemory::set_active_segments(&segment_ids)
104}
105
106/// Sets available foreign memory segment for the next tick to a memory
107/// segment marked as public by another user. If no id is passed, the user's
108/// default public segment is retrieved.
109///
110/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.setActiveForeignSegment)
111pub fn set_active_foreign_segment(username: &JsString, segment_id: Option<u8>) {
112    RawMemory::set_active_foreign_segment(username, segment_id)
113}
114
115/// Sets your default foreign memory segment for other players to read, or
116/// remove your public segment with `None`.
117///
118/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.setDefaultPublicSegment)
119pub fn set_default_public_segment(segment_id: Option<u8>) {
120    RawMemory::set_default_public_segment(
121        segment_id
122            .map(|f| JsValue::from_f64(f as f64))
123            .unwrap_or(JsValue::NULL),
124    )
125}
126
127/// Sets which of your memory segments are readable to other players as
128/// foreign segments, overriding previous settings.
129///
130/// [Screeps documentation](https://docs.screeps.com/api/#RawMemory.setPublicSegments)
131pub fn set_public_segments(segment_ids: &[u8]) {
132    let segment_ids: Array = segment_ids
133        .iter()
134        .map(|s| *s as f64)
135        .map(JsValue::from_f64)
136        .collect();
137
138    RawMemory::set_public_segments(&segment_ids)
139}
140
141#[wasm_bindgen]
142extern "C" {
143    /// The data from another user's foreign memory segment, which can be
144    /// retrieved by [`foreign_segment`], after being requested on the previous
145    /// tick by [`set_active_foreign_segment`].
146    #[wasm_bindgen]
147    pub type ForeignSegment;
148    #[wasm_bindgen(method, getter)]
149    pub fn username(this: &ForeignSegment) -> JsString;
150    #[wasm_bindgen(method, getter)]
151    pub fn id(this: &ForeignSegment) -> u8;
152    #[wasm_bindgen(method, getter)]
153    pub fn data(this: &ForeignSegment) -> JsString;
154}