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 
lastName()52 	GLuint lastName()
53 	{
54 		return map.rbegin()->first;
55 	}
56 
allocate(ObjectType * object=nullptr)57 	GLuint allocate(ObjectType *object = nullptr)
58 	{
59 		GLuint name = freeName;
60 
61 		while(isReserved(name))
62 		{
63 			name++;
64 		}
65 
66 		map.insert({name, object});
67 		freeName = name + 1;
68 
69 		return name;
70 	}
71 
isReserved(GLuint name) const72 	bool isReserved(GLuint name) const
73 	{
74 		return map.find(name) != map.end();
75 	}
76 
insert(GLuint name,ObjectType * object)77 	void insert(GLuint name, ObjectType *object)
78 	{
79 		map[name] = object;
80 
81 		if(name == freeName)
82 		{
83 			freeName++;
84 		}
85 	}
86 
remove(GLuint name)87 	ObjectType *remove(GLuint name)
88 	{
89 		auto element = map.find(name);
90 
91 		if(element != map.end())
92 		{
93 			ObjectType *object = element->second;
94 			map.erase(element);
95 
96 			if(name < freeName)
97 			{
98 				freeName = name;
99 			}
100 
101 			return object;
102 		}
103 
104 		return nullptr;
105 	}
106 
find(GLuint name) const107 	ObjectType *find(GLuint name) const
108 	{
109 		auto element = map.find(name);
110 
111 		if(element == map.end())
112 		{
113 			return nullptr;
114 		}
115 
116 		return element->second;
117 	}
118 
119 private:
120 	typedef std::map<GLuint, ObjectType*> Map;
121 	Map map;
122 
123 	GLuint freeName;   // Lowest known potentially free name
124 };
125 
126 }
127 
128 #endif   // gl_NameSpace_hpp
129