1 /*
2  *  BSD 3-Clause License
3  *  
4  *  Copyright (c) 2016, Mango-Engine Team
5  *  All rights reserved.
6  *  
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions are met:
9  *  
10  *  * Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *  
13  *  * Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  *  
17  *  * Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from
19  *    this software without specific prior written permission.
20  *  
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 module mango_engine.graphics.scene;
33 
34 import mango_engine.util;
35 import mango_engine.exception;
36 import mango_engine.graphics.model;
37 import mango_engine.graphics.texture;
38 import mango_engine.graphics.shader;
39 
40 import std.exception : enforce;
41 
42 /// Represents a Scene with Models
43 class Scene {
44     immutable string name; 
45 
46     private shared size_t modelCounter = 0;
47 
48     private shared SyncLock modelLock;
49     private shared SyncLock textureLock;
50     private shared SyncLock shaderLock;
51 
52     package shared Model[size_t] models;
53     package shared Texture[string] textures;
54     package shared ShaderProgram[string] shaders;
55 
56     package bool isRendering = false;
57 
58     this(in string name) @safe nothrow {
59         this.name = name;
60 
61         modelLock = new SyncLock();
62         textureLock = new SyncLock();
63         shaderLock = new SyncLock();
64     }
65 
66     size_t addModel(Model model) @trusted {
67         import core.atomic : atomicOp;
68 
69         synchronized(modelLock) {
70             this.models[atomicOp!"+="(modelCounter, 1)] = cast(shared) model;
71             return modelCounter;
72         }
73     }
74 
75     void addTexture(in string textureName, Texture texture) @trusted {
76         synchronized(textureLock) {
77             this.textures[textureName] = cast(shared) texture;
78         }
79     }
80 
81     void addShader(in string shaderName, ShaderProgram shader) @trusted {
82         synchronized(shaderLock) {
83             this.shaders[shaderName] = cast(shared) shader;
84         }
85     }
86 
87     void removeModel(in size_t modelId) @safe {
88         synchronized(modelLock) {
89             enforce(modelId in this.models, new InvalidArgumentException("Invalid modelId! (not a valid key)"));
90 
91             this.models.remove(modelId);
92         }
93     }
94 
95     void removeTexture(in string textureName) @safe {
96         synchronized(textureLock) {
97             enforce(textureName in this.textures, new InvalidArgumentException("Invalid textureName (not a valid key)"));
98 
99             this.textures.remove(textureName);
100         }
101     }
102 
103     void removeShader(in string shaderName) @safe {
104         synchronized(shaderLock) {
105             enforce(shaderName in this.shaders, new InvalidArgumentException("Invalid shaderName (not a valid key)"));
106 
107             this.shaders.remove(shaderName);
108         }
109     }
110 }