1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // NameSpace.h: Defines the NameSpace class, which is used to
16 // allocate GL object names.
17 
18 #ifndef gl_NameSpace_hpp
19 #define gl_NameSpace_hpp
20 
21 #include "Object.hpp"
22 #include "debug.h"
23 
24 #include <map>
25 
26 namespace gl
27 {
28 
29 template<class ObjectType, GLuint baseName = 1>
30 class NameSpace
31 {
32 public:
NameSpace()33 	NameSpace() : freeName(baseName)
34 	{
35 	}
36 
~NameSpace()37 	~NameSpace()
38 	{
39 		ASSERT(empty());
40 	}
41 
empty()42 	bool empty()
43 	{
44 		return map.empty();
45 	}
46 
firstName()47 	GLuint firstName()
48 	{
49 		return map.begin()->first;
50 	}
51 
allocate(ObjectType * object=nullptr)52 	GLuint allocate(ObjectType *object = nullptr)
53 	{
54 		GLuint name = freeName;
55 
56 		while(isReserved(name))
57 		{
58 			name++;
59 		}
60 
61 		map.insert({name, object});
62 		freeName = name + 1;
63 
64 		return name;
65 	}
66 
isReserved(GLuint name) const67 	bool isReserved(GLuint name) const
68 	{
69 		return map.find(name) != map.end();
70 	}
71 
insert(GLuint name,ObjectType * object)72 	void insert(GLuint name, ObjectType *object)
73 	{
74 		map[name] = object;
75 
76 		if(name == freeName)
77 		{
78 			freeName++;
79 		}
80 	}
81 
remove(GLuint name)82 	ObjectType *remove(GLuint name)
83 	{
84 		auto element = map.find(name);
85 
86 		if(element != map.end())
87 		{
88 			ObjectType *object = element->second;
89 			map.erase(element);
90 
91 			if(name < freeName)
92 			{
93 				freeName = name;
94 			}
95 
96 			return object;
97 		}
98 
99 		return nullptr;
100 	}
101 
find(GLuint name) const102 	ObjectType *find(GLuint name) const
103 	{
104 		auto element = map.find(name);
105 
106 		if(element == map.end())
107 		{
108 			return nullptr;
109 		}
110 
111 		return element->second;
112 	}
113 
114 private:
115 	typedef std::map<GLuint, ObjectType*> Map;
116 	Map map;
117 
118 	GLuint freeName;   // Lowest known potentially free name
119 };
120 
121 }
122 
123 #endif   // gl_NameSpace_hpp
124