rush_ecs_svm/state/
instance.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2use rush_ecs_core::blueprint::{Component, ComponentValue};
3use shank::ShankAccount;
4use solana_program::pubkey::Pubkey;
5use spl_discriminator::{ArrayDiscriminator, SplDiscriminate};
6use std::collections::BTreeMap;
7
8// OPT-OUT: didn't use #[seeds()] because ShankAccount seeds
9// helper attribute is buggy. PDA is generated offchain
10// instead and seeds are validated
11
12#[derive(
13    Clone,
14    BorshSerialize,
15    BorshDeserialize,
16    Debug,
17    Default,
18    Eq,
19    PartialEq,
20    ShankAccount,
21    SplDiscriminate,
22)]
23#[discriminator_hash_input("rush_ecs_store::state::Instance")]
24pub struct Instance {
25    /// Identifier for this specific structure
26    pub discriminator: [u8; 8],
27
28    /// Source of truth for what the values of the components are
29    pub components: BTreeMap<Component, ComponentValue>,
30    /// Nonce to allow multiple Instances
31    pub nonce: u64,
32    /// Instance authority who has access to state changing
33    /// operations in this specific Instance
34    pub instance_authority: Pubkey,
35
36    /// Canonical bump for Instances
37    pub bump: u8,
38}
39
40impl Instance {
41    /// Create new Instance state
42    pub fn new(
43        components: BTreeMap<Component, ComponentValue>,
44        nonce: u64,
45        instance_authority: Pubkey,
46        bump: u8,
47    ) -> Self {
48        Self {
49            components,
50            nonce,
51            instance_authority,
52            bump,
53            discriminator: Self::SPL_DISCRIMINATOR.into(),
54        }
55    }
56
57    /// Is `true` if Instances is initialized
58    pub fn is_initialized(&self) -> bool {
59        self.discriminator.as_slice() == Instance::SPL_DISCRIMINATOR_SLICE
60    }
61
62    /// Is `true` if Instance is uninitialized
63    pub fn is_uninitialized(&self) -> bool {
64        self.discriminator.as_slice() == ArrayDiscriminator::UNINITIALIZED.as_slice()
65    }
66}