opengl-registry 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.1
6
+ before_install: gem install bundler -v 2.1.4
data/.yardopts ADDED
@@ -0,0 +1,7 @@
1
+ --readme README.md
2
+ --title 'OpenGL Registry'
3
+ --charset utf-8
4
+ --markup markdown
5
+ --protected
6
+ lib/**/*.rb
7
+ --exclude lib/opengl/registry/words.rb
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # Version History
2
+
3
+ ## 1.0
4
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
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
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
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,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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