opengl-registry 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +6 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +85 -0
- data/Rakefile +3 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/opengl/registry.rb +318 -0
- data/lib/opengl/registry/argument.rb +60 -0
- data/lib/opengl/registry/enum.rb +64 -0
- data/lib/opengl/registry/extension.rb +23 -0
- data/lib/opengl/registry/feature.rb +48 -0
- data/lib/opengl/registry/feature_group.rb +38 -0
- data/lib/opengl/registry/feature_provider.rb +45 -0
- data/lib/opengl/registry/function.rb +86 -0
- data/lib/opengl/registry/group.rb +62 -0
- data/lib/opengl/registry/native_type.rb +59 -0
- data/lib/opengl/registry/token.rb +29 -0
- data/lib/opengl/registry/version.rb +10 -0
- data/lib/opengl/registry/words.rb +39 -0
- data/lib/opengl/spec.rb +176 -0
- data/opengl-registry.gemspec +37 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 140b56969d6bf604555783463786f8c26cf5df295867117030082ea8ea554569
|
4
|
+
data.tar.gz: 0e4416074336ef92dca0946b188fb2afbfa19b40046aa054a73f47bfda269a11
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 50fa00baa919c7556ce6b4628be3d5c3ec0a0938770c083519939276d247925ddc5e0b0f6c1802b6b72e373b84bab0bd3c20c0ed2e9b44ae6da5d87b61949efc
|
7
|
+
data.tar.gz: 7415697ad77a33c8148d9a1fb97fe97a59e79f154e3704b84593a7fa4fe9faac0894d2237c8ee236b915e8ff99ad2639796b2a29d9ca40a567c1c0c68ffdb206
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 ForeverZer0
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# OpenGL Registry
|
2
|
+
|
3
|
+
Parses the Khronos OpenGL registry into a standardized and user-friendly data structure that can be walked through, providing an essential need for tools that generate code to create an OpenGL wrapper/bindings, for any language. Given an API name, version, and profile, is capable of filtering and grouping data structures that cover that specific subset of definitions, using a typical Ruby object-oriented approach.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'opengl-registry'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install opengl-registry
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
#### Get the OpenGL Registry from Khronos
|
24
|
+
|
25
|
+
You can either download the latest copy of [gl.xml](https://github.com/KhronosGroup/OpenGL-Registry/blob/master/xml/gl.xml) directly from the [Khronos repo](https://github.com/KhronosGroup/OpenGL-Registry/tree/master/), or fetch it through the API.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'opengl-registry'
|
29
|
+
|
30
|
+
GL::Registry.download('/path/to/save/gl.xml')
|
31
|
+
```
|
32
|
+
|
33
|
+
For successive runs, you can simply check that the version you have is up to date.
|
34
|
+
```ruby
|
35
|
+
if GL::Registry.outdated?('/path/to/gl.xml')
|
36
|
+
# Download updated copy
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
#### Create a Registry instance
|
41
|
+
|
42
|
+
First step is to create the registry, which is essentially a container that stores every definition defined for OpenGL, OpenGLES (Embedded Systems), and OpenGLSC (Security Critical).
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
registry = GL::Registry.load('/path/to/gl.xml')
|
46
|
+
```
|
47
|
+
|
48
|
+
Alternatively, if you have the XML as a string...
|
49
|
+
```ruby
|
50
|
+
registry = GL::Registry.parse(xml_string)
|
51
|
+
```
|
52
|
+
|
53
|
+
#### Create the OpenGL specification you wish to target
|
54
|
+
|
55
|
+
In order to filter results and definitions by a subset of the API, version, profile, etc, create a new spec.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
extensions = ['GL_ARB_get_program_binary', 'GL_ARB_texture_storage']
|
59
|
+
spec = GL::Spec.new(registry, :gl, 3.3, :core, extensions)
|
60
|
+
```
|
61
|
+
|
62
|
+
The created `spec` object can be then used to enumerate through every definition that this subset defines. The data will automatically be filtered and sorted, allowing for easy inspection of each entity.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
spec.functions.each do |function|
|
66
|
+
# Print out the function name and return type
|
67
|
+
puts "#{function.name} (#{function.type})"
|
68
|
+
|
69
|
+
# Loop through argument definitions
|
70
|
+
function.arguments.each do |argument|
|
71
|
+
puts " #{argument.name} (#{argument.type})"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
spec.enums.each do |enum|
|
76
|
+
# Enums also define "groups" for creating C-style enumeration types, etc
|
77
|
+
puts "#{enum.name} = #{enum.value}"
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
There are many helper functions throughout for detailed filtering, and retrieving any relevant information that might be required, such as generating bindings for a particular language, etc. See the [documentation](https://www.rubydoc.info/gems/opengl-registry/1.0.0) for more details.
|
82
|
+
|
83
|
+
## License
|
84
|
+
|
85
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "opengl/registry"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,318 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ox'
|
4
|
+
require 'net/http'
|
5
|
+
require 'json'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
require_relative 'registry/version'
|
10
|
+
require_relative 'registry/words'
|
11
|
+
require_relative 'registry/token'
|
12
|
+
require_relative 'registry/native_type'
|
13
|
+
require_relative 'registry/group'
|
14
|
+
require_relative 'registry/enum'
|
15
|
+
require_relative 'registry/argument'
|
16
|
+
require_relative 'registry/function'
|
17
|
+
require_relative 'registry/feature_provider'
|
18
|
+
require_relative 'registry/feature'
|
19
|
+
require_relative 'registry/feature_group'
|
20
|
+
require_relative 'registry/extension'
|
21
|
+
require_relative 'spec'
|
22
|
+
|
23
|
+
##
|
24
|
+
# Top-level namespace.
|
25
|
+
#
|
26
|
+
# @author Eric "ForeverZer0" Freed
|
27
|
+
module GL
|
28
|
+
|
29
|
+
##
|
30
|
+
# Container for all definitions of the OpenGL registry.
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
#
|
34
|
+
# # Check if registry XML file is up to data
|
35
|
+
# if GL::Registry.outdated?('gl.xml')
|
36
|
+
# GL::Registry.download('gl.xml')
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# registry = GL::Registry.load('gl.xml')
|
40
|
+
# spec = GL::Spec.new(registry, :gl, 3.3, :core)
|
41
|
+
#
|
42
|
+
# # Use "spec" object to enumerate over detailed objects defining each token
|
43
|
+
#
|
44
|
+
class Registry
|
45
|
+
|
46
|
+
##
|
47
|
+
# An array of OpenGL type names, as symbols.
|
48
|
+
GL_TYPES = %i[
|
49
|
+
GLenum GLboolean GLbitfield GLvoid GLbyte GLubyte GLshort GLushort GLint
|
50
|
+
GLuint GLclampx GLsizei GLfloat GLclampf GLdouble GLclampd
|
51
|
+
GLeglClientBufferEXT GLeglImageOES GLchar GLhandleARB GLhalf GLhalfARB
|
52
|
+
GLfixed GLintptr GLintptrARB GLsizeiptr GLsizeiptrARB GLint64 GLint64EXT
|
53
|
+
GLuint64 GLuint64EXT GLsync struct\ _cl_context struct\ _cl_event
|
54
|
+
GLDEBUGPROC GLDEBUGPROCARB GLDEBUGPROCKHR GLDEBUGPROCAMD GLhalfNV
|
55
|
+
GLvdpauSurfaceNV GLVULKANPROCNV
|
56
|
+
].freeze
|
57
|
+
|
58
|
+
##
|
59
|
+
# @return [Array<Group>] a collection of all enumeration groups defined by OpenGL.
|
60
|
+
# @note This is for reference only, and should not be used for building definitions or determining a comprehensive
|
61
|
+
# list of which enum values belong in each group, use the {Enum#groups} property instead.
|
62
|
+
attr_reader :groups
|
63
|
+
|
64
|
+
##
|
65
|
+
# @return [Array<Function>] a complete collection of all OpenGL functions.
|
66
|
+
attr_reader :functions
|
67
|
+
|
68
|
+
##
|
69
|
+
# @!attribute [r] enums
|
70
|
+
# @return [Array<Enum>] a complete collection of all OpenGL enum values.
|
71
|
+
|
72
|
+
##
|
73
|
+
# @return [Array<FeatureGroup>] a complete collection of all OpenGL feature groups.
|
74
|
+
attr_reader :features
|
75
|
+
|
76
|
+
##
|
77
|
+
# @return [Array<Extension>] a complete collection of all OpenGL extensions.
|
78
|
+
attr_reader :extensions
|
79
|
+
|
80
|
+
##
|
81
|
+
# Creates a new {Registry} from the specified XML file.
|
82
|
+
#
|
83
|
+
# @param path [String] The path to the registry file.
|
84
|
+
#
|
85
|
+
# @return [Registry] a newly created and parsed {Registry}.
|
86
|
+
def self.load(path)
|
87
|
+
doc = Ox.load_file(path, mode: :generic)
|
88
|
+
new(doc.root)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Creates a new {Registry} from the specified XML string.
|
93
|
+
#
|
94
|
+
# @param xml [String] The OpenGL registry as an XML string.
|
95
|
+
#
|
96
|
+
# @return [Registry] a newly created and parsed {Registry}.
|
97
|
+
def self.parse(xml)
|
98
|
+
doc = Ox.load(xml, mode: :generic)
|
99
|
+
new(doc.root)
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# @return [Array<Symbol>] an array of Symbol objects that represent each defined API in the registry.
|
104
|
+
def api_names
|
105
|
+
# RubyMine warns that the return value is wrong. It lies.
|
106
|
+
#noinspection RubyYardReturnMatch
|
107
|
+
@features.map(&:api).uniq
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Retrieves an array of profiles defined in the registry.
|
112
|
+
#
|
113
|
+
# @overload profiles
|
114
|
+
#
|
115
|
+
# @overload profiles(api)
|
116
|
+
# @param api [Symbol] An API to limit results to a specific API.
|
117
|
+
#
|
118
|
+
# @overload profiles(api, version)
|
119
|
+
# @param api [Symbol] An API to limit results to a specific API.
|
120
|
+
# @param version [String|Float] A version to limit results to.
|
121
|
+
#
|
122
|
+
# @return [Array<Symbol>] an array of defined profiles.
|
123
|
+
def profiles(api = nil, version = '1.0')
|
124
|
+
# RubyMine warns that the return value is wrong. It lies.
|
125
|
+
if api
|
126
|
+
values = @features.find_all { |group| group.api == api && group.version <= version.to_s }
|
127
|
+
#noinspection RubyYardReturnMatch
|
128
|
+
return values.flat_map(&:additions).map(&:profile).uniq
|
129
|
+
end
|
130
|
+
#noinspection RubyYardReturnMatch
|
131
|
+
@features.flat_map(&:additions).map(&:profile).uniq
|
132
|
+
end
|
133
|
+
|
134
|
+
def enums
|
135
|
+
#noinspection RubyResolve
|
136
|
+
@enums ||= each_enum.to_a
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# Enumerates through each enum defined in the registry.
|
141
|
+
#
|
142
|
+
# @overload each_enum
|
143
|
+
# When called without a block, returns an Enumerator.
|
144
|
+
# @return [Enumerator] An enum enumerator.
|
145
|
+
#
|
146
|
+
# @overload each_enum(&block)
|
147
|
+
# When called with a block, yields each item to the block and returns `nil`.
|
148
|
+
# @yieldparam enum [Enum] Yields an enum to the block.
|
149
|
+
# @return [void]
|
150
|
+
def each_enum
|
151
|
+
#noinspection RubyYardReturnMatch
|
152
|
+
return enum_for(__method__) unless block_given?
|
153
|
+
@groups.each do |group|
|
154
|
+
group.members.each { |item| yield item }
|
155
|
+
end
|
156
|
+
nil
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# Enumerates through each group defined in the registry.
|
161
|
+
#
|
162
|
+
# @overload each_group
|
163
|
+
# When called without a block, returns an Enumerator.
|
164
|
+
# @return [Enumerator] A group enumerator.
|
165
|
+
#
|
166
|
+
# @overload each_group(&block)
|
167
|
+
# When called with a block, yields each item to the block and returns `nil`.
|
168
|
+
# @yieldparam group [Group] Yields a group to the block.
|
169
|
+
# @return [void]
|
170
|
+
def each_group
|
171
|
+
#noinspection RubyYardReturnMatch
|
172
|
+
return enum_for(__method__) unless block_given?
|
173
|
+
@groups.each { |item| yield item }
|
174
|
+
nil
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Enumerates through each function defined in the registry.
|
179
|
+
#
|
180
|
+
# @overload each_function
|
181
|
+
# When called without a block, returns an Enumerator.
|
182
|
+
# @return [Enumerator] A function enumerator.
|
183
|
+
#
|
184
|
+
# @overload each_function(&block)
|
185
|
+
# When called with a block, yields each item to the block and returns `nil`.
|
186
|
+
# @yieldparam enum [Function] Yields a function to the block.
|
187
|
+
# @return [void]
|
188
|
+
def each_function
|
189
|
+
#noinspection RubyYardReturnMatch
|
190
|
+
return enum_for(__method__) unless block_given?
|
191
|
+
@functions.each { |item| yield item }
|
192
|
+
nil
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# Enumerates through each feature group defined in the registry.
|
197
|
+
#
|
198
|
+
# @overload each_feature
|
199
|
+
# When called without a block, returns an Enumerator.
|
200
|
+
# @return [Enumerator] A feature group enumerator.
|
201
|
+
#
|
202
|
+
# @overload each_feature(&block)
|
203
|
+
# When called with a block, yields each item to the block and returns `nil`.
|
204
|
+
# @yieldparam enum [FeatureGroup] Yields a group to the block.
|
205
|
+
# @return [void]
|
206
|
+
def each_feature
|
207
|
+
#noinspection RubyYardReturnMatch
|
208
|
+
return enum_for(__method__) unless block_given?
|
209
|
+
@features.each { |item| yield item }
|
210
|
+
nil
|
211
|
+
end
|
212
|
+
|
213
|
+
##
|
214
|
+
# Enumerates through each extension defined in the registry.
|
215
|
+
#
|
216
|
+
# @overload each_enum
|
217
|
+
# When called without a block, returns an Enumerator.
|
218
|
+
# @return [Enumerator] An extension enumerator.
|
219
|
+
#
|
220
|
+
# @overload each_enum(&block)
|
221
|
+
# When called with a block, yields each item to the block and returns `nil`.
|
222
|
+
# @yieldparam enum [Extension] Yields an extension to the block.
|
223
|
+
# @return [void]
|
224
|
+
def each_extension
|
225
|
+
#noinspection RubyYardReturnMatch
|
226
|
+
return enum_for(__method__) unless block_given?
|
227
|
+
@extensions.each { |item| yield item }
|
228
|
+
nil
|
229
|
+
end
|
230
|
+
|
231
|
+
##
|
232
|
+
# Download the latest version of the OpenGL registry to the specified file.
|
233
|
+
#
|
234
|
+
# @param path [String] The path where the file will be saved.
|
235
|
+
#
|
236
|
+
# @return [Boolean] `true` on success, otherwise `false` if an error occurred.
|
237
|
+
def self.download(path)
|
238
|
+
begin
|
239
|
+
URI.open('https://raw.githubusercontent.com/KhronosGroup/OpenGL-Registry/master/xml/gl.xml') do |io|
|
240
|
+
FileUtils.mv(io.path, path)
|
241
|
+
end
|
242
|
+
return true
|
243
|
+
rescue
|
244
|
+
return false
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
##
|
249
|
+
# Compares the registry at the specified path to the current registry version and returns value indicating if there
|
250
|
+
# is a newer version available.
|
251
|
+
#
|
252
|
+
# @param path [String] The path to a registry file to test.
|
253
|
+
#
|
254
|
+
# @return [Boolean] `true` if a newer version is available, otherwise `false` if file is current and/or an error
|
255
|
+
# occurred.
|
256
|
+
#
|
257
|
+
# @note This method is not guaranteed to be accurate, it only uses the timestamps in the file's metadata, which
|
258
|
+
# could be inaccurate due to file copying, system time changes, creating from different source, etc.
|
259
|
+
def self.outdated?(path)
|
260
|
+
|
261
|
+
return false unless path && File.exist?(path)
|
262
|
+
|
263
|
+
begin
|
264
|
+
uri = URI('https://api.github.com/repos/KhronosGroup/OpenGL-Registry/commits?path=xml/gl.xml')
|
265
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true, open_timeout: 3, read_timeout: 5) do |http|
|
266
|
+
|
267
|
+
req = Net::HTTP::Get.new(uri)
|
268
|
+
response = http.request(req)
|
269
|
+
|
270
|
+
if response.code == '200'
|
271
|
+
json = JSON.parse(response.body, symbolize_names: true)
|
272
|
+
commit = DateTime.parse(json.first[:commit][:author][:date]).to_time
|
273
|
+
return File.mtime(path) < commit
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
rescue
|
278
|
+
warn('failed to query current registry version')
|
279
|
+
return false
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
private
|
284
|
+
|
285
|
+
def initialize(root)
|
286
|
+
raise ArgumentError, 'root cannot be nil' unless root
|
287
|
+
|
288
|
+
@groups = []
|
289
|
+
root.locate('enums').each do |enum|
|
290
|
+
next unless enum.is_a?(Ox::Element)
|
291
|
+
@groups << Group.new(enum)
|
292
|
+
end
|
293
|
+
|
294
|
+
@functions = []
|
295
|
+
root.locate('commands/command').each do |function|
|
296
|
+
next unless function.is_a?(Ox::Element)
|
297
|
+
@functions << Function.new(function)
|
298
|
+
end
|
299
|
+
|
300
|
+
@features = []
|
301
|
+
root.locate('feature').each do |feature|
|
302
|
+
next unless feature.is_a?(Ox::Element)
|
303
|
+
@features << FeatureGroup.new(feature)
|
304
|
+
end
|
305
|
+
|
306
|
+
@extensions = []
|
307
|
+
root.locate('extensions/extension').each do |extension|
|
308
|
+
next unless extension.is_a?(Ox::Element)
|
309
|
+
@extensions << Extension.new(extension)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
registry = GL::Registry.load('/code/ruby/khronos-temp/gl.xml')
|
316
|
+
spec = GL::Spec.new(registry, :gl, 4.3, :compatibility)
|
317
|
+
|
318
|
+
p spec.enums.size
|