summaryrefslogtreecommitdiff
path: root/engine/src/rendering/object.rs
blob: ead20e62ff0f52538bee566292a35dc22942b88f (plain)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::collections::HashMap;
use std::sync::atomic::{AtomicU64, Ordering};

use crate::asset::Id as AssetId;
use crate::ecs::Sole;

pub type RawValue = u32;

/// Rendering object ID.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Id
{
    Asset(AssetId),
    Sequential(SequentialId),
}

impl Id
{
    pub fn new_sequential() -> Self
    {
        static NEXT_SEQUENTIAL_ID: AtomicU64 = AtomicU64::new(0);

        Self::Sequential(SequentialId(
            NEXT_SEQUENTIAL_ID.fetch_add(1, Ordering::Relaxed),
        ))
    }

    pub fn into_asset_id(self) -> Option<AssetId>
    {
        match self {
            Self::Asset(asset_id) => Some(asset_id),
            Self::Sequential(_) => None,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SequentialId(u64);

/// Rendering object store.
#[derive(Debug, Default, Sole)]
pub struct Store
{
    objects: HashMap<Id, Option<Object>>,
}

impl Store
{
    pub fn get_obj(&self, id: &Id) -> Option<&Object>
    {
        self.objects.get(id).and_then(|obj| obj.as_ref())
    }

    pub fn get_texture_obj(&self, id: &Id) -> Option<&Object>
    {
        let obj = self.get_obj(id)?;

        if !matches!(obj.kind(), Kind::Texture) {
            return None;
        }

        Some(obj)
    }

    pub fn get_shader_program_obj(&self, id: &Id) -> Option<&Object>
    {
        let obj = self.get_obj(id)?;

        if !matches!(obj.kind(), Kind::ShaderProgram) {
            return None;
        }

        Some(obj)
    }

    pub fn contains_maybe_pending_with_id(&self, id: &Id) -> bool
    {
        self.objects.contains_key(id)
    }

    pub fn contains_non_pending_with_id(&self, id: &Id) -> bool
    {
        self.objects.get(id).and_then(|obj| obj.as_ref()).is_some()
    }

    pub fn insert(&mut self, id: Id, object: Object)
    {
        self.objects.insert(id, Some(object));
    }

    pub fn insert_pending(&mut self, id: Id)
    {
        self.objects.insert(id, None);
    }

    pub fn remove(&mut self, id: &Id) -> Option<Option<Object>>
    {
        self.objects.remove(id)
    }
}

/// Rendering object.
#[derive(Debug, Clone)]
pub struct Object
{
    raw: RawValue,
    kind: Kind,
}

impl Object
{
    pub fn from_raw(raw: RawValue, kind: Kind) -> Self
    {
        Self { raw, kind }
    }

    pub fn as_raw(&self) -> RawValue
    {
        self.raw
    }

    pub fn kind(&self) -> Kind
    {
        self.kind
    }
}

/// Rendering object kind.
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum Kind
{
    Texture,
    ShaderProgram,
    ImplementationSpecific,
}