From: Jean Privat Date: Mon, 28 Sep 2015 14:42:57 +0000 (-0400) Subject: Merge: Basename fix X-Git-Tag: v0.7.8~1 X-Git-Url: http://nitlanguage.org?hp=0a79a5c3944235bce7627912b1220bbf5e45a98c Merge: Basename fix Should close #1736 if performances are adequate for @privat. This PR optimizes some methods in both `SequenceRead` and `FlatString`, on the test program exposed in #1736, the valgrind runtime has gone from 418,872,526 Ir to 136,522,095 Ir (~67.5% improvement) Some more improvements could be observed if we could get rid of some useless Boxes in `NativeString::to_s_with_copy` because of a `is_same_instance` which boxes NativeStrings (24k allocations in total to remove). Pull-Request: #1740 Reviewed-by: Jean Privat --- diff --git a/contrib/memory/Makefile b/contrib/memory/Makefile index 8e39e1d..ac91a73 100644 --- a/contrib/memory/Makefile +++ b/contrib/memory/Makefile @@ -33,4 +33,4 @@ bin/memory.apk: assets/images/drawing.png src/*.nit res/drawable-ldpi/icon.png android-release: assets/images/drawing.png src/*.nit res/drawable-ldpi/icon.png mkdir -p bin - ../../bin/nitc -o bin/memory.apk src/memory.nit -m ../../lib/mnit/android/android.nit -m ../../lib/android/ landscape.nit --release + ../../bin/nitc -o bin/memory.apk src/memory.nit -m ../../lib/mnit/android/android.nit -m ../../lib/android/landscape.nit --release diff --git a/contrib/memory/org.nitlanguage.memory.txt b/contrib/memory/org.nitlanguage.memory.txt index 1bef17b..77756da 100644 --- a/contrib/memory/org.nitlanguage.memory.txt +++ b/contrib/memory/org.nitlanguage.memory.txt @@ -4,7 +4,7 @@ Web Site:http://nitlanguage.org Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/contrib/memory Issue Tracker:https://github.com/nitlang/nit/issues -Summary: memory-based game using shapes and colors +Summary:memory-based game using shapes and colors Description: A memory-based game where figures are cliqued in sequence by the computer and should be replayed by the player in the same order. As the player progresses, more figures are added and the sequences to remember become longer. diff --git a/contrib/memory/package.ini b/contrib/memory/package.ini index d271a73..9a79f36 100644 --- a/contrib/memory/package.ini +++ b/contrib/memory/package.ini @@ -9,3 +9,4 @@ git=https://github.com/nitlang/nit.git git.directory=contrib/memory/ homepage=http://nitlanguage.org issues=https://github.com/nitlang/nit/issues +apk=http://nitlanguage.org/fdroid/apk/memory.apk diff --git a/contrib/memory/src/memory.nit b/contrib/memory/src/memory.nit index 3e9877d..e184b99 100644 --- a/contrib/memory/src/memory.nit +++ b/contrib/memory/src/memory.nit @@ -27,6 +27,7 @@ # * Crappy UI element placement module memory is app_name("Memorize Shapes and Colors") + app_namespace "org.nitlanguage.memory" app_version(0, 1, git_revision) end diff --git a/contrib/mnit_test/package.ini b/contrib/mnit_test/package.ini index adcdf8f..5247640 100644 --- a/contrib/mnit_test/package.ini +++ b/contrib/mnit_test/package.ini @@ -1,6 +1,6 @@ [package] name=mnit_test -tags= +tags=testing maintainer=Alexis Laferrière license=Apache-2.0 [upstream] diff --git a/contrib/nitcc/tests/package.ini b/contrib/nitcc/tests/packages.ini similarity index 100% rename from contrib/nitcc/tests/package.ini rename to contrib/nitcc/tests/packages.ini diff --git a/examples/draw_operation.ini b/examples/draw_operation.ini index 189e88d..4ae4096 100644 --- a/examples/draw_operation.ini +++ b/examples/draw_operation.ini @@ -1,6 +1,6 @@ [package] name=draw_operation -tags= +tags=example maintainer=Alexis Laferrière license=Apache-2.0 [upstream] diff --git a/examples/mnit_ballz/org.nitlanguage.ballz_android.txt b/examples/mnit_ballz/org.nitlanguage.ballz.txt similarity index 100% rename from examples/mnit_ballz/org.nitlanguage.ballz_android.txt rename to examples/mnit_ballz/org.nitlanguage.ballz.txt diff --git a/lib/core/collection/abstract_collection.nit b/lib/core/collection/abstract_collection.nit index b65db67..6b07149 100644 --- a/lib/core/collection/abstract_collection.nit +++ b/lib/core/collection/abstract_collection.nit @@ -228,6 +228,16 @@ interface Iterator[E] # Iterate over `self` fun iterator: Iterator[E] do return self + # Pre-iteration hook. + # + # Used to inform `self` that the iteration is starting. + # Specific iterators can use this to prepare some resources. + # + # Is automatically invoked at the beginning of `for` structures. + # + # Do nothing by default. + fun start do end + # Post-iteration hook. # # Used to inform `self` that the iteration is over. @@ -708,6 +718,16 @@ interface MapIterator[K, V] # Set a new `item` at `key`. #fun item=(item: E) is abstract + # Pre-iteration hook. + # + # Used to inform `self` that the iteration is starting. + # Specific iterators can use this to prepare some resources. + # + # Is automatically invoked at the beginning of `for` structures. + # + # Do nothing by default. + fun start do end + # Post-iteration hook. # # Used to inform `self` that the iteration is over. diff --git a/lib/core/stream.nit b/lib/core/stream.nit index b4a0e2b..e8cb232 100644 --- a/lib/core/stream.nit +++ b/lib/core/stream.nit @@ -39,6 +39,26 @@ abstract class Stream # close the stream fun close is abstract + + # Pre-work hook. + # + # Used to inform `self` that operations will start. + # Specific streams can use this to prepare some resources. + # + # Is automatically invoked at the beginning of `with` structures. + # + # Do nothing by default. + fun start do end + + # Post-work hook. + # + # Used to inform `self` that the operations are over. + # Specific streams can use this to free some resources. + # + # Is automatically invoked at the end of `woth` structures. + # + # call `close` by default. + fun finish do close end # A `Stream` that can be read from @@ -425,6 +445,13 @@ interface Writable end end +redef class Bytes + super Writable + redef fun write_to(s) do s.write_bytes(self) + + redef fun write_to_string do return to_s +end + redef class Text super Writable redef fun write_to(stream) do stream.write(self) diff --git a/lib/gamnit/examples/triangle/src/portable_triangle.nit b/lib/gamnit/examples/triangle/src/portable_triangle.nit index ac8e0e6..624ec47 100644 --- a/lib/gamnit/examples/triangle/src/portable_triangle.nit +++ b/lib/gamnit/examples/triangle/src/portable_triangle.nit @@ -20,7 +20,7 @@ module portable_triangle is app_name "gamnit Triangle" app_namespace "org.nitlanguage.triangle" - app_version(1, 0, git_revision) + app_version(1, 1, git_revision) end import gamnit @@ -54,8 +54,8 @@ redef class App # GL program program = new GLProgram - if not program.is_ok then - print "Program is not ok: {gl.error.to_s}\nLog:" + if not glIsProgram(program) then + print "Program is not ok: {glGetError.to_s}\nLog:" print program.info_log abort end @@ -63,37 +63,37 @@ redef class App # Vertex shader vertex_shader = new GLVertexShader - assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl.error}" - vertex_shader.source = """ + assert glIsShader(vertex_shader) else print "Vertex shader is not ok: {glGetError}" + glShaderSource(vertex_shader, """ attribute vec4 vPosition; void main() { gl_Position = vPosition; } - """@glsl_vertex_shader.to_cstring - vertex_shader.compile + """@glsl_vertex_shader.to_cstring) + glCompileShader(vertex_shader) assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}" assert_no_gl_error # Fragment shader fragment_shader = new GLFragmentShader - assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl.error}" - fragment_shader.source = """ + assert glIsShader(fragment_shader) else print "Fragment shader is not ok: {glGetError}" + glShaderSource(fragment_shader, """ precision mediump float; void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } - """@glsl_fragment_shader.to_cstring - fragment_shader.compile + """@glsl_fragment_shader.to_cstring) + glCompileShader(fragment_shader) assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}" assert_no_gl_error # Attach to program - program.attach_shader vertex_shader - program.attach_shader fragment_shader + glAttachShader(program, vertex_shader) + glAttachShader(program, fragment_shader) program.bind_attrib_location(0, "vPosition") - program.link + glLinkProgram program assert program.is_linked else print "Linking failed: {program.info_log}" assert_no_gl_error @@ -103,30 +103,35 @@ redef class App vertex_array.attrib_pointer end + private var t = 0.0 + redef fun frame_core do var display = display if display != null then - gl.clear_color(0.5, 0.0, 0.5, 1.0) + glClearColor(t, t, t, 1.0) assert_no_gl_error - gl.viewport(0, 0, display.width, display.height) - gl.clear((new GLBuffer).color) - program.use + glViewport(0, 0, display.width, display.height) + glClear gl_COLOR_BUFFER_BIT + glUseProgram program vertex_array.enable - glDrawArrays(new GLDrawMode.triangles, 0, 3) + glDrawArrays(gl_TRIANGLES, 0, 3) display.flip + + t += 0.01 + if t > 1.0 then t = 0.0 end end redef fun on_stop do # Clean up - program.delete - vertex_shader.delete - fragment_shader.delete + glDeleteProgram program + glDeleteShader vertex_shader + glDeleteShader fragment_shader # Close gamnit var display = display diff --git a/lib/gamnit/examples/triangle/src/standalone_triangle.nit b/lib/gamnit/examples/triangle/src/standalone_triangle.nit index 04e14db..209597f 100644 --- a/lib/gamnit/examples/triangle/src/standalone_triangle.nit +++ b/lib/gamnit/examples/triangle/src/standalone_triangle.nit @@ -40,10 +40,10 @@ assert_no_gl_error assert gl.shader_compiler else print "Cannot compile shaders" # GL program -print gl.error.to_s +print glGetError.to_s var program = new GLProgram -if not program.is_ok then - print "Program is not ok: {gl.error.to_s}\nLog:" +if not glIsProgram(program) then + print "Program is not ok: {glGetError.to_s}\nLog:" print program.info_log abort end @@ -51,37 +51,37 @@ assert_no_gl_error # Vertex shader var vertex_shader = new GLVertexShader -assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl.error}" -vertex_shader.source = """ +assert glIsShader(vertex_shader) else print "Vertex shader is not ok: {glGetError}" +glShaderSource(vertex_shader, """ attribute vec4 vPosition; void main() { gl_Position = vPosition; } -"""@glsl_vertex_shader.to_cstring -vertex_shader.compile +"""@glsl_vertex_shader.to_cstring) +glCompileShader vertex_shader assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}" assert_no_gl_error # Fragment shader var fragment_shader = new GLFragmentShader -assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl.error}" -fragment_shader.source = """ +assert glIsShader(fragment_shader) else print "Fragment shader is not ok: {glGetError}" +glShaderSource(fragment_shader, """ precision mediump float; void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } -"""@glsl_fragment_shader.to_cstring -fragment_shader.compile +"""@glsl_fragment_shader.to_cstring) +glIsShader fragment_shader assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}" assert_no_gl_error # Attach to program -program.attach_shader vertex_shader -program.attach_shader fragment_shader +glAttachShader(program, vertex_shader) +glAttachShader(program, fragment_shader) program.bind_attrib_location(0, "vPosition") -program.link +glLinkProgram program assert program.is_linked else print "Linking failed: {program.info_log}" assert_no_gl_error @@ -89,24 +89,24 @@ assert_no_gl_error var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0] var vertex_array = new VertexArray(0, 3, vertices) vertex_array.attrib_pointer -gl.clear_color(0.5, 0.0, 0.5, 1.0) +glClearColor(0.5, 0.0, 0.5, 1.0) for i in [0..1000[ do printn "." assert_no_gl_error - gl.viewport(0, 0, width, height) - gl.clear((new GLBuffer).color) - program.use + glViewport(0, 0, width, height) + glClear gl_COLOR_BUFFER_BIT + glUseProgram program vertex_array.enable - glDrawArrays(new GLDrawMode.triangles, 0, 3) + glDrawArrays(gl_TRIANGLES, 0, 3) display.flip end # Clean up -program.delete -vertex_shader.delete -fragment_shader.delete +glDeleteProgram program +glDeleteShader vertex_shader +glDeleteShader fragment_shader # Close gamnit display.close diff --git a/lib/gen_nit.ini b/lib/gen_nit.ini new file mode 100644 index 0000000..0f1530c --- /dev/null +++ b/lib/gen_nit.ini @@ -0,0 +1,11 @@ +[package] +name=gen_nit +tags=devel +maintainer=Alexis Laferrière +license=Apache-2.0 +[upstream] +browse=https://github.com/nitlang/nit/tree/master/lib/gen_nit.nit +git=https://github.com/nitlang/nit.git +git.directory=lib/gen_nit.nit +homepage=http://nitlanguage.org +issues=https://github.com/nitlang/nit/issues diff --git a/lib/glesv2/.gitignore b/lib/glesv2/.gitignore new file mode 100644 index 0000000..6f7cefe --- /dev/null +++ b/lib/glesv2/.gitignore @@ -0,0 +1 @@ +glesv2_stub.nit diff --git a/lib/glesv2/Makefile b/lib/glesv2/Makefile new file mode 100644 index 0000000..df29bb6 --- /dev/null +++ b/lib/glesv2/Makefile @@ -0,0 +1,9 @@ +# Generate basic Nit wrapper for glesv2, must be adapted by hands afterwards +glesv2_stub.nit: + cat /usr/include/GLES2/gl2.h | sed \ + -e "s/GL_APICALL void GL_APIENTRY \([^ ]*\) /fun \1 \`{ \1/" \ + -e "s/GL_APICALL [^ ]* GL_APIENTRY \([^ ]*\) /fun \1: Int \`{ return \1/" \ + -e "s/;/; \`}/" \ + -e "s/#define GL_\([^ ]*\) .*/fun gl_\1: Int \`{ return GL_\1; \`}/" | grep fun > $@ + +.PHONY: glesv2_stub.nit diff --git a/lib/glesv2/examples/opengles2_hello_triangle.nit b/lib/glesv2/examples/opengles2_hello_triangle.nit index 3a1e1c5..340c307 100644 --- a/lib/glesv2/examples/opengles2_hello_triangle.nit +++ b/lib/glesv2/examples/opengles2_hello_triangle.nit @@ -112,10 +112,10 @@ assert_no_gl_error assert gl.shader_compiler else print "Cannot compile shaders" # gl program -print gl.error.to_s +print glGetError.to_s var program = new GLProgram -if not program.is_ok then - print "Program is not ok: {gl.error.to_s}\nLog:" +if not glIsProgram(program) then + print "Program is not ok: {glGetError.to_s}\nLog:" print program.info_log abort end @@ -123,36 +123,36 @@ assert_no_gl_error # vertex shader var vertex_shader = new GLVertexShader -assert vertex_shader.is_ok else print "Vertex shader is not ok: {gl.error}" -vertex_shader.source = """ +assert glIsShader(vertex_shader) else print "Vertex shader is not ok: {glGetError}" +glShaderSource(vertex_shader, """ attribute vec4 vPosition; void main() { gl_Position = vPosition; } -""".to_cstring -vertex_shader.compile +""".to_cstring) +glCompileShader vertex_shader assert vertex_shader.is_compiled else print "Vertex shader compilation failed with: {vertex_shader.info_log} {program.info_log}" assert_no_gl_error # fragment shader var fragment_shader = new GLFragmentShader -assert fragment_shader.is_ok else print "Fragment shader is not ok: {gl.error}" -fragment_shader.source = """ +assert glIsShader(fragment_shader) else print "Fragment shader is not ok: {glGetError}" +glShaderSource(fragment_shader, """ precision mediump float; void main() { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } -""".to_cstring -fragment_shader.compile +""".to_cstring) +glCompileShader(fragment_shader) assert fragment_shader.is_compiled else print "Fragment shader compilation failed with: {fragment_shader.info_log}" assert_no_gl_error -program.attach_shader vertex_shader -program.attach_shader fragment_shader +glAttachShader(program, vertex_shader) +glAttachShader(program, fragment_shader) program.bind_attrib_location(0, "vPosition") -program.link +glLinkProgram program assert program.is_linked else print "Linking failed: {program.info_log}" assert_no_gl_error @@ -160,30 +160,30 @@ assert_no_gl_error var vertices = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0] var vertex_array = new VertexArray(0, 3, vertices) vertex_array.attrib_pointer -gl.clear_color(0.5, 0.0, 0.5, 1.0) +glClearColor(0.5, 0.0, 0.5, 1.0) for i in [0..10000[ do printn "." assert_no_gl_error - gl.viewport(0, 0, width, height) - gl.clear((new GLBuffer).color) - program.use + glViewport(0, 0, width, height) + glClear gl_COLOR_BUFFER_BIT + glUseProgram program vertex_array.enable - glDrawArrays(new GLDrawMode.triangles, 0, 3) + glDrawArrays(gl_TRIANGLES, 0, 3) egl_display.swap_buffers(surface) end # delete -program.delete -vertex_shader.delete -fragment_shader.delete +glDeleteProgram program +glDeleteShader vertex_shader +glDeleteShader fragment_shader # ## EGL # # close egl_display.make_current(new EGLSurface.none, new EGLSurface.none, new EGLContext.none) -egl_display.destroy_context(context) -egl_display.destroy_surface(surface) +egl_display.destroy_context context +egl_display.destroy_surface surface # ## SDL diff --git a/lib/glesv2/glesv2.nit b/lib/glesv2/glesv2.nit index 9c3e1d7..526fc0b 100644 --- a/lib/glesv2/glesv2.nit +++ b/lib/glesv2/glesv2.nit @@ -50,12 +50,6 @@ extern class GLProgram `{GLuint`} # The newly created instance should be checked using `is_ok`. new `{ return glCreateProgram(); `} - # Is this a valid program? - fun is_ok: Bool `{ return glIsProgram(self); `} - - # Attach a `shader` to this program - fun attach_shader(shader: GLShader) `{ glAttachShader(self, shader); `} - # Set the location for the attribute by `name` fun bind_attrib_location(index: Int, name: String) import String.to_cstring `{ GLchar *c_name = String_to_cstring(name); @@ -85,28 +79,12 @@ extern class GLProgram `{GLuint`} return val; `} - # Try to link this program - # - # Check result using `in_linked` and `info_log`. - fun link `{ glLinkProgram(self); `} - # Is this program linked? fun is_linked: Bool do return query(0x8B82) != 0 - # Use this program for the following operations - fun use `{ glUseProgram(self); `} - - # Delete this program - fun delete `{ glDeleteProgram(self); `} - # Has this program been deleted? fun is_deleted: Bool do return query(0x8B80) != 0 - # Validate whether this program can be executed in the current OpenGL state - # - # Check results using `is_validated` and `info_log`. - fun validate `{ glValidateProgram(self); `} - # Boolean result of `validate`, must be called after `validate` fun is_validated: Bool do return query(0x8B83) != 0 @@ -210,12 +188,32 @@ extern class GLProgram `{GLuint`} `} end +# Create a program object +fun glCreateProgram: GLProgram `{ return glCreateProgram(); `} + +# Install the `program` as part of current rendering state +fun glUseProgram(program: GLProgram) `{ glUseProgram(program); `} + +# Link the `program` object +fun glLinkProgram(program: GLProgram) `{ glLinkProgram(program); `} + +# Validate the `program` object +fun glValidateProgram(program: GLProgram) `{ glValidateProgram(program); `} + +# Delete the `program` object +fun glDeleteProgram(program: GLProgram) `{ glDeleteProgram(program); `} + +# Determine if `name` corresponds to a program object +fun glIsProgram(name: GLProgram): Bool `{ return glIsProgram(name); `} + +# Attach a `shader` to `program` +fun glAttachShader(program: GLProgram, shader: GLShader) `{ glAttachShader(program, shader); `} + +# Detach `shader` from `program` +fun glDetachShader(program: GLProgram, shader: GLShader) `{ glDetachShader(program, shader); `} + # Abstract OpenGL ES shader object, implemented by `GLFragmentShader` and `GLVertexShader` extern class GLShader `{GLuint`} - # Set the source of the shader - fun source=(code: NativeString) `{ - glShaderSource(self, 1, (GLchar const **)&code, NULL); - `} # Source of the shader, if available # @@ -241,23 +239,12 @@ extern class GLShader `{GLuint`} return val; `} - # Try to compile `source` into a binary GPU program - # - # Check the result using `is_compiled` and `info_log` - fun compile `{ glCompileShader(self); `} - # Has this shader been compiled? fun is_compiled: Bool do return query(0x8B81) != 0 - # Delete this shader - fun delete `{ glDeleteShader(self); `} - # Has this shader been deleted? fun is_deleted: Bool do return query(0x8B80) != 0 - # Is this a valid shader? - fun is_ok: Bool `{ return glIsShader(self); `} - # Retrieve the information log of this shader # # Useful with `link` and `validate` @@ -270,6 +257,33 @@ extern class GLShader `{GLuint`} `} end +# Shader type +extern class GLShaderType + super GLEnum +end + +fun gl_VERTEX_SHADER: GLShaderType `{ return GL_VERTEX_SHADER; `} +fun gl_FRAGMENT_SHADER: GLShaderType `{ return GL_FRAGMENT_SHADER; `} + +# Create a shader object of the `shader_type` +fun glCreateShader(shader_type: GLShaderType): GLShader `{ + return glCreateShader(shader_type); +`} + +# Replace the source code in the `shader` object with `code` +fun glShaderSource(shader: GLShader, code: NativeString) `{ + glShaderSource(shader, 1, (GLchar const **)&code, NULL); +`} + +# Compile the `shader` object +fun glCompileShader(shader: GLShader) `{ glCompileShader(shader); `} + +# Delete the `shader` object +fun glDeleteShader(shader: GLShader) `{ glDeleteShader(shader); `} + +# Determine if `name` corresponds to a shader object +fun glIsShader(name: GLShader): Bool `{ return glIsShader(name); `} + # An OpenGL ES 2.0 fragment shader extern class GLFragmentShader super GLShader @@ -407,48 +421,119 @@ extern class GLEnum `{ GLenum `} redef fun ==(o) do return o != null and is_same_type(o) and o.hash == self.hash end +# Error information +fun glGetError: GLError `{ return glGetError(); `} + # An OpenGL ES 2.0 error code extern class GLError super GLEnum - # Is there no error? - fun is_ok: Bool do return is_no_error - - # Is this not an error? - fun is_no_error: Bool `{ return self == GL_NO_ERROR; `} - - fun is_invalid_enum: Bool `{ return self == GL_INVALID_ENUM; `} - fun is_invalid_value: Bool `{ return self == GL_INVALID_VALUE; `} - fun is_invalid_operation: Bool `{ return self == GL_INVALID_OPERATION; `} - fun is_invalid_framebuffer_operation: Bool `{ return self == GL_INVALID_FRAMEBUFFER_OPERATION; `} - fun is_out_of_memory: Bool `{ return self == GL_OUT_OF_MEMORY; `} - redef fun to_s do - if is_no_error then return "No error" - if is_invalid_enum then return "Invalid enum" - if is_invalid_value then return "Invalid value" - if is_invalid_operation then return "Invalid operation" - if is_invalid_framebuffer_operation then return "invalid framebuffer operation" - if is_out_of_memory then return "Out of memory" - return "Truely unknown error" + if self == gl_NO_ERROR then return "No error" + if self == gl_INVALID_ENUM then return "Invalid enum" + if self == gl_INVALID_VALUE then return "Invalid value" + if self == gl_INVALID_OPERATION then return "Invalid operation" + if self == gl_INVALID_FRAMEBUFFER_OPERATION then return "invalid framebuffer operation" + if self == gl_OUT_OF_MEMORY then return "Out of memory" + return "Unknown error" end end +fun gl_NO_ERROR: GLError `{ return GL_NO_ERROR; `} +fun gl_INVALID_ENUM: GLError `{ return GL_INVALID_ENUM; `} +fun gl_INVALID_VALUE: GLError `{ return GL_INVALID_VALUE; `} +fun gl_INVALID_OPERATION: GLError `{ return GL_INVALID_OPERATION; `} +fun gl_INVALID_FRAMEBUFFER_OPERATION: GLError `{ return GL_INVALID_FRAMEBUFFER_OPERATION; `} +fun gl_OUT_OF_MEMORY: GLError `{ return GL_OUT_OF_MEMORY; `} + fun assert_no_gl_error do - var error = gl.error - if not error.is_ok then + var error = glGetError + if not error == gl_NO_ERROR then print "GL error: {error}" abort end end -# Does `name` corresponds to a texture? -fun glIsTexture(name: Int): Bool `{ return glIsTexture(name); `} +# Texture unit, the number of texture units is implementation dependent +extern class GLTextureUnit + super GLEnum +end + +fun gl_TEXTURE0: GLTextureUnit `{ return GL_TEXTURE0; `} +fun gl_TEXTURE1: GLTextureUnit `{ return GL_TEXTURE1; `} +fun gl_TEXTURE2: GLTextureUnit `{ return GL_TEXTURE2; `} +fun gl_TEXTURE3: GLTextureUnit `{ return GL_TEXTURE3; `} +fun gl_TEXTURE4: GLTextureUnit `{ return GL_TEXTURE4; `} +fun gl_TEXTURE5: GLTextureUnit `{ return GL_TEXTURE5; `} +fun gl_TEXTURE6: GLTextureUnit `{ return GL_TEXTURE6; `} +fun gl_TEXTURE7: GLTextureUnit `{ return GL_TEXTURE7; `} +fun gl_TEXTURE8: GLTextureUnit `{ return GL_TEXTURE8; `} +fun gl_TEXTURE9: GLTextureUnit `{ return GL_TEXTURE9; `} +fun gl_TEXTURE10: GLTextureUnit `{ return GL_TEXTURE10; `} +fun gl_TEXTURE11: GLTextureUnit `{ return GL_TEXTURE11; `} +fun gl_TEXTURE12: GLTextureUnit `{ return GL_TEXTURE12; `} +fun gl_TEXTURE13: GLTextureUnit `{ return GL_TEXTURE13; `} +fun gl_TEXTURE14: GLTextureUnit `{ return GL_TEXTURE14; `} +fun gl_TEXTURE15: GLTextureUnit `{ return GL_TEXTURE15; `} +fun gl_TEXTURE16: GLTextureUnit `{ return GL_TEXTURE16; `} +fun gl_TEXTURE17: GLTextureUnit `{ return GL_TEXTURE17; `} +fun gl_TEXTURE18: GLTextureUnit `{ return GL_TEXTURE18; `} +fun gl_TEXTURE19: GLTextureUnit `{ return GL_TEXTURE19; `} +fun gl_TEXTURE20: GLTextureUnit `{ return GL_TEXTURE20; `} +fun gl_TEXTURE21: GLTextureUnit `{ return GL_TEXTURE21; `} +fun gl_TEXTURE22: GLTextureUnit `{ return GL_TEXTURE22; `} +fun gl_TEXTURE23: GLTextureUnit `{ return GL_TEXTURE23; `} +fun gl_TEXTURE24: GLTextureUnit `{ return GL_TEXTURE24; `} +fun gl_TEXTURE25: GLTextureUnit `{ return GL_TEXTURE25; `} +fun gl_TEXTURE26: GLTextureUnit `{ return GL_TEXTURE26; `} +fun gl_TEXTURE27: GLTextureUnit `{ return GL_TEXTURE27; `} +fun gl_TEXTURE28: GLTextureUnit `{ return GL_TEXTURE28; `} +fun gl_TEXTURE29: GLTextureUnit `{ return GL_TEXTURE29; `} +fun gl_TEXTURE30: GLTextureUnit `{ return GL_TEXTURE30; `} +fun gl_TEXTURE31: GLTextureUnit `{ return GL_TEXTURE31; `} + +# Texture unit at `offset` after `gl_TEXTURE0` +fun gl_TEXTURE(offset: Int): GLTextureUnit `{ return GL_TEXTURE0 + offset; `} + +# Generate `n` texture names +fun glGenTextures(n: Int): Array[Int] +do + var array = new CIntArray(n) + native_glGenTextures(n, array.native_array) + var a = array.to_a + array.destroy + return a +end + +private fun native_glGenTextures(n: Int, textures: NativeCIntArray) `{ + glGenTextures(n, (GLuint*)textures); +`} + +# Select server-side active texture unit +fun glActiveTexture(texture: GLTextureUnit) `{ glActiveTexture(texture); `} # Bind the named `texture` to a `target` -fun glBindTexture(target: GLTextureTarget, texture: Int) `{ glBindTexture(target, texture); `} +fun glBindTexture(target: GLTextureTarget, texture: Int) `{ + glBindTexture(target, texture); +`} + +# Delete named textures +fun glDeleteTextures(textures: SequenceRead[Int]) +do + var n = textures.length + var array = new CIntArray.from(textures) + native_glDeleteTextures(n, array.native_array) + array.destroy +end + +private fun native_glDeleteTextures(n: Int, textures: NativeCIntArray) `{ + glDeleteTextures(n, (const GLuint *)textures); +`} + +# Does `name` corresponds to a texture? +fun glIsTexture(name: Int): Bool `{ return glIsTexture(name); `} # Set pixel storage modes fun glPixelStorei(parameter: GLPack, val: Int) `{ glPixelStorei(parameter, val); `} @@ -468,34 +553,50 @@ fun gl_UNPACK_ALIGNEMENT: GLPack `{ return GL_UNPACK_ALIGNMENT; `} # GL_UNPACK_ROW_LENGTH, GL_UNPACK_IMAGE_HEIGHT, GL_UNPACK_SKIP_PIXELS, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SKIP_IMAGES # Specify a two-dimensional texture image -fun glTexImage2D(target: GLTextureTarget, level, internalformat, width, height, border: Int, - format: GLPixelFormat, typ: GLPixelType, data: NativeCByteArray) `{ +fun glTexImage2D(target: GLTextureTarget, level: Int, internalformat: GLPixelFormat, + width, height, border: Int, + format: GLPixelFormat, typ: GLPixelType, data: Pointer) `{ glTexImage2D(target, level, internalformat, width, height, border, format, typ, data); `} -# Texture minifying and magnifying function -extern class GLTextureFilter - super GLEnum -end +# Specify a two-dimensional texture subimage +fun glTexSubImage2D(target: GLTextureTarget, + level, xoffset, yoffset, width, height, border: Int, + format: GLPixelFormat, typ: GLPixelType, data: Pointer) `{ + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, typ, data); +`} -fun gl_NEAREST: GLTextureFilter `{ return GL_NEAREST; `} -fun gl_LINEAR: GLTextureFilter `{ return GL_LINEAR; `} -fun gl_NEAREST_MIPMAP_NEAREST: GLTextureFilter `{ return GL_NEAREST_MIPMAP_NEAREST; `} -fun gl_LINEAR_MIPMAP_NEAREST: GLTextureFilter `{ return GL_LINEAR_MIPMAP_NEAREST; `} -fun gl_NEAREST_MIPMAP_NINEAR: GLTextureFilter `{ return GL_NEAREST_MIPMAP_LINEAR; `} -fun gl_LINEAR_MIPMAP_LINEAR: GLTextureFilter `{ return GL_LINEAR_MIPMAP_LINEAR; `} +# Copy pixels into a 2D texture image +fun glCopyTexImage2D(target: GLTextureTarget, level: Int, internalformat: GLPixelFormat, + x, y, width, height, border: Int) `{ + glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +`} -# Wrap parameter of a texture -# -# Used by: `tex_parameter_wrap_*` -extern class GLTextureWrap - super GLEnum +# Copy a two-dimensional texture subimage +fun glCopyTexSubImage2D(target: GLTextureTarget, level, xoffset, yoffset, x, y, width, height: Int) `{ + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +`} + +# Copy a block of pixels from the framebuffer of `fomat` and `typ` at `data` +fun glReadPixels(x, y, width, height: Int, format: GLPixelFormat, typ: GLPixelType, data: Pointer) `{ + glReadPixels(x, y, width, height, format, typ, data); +`} - new clamp_to_edge `{ return GL_CLAMP_TO_EDGE; `} - new mirrored_repeat `{ return GL_MIRRORED_REPEAT; `} - new repeat `{ return GL_REPEAT; `} +# Texture minifying and magnifying function +extern class GLTexParameteri + super GLEnum end +fun gl_NEAREST: GLTexParameteri `{ return GL_NEAREST; `} +fun gl_LINEAR: GLTexParameteri `{ return GL_LINEAR; `} +fun gl_NEAREST_MIPMAP_NEAREST: GLTexParameteri `{ return GL_NEAREST_MIPMAP_NEAREST; `} +fun gl_LINEAR_MIPMAP_NEAREST: GLTexParameteri `{ return GL_LINEAR_MIPMAP_NEAREST; `} +fun gl_NEAREST_MIPMAP_NINEAR: GLTexParameteri `{ return GL_NEAREST_MIPMAP_LINEAR; `} +fun gl_LINEAR_MIPMAP_LINEAR: GLTexParameteri `{ return GL_LINEAR_MIPMAP_LINEAR; `} +fun gl_CLAMP_TO_EDGE: GLTexParameteri `{ return GL_CLAMP_TO_EDGE; `} +fun gl_MIRRORED_REPEAT: GLTexParameteri `{ return GL_MIRRORED_REPEAT; `} +fun gl_REPEAT: GLTexParameteri `{ return GL_REPEAT; `} + # Target texture extern class GLTextureTarget super GLEnum @@ -530,6 +631,38 @@ class GLCap redef fun ==(o) do return o != null and is_same_type(o) and o.hash == self.hash end +# Generate `n` renderbuffer object names +fun glGenRenderbuffers(n: Int): Array[Int] +do + var array = new CIntArray(n) + native_glGenRenderbuffers(n, array.native_array) + var a = array.to_a + array.destroy + return a +end + +private fun native_glGenRenderbuffers(n: Int, renderbuffers: NativeCIntArray) `{ + glGenRenderbuffers(n, (GLuint *)renderbuffers); +`} + +# Determine if `name` corresponds to a renderbuffer object +fun glIsRenderbuffer(name: Int): Bool `{ + return glIsRenderbuffer(name); +`} + +# Delete named renderbuffer objects +fun glDeleteRenderbuffers(renderbuffers: SequenceRead[Int]) +do + var n = renderbuffers.length + var array = new CIntArray.from(renderbuffers) + native_glDeleteRenderbuffers(n, array.native_array) + array.destroy +end + +private fun native_glDeleteRenderbuffers(n: Int, renderbuffers: NativeCIntArray) `{ + return glDeleteRenderbuffers(n, (const GLuint *)renderbuffers); +`} + # Attach a renderbuffer object to a framebuffer object fun glFramebufferRenderbuffer(target: GLFramebufferTarget, attachment: GLAttachment, renderbuffertarget: GLRenderbufferTarget, renderbuffer: Int) `{ @@ -585,46 +718,6 @@ fun gl: GLES do return sys.gles # OpenGL ES 2.0 services class GLES - # Clear the color buffer to `red`, `green`, `blue` and `alpha` - fun clear_color(red, green, blue, alpha: Float) `{ - glClearColor(red, green, blue, alpha); - `} - - # Set the viewport - fun viewport(x, y, width, height: Int) `{ glViewport(x, y, width, height); `} - - # Specify mapping of depth values from normalized device coordinates to window coordinates - # - # Default at `gl_depth_range(0.0, 1.0)` - fun depth_range(near, far: Float) `{ glDepthRangef(near, far); `} - - # Define front- and back-facing polygons - # - # Front-facing polygons are clockwise if `value`, counter-clockwise otherwise. - fun front_face=(value: Bool) `{ glFrontFace(value? GL_CW: GL_CCW); `} - - # Specify whether front- or back-facing polygons can be culled, default is `back` only - # - # One or both of `front` or `back` must be `true`. If you want to deactivate culling - # use `(new GLCap.cull_face).disable`. - # - # Require: `front or back` - fun cull_face(front, back: Bool) - do - assert not (front or back) - cull_face_native(front, back) - end - - private fun cull_face_native(front, back: Bool) `{ - glCullFace(front? back? GL_FRONT_AND_BACK: GL_BACK: GL_FRONT); - `} - - # Clear the `buffer` - fun clear(buffer: GLBuffer) `{ glClear(buffer); `} - - # Last error from OpenGL ES 2.0 - fun error: GLError `{ return glGetError(); `} - # Query the boolean value at `key` private fun get_bool(key: Int): Bool `{ GLboolean val; @@ -651,75 +744,51 @@ class GLES # Should always return `true` in OpenGL ES 2.0 and 3.0. fun shader_compiler: Bool do return get_bool(0x8DFA) - # Enable or disable writing into the depth buffer - fun depth_mask(value: Bool) `{ glDepthMask(value); `} - - # Set the scale and units used to calculate depth values - fun polygon_offset(factor, units: Float) `{ glPolygonOffset(factor, units); `} + # OpenGL server-side capabilities + var capabilities = new GLCapabilities is lazy +end - # Specify the width of rasterized lines - fun line_width(width: Float) `{ glLineWidth(width); `} +# Specify the clear values for the color buffer, default values are at 0.0 +fun glClearColor(red, green, blue, alpha: Float) `{ + glClearColor(red, green, blue, alpha); +`} - # Set the pixel arithmetic for the blending operations - # - # Defaultvalues before assignation: - # * `src_factor`: `GLBlendFactor::one` - # * `dst_factor`: `GLBlendFactor::zero` - fun blend_func(src_factor, dst_factor: GLBlendFactor) `{ - glBlendFunc(src_factor, dst_factor); - `} +# Specify the clear `value` for the depth buffer, default at 1.0 +fun glClearDepthf(value: Float) `{ glClearDepthf(value); `} - # Specify the value used for depth buffer comparisons - # - # Default value is `GLDepthFunc::less` - # - # Foreign: glDepthFunc - fun depth_func(func: GLDepthFunc) `{ glDepthFunc(func); `} +# Specify the clear `value` for the stencil buffer, default at 0 +fun glClearStencil(value: Int) `{ glClearStencil(value); `} - # Copy a block of pixels from the framebuffer of `fomat` and `typ` at `data` - # - # Foreign: glReadPixel - fun read_pixels(x, y, width, height: Int, format: GLPixelFormat, typ: GLPixelType, data: Pointer) `{ - glReadPixels(x, y, width, height, format, typ, data); - `} +# Clear the `buffer` +fun glClear(buffer: GLBuffer) `{ glClear(buffer); `} - # Set the texture minifying function - # - # Foreign: glTexParameter with GL_TEXTURE_MIN_FILTER - fun tex_parameter_min_filter(target: GLTextureTarget, value: GLTextureFilter) `{ - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, value); - `} +# Enable and disable writing of frame buffer color components +fun glColorMask(red, green, blue, alpha: Bool) `{ glColorMask(red, green, blue, alpha); `} - # Set the texture magnification function - # - # Foreign: glTexParameter with GL_TEXTURE_MAG_FILTER - fun tex_parameter_mag_filter(target: GLTextureTarget, value: GLTextureFilter) `{ - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, value); - `} +# Set the viewport +fun glViewport(x, y, width, height: Int) `{ glViewport(x, y, width, height); `} - # Set the texture wrap parameter for coordinates _s_ - # - # Foreign: glTexParameter with GL_TEXTURE_WRAP_S - fun tex_parameter_wrap_s(target: GLTextureTarget, value: GLTextureWrap) `{ - glTexParameteri(target, GL_TEXTURE_WRAP_S, value); - `} +# Block until all GL execution is complete +fun glFinish `{ glFinish(); `} - # Set the texture wrap parameter for coordinates _t_ - # - # Foreign: glTexParameter with GL_TEXTURE_WRAP_T - fun tex_parameter_wrap_t(target: GLTextureTarget, value: GLTextureWrap) `{ - glTexParameteri(target, GL_TEXTURE_WRAP_T, value); - `} +# Force execution of GL commands in finite time +fun glFlush `{ glFlush(); `} - # Render primitives from array data - # - # Foreign: glDrawArrays - fun draw_arrays(mode: GLDrawMode, from, count: Int) `{ glDrawArrays(mode, from, count); `} +# Set texture parameters +fun glTexParameteri(target: GLTextureTarget, pname: GLTexParameteriName, param: GLTexParameteri) `{ + glTexParameteri(target, pname, param); +`} - # OpenGL server-side capabilities - var capabilities = new GLCapabilities is lazy +# Name of parameters of textures +extern class GLTexParameteriName + super GLEnum end +fun gl_TEXTURE_MIN_FILTER: GLTexParameteriName `{ return GL_TEXTURE_MIN_FILTER; `} +fun gl_TEXTURE_MAG_FILTER: GLTexParameteriName `{ return GL_TEXTURE_MAG_FILTER; `} +fun gl_TEXTURE_WRAP_S: GLTexParameteriName `{ return GL_TEXTURE_WRAP_S; `} +fun gl_TEXTURE_WRAP_T: GLTexParameteriName `{ return GL_TEXTURE_WRAP_T; `} + # Bind `framebuffer` to a framebuffer target # # In OpenGL ES 2.0, `target` must be `gl_FRAMEBUFFER`. @@ -839,6 +908,38 @@ fun gl_NICEST: GLHintMode `{ return GL_NICEST; `} # No preference fun gl_DONT_CARE: GLHintMode `{ return GL_DONT_CARE; `} +# Generate `n` framebuffer object names +fun glGenFramebuffers(n: Int): Array[Int] +do + var array = new CIntArray(n) + native_glGenFramebuffers(n, array.native_array) + var a = array.to_a + array.destroy + return a +end + +private fun native_glGenFramebuffers(n: Int, textures: NativeCIntArray) `{ + glGenFramebuffers(n, (GLuint *)textures); +`} + +# Determine if `name` corresponds to a framebuffer object +fun glIsFramebuffer(name: Int): Bool `{ + return glIsFramebuffer(name); +`} + +# Delete named framebuffer objects +fun glDeleteFramebuffers(framebuffers: SequenceRead[Int]) +do + var n = framebuffers.length + var array = new CIntArray.from(framebuffers) + native_glDeleteFramebuffers(n, array.native_array) + array.destroy +end + +private fun native_glDeleteFramebuffers(n: Int, framebuffers: NativeCIntArray) `{ + return glDeleteFramebuffers(n, (const GLuint *)framebuffers); +`} + # Attach a level of a texture object as a logical buffer to the currently bound framebuffer object fun glFramebufferTexture2D(target: GLFramebufferTarget, attachment: GLAttachment, texture_target: GLTextureTarget, texture, level: Int) `{ @@ -935,99 +1036,126 @@ extern class GLDataType fun is_sampler_cube: Bool `{ return self == GL_SAMPLER_CUBE; `} end -# Kind of primitives to render with `GLES::draw_arrays` +# Kind of primitives to render extern class GLDrawMode super GLEnum - - new points `{ return GL_POINTS; `} - new line_strip `{ return GL_LINE_STRIP; `} - new line_loop `{ return GL_LINE_LOOP; `} - new lines `{ return GL_LINES; `} - new triangle_strip `{ return GL_TRIANGLE_STRIP; `} - new triangle_fan `{ return GL_TRIANGLE_FAN; `} - new triangles `{ return GL_TRIANGLES; `} end +fun gl_POINTS: GLDrawMode `{ return GL_POINTS; `} +fun gl_LINES: GLDrawMode `{ return GL_LINES; `} +fun gl_LINE_LOOP: GLDrawMode `{ return GL_LINE_LOOP; `} +fun gl_LINE_STRIP: GLDrawMode `{ return GL_LINE_STRIP; `} +fun gl_TRIANGLES: GLDrawMode `{ return GL_TRIANGLES; `} +fun gl_TRIANGLE_STRIP: GLDrawMode `{ return GL_TRIANGLE_STRIP; `} +fun gl_TRIANGLE_FAN: GLDrawMode `{ return GL_TRIANGLE_FAN; `} + # Pixel arithmetic for blending operations -# -# Used by `GLES::blend_func` extern class GLBlendFactor super GLEnum - - new zero `{ return GL_ZERO; `} - new one `{ return GL_ONE; `} - new src_color `{ return GL_SRC_COLOR; `} - new one_minus_src_color `{ return GL_ONE_MINUS_SRC_COLOR; `} - new dst_color `{ return GL_DST_COLOR; `} - new one_minus_dst_color `{ return GL_ONE_MINUS_DST_COLOR; `} - new src_alpha `{ return GL_SRC_ALPHA; `} - new one_minus_src_alpha `{ return GL_ONE_MINUS_SRC_ALPHA; `} - new dst_alpha `{ return GL_DST_ALPHA; `} - new one_minus_dst_alpha `{ return GL_ONE_MINUS_DST_ALPHA; `} - new constant_color `{ return GL_CONSTANT_COLOR; `} - new one_minus_constant_color `{ return GL_ONE_MINUS_CONSTANT_COLOR; `} - new constant_alpha `{ return GL_CONSTANT_ALPHA; `} - new one_minus_constant_alpha `{ return GL_ONE_MINUS_CONSTANT_ALPHA; `} - - # Used for destination only - new src_alpha_saturate `{ return GL_SRC_ALPHA_SATURATE; `} end +fun gl_ZERO: GLBlendFactor `{ return GL_ZERO; `} +fun gl_ONE: GLBlendFactor `{ return GL_ONE; `} +fun gl_SRC_COLOR: GLBlendFactor `{ return GL_SRC_COLOR; `} +fun gl_ONE_MINUS_SRC_COLOR: GLBlendFactor `{ return GL_ONE_MINUS_SRC_COLOR; `} +fun gl_SRC_ALPHA: GLBlendFactor `{ return GL_SRC_ALPHA; `} +fun gl_ONE_MINUS_SRC_ALPHA: GLBlendFactor `{ return GL_ONE_MINUS_SRC_ALPHA; `} +fun gl_DST_ALPHA: GLBlendFactor `{ return GL_DST_ALPHA; `} +fun gl_ONE_MINUS_DST_ALPHA: GLBlendFactor `{ return GL_ONE_MINUS_DST_ALPHA; `} +fun gl_DST_COLOR: GLBlendFactor `{ return GL_DST_COLOR; `} +fun gl_ONE_MINUS_DST_COLOR: GLBlendFactor `{ return GL_ONE_MINUS_DST_COLOR; `} +fun gl_SRC_ALPHA_SATURATE: GLBlendFactor `{ return GL_SRC_ALPHA_SATURATE; `} + # Condition under which a pixel will be drawn -# -# Used by `GLES::depth_func` extern class GLDepthFunc super GLEnum - - new never `{ return GL_NEVER; `} - new less `{ return GL_LESS; `} - new equal `{ return GL_EQUAL; `} - new lequal `{ return GL_LEQUAL; `} - new greater `{ return GL_GREATER; `} - new not_equal `{ return GL_NOTEQUAL; `} - new gequal `{ return GL_GEQUAL; `} - new always `{ return GL_ALWAYS; `} end +fun gl_NEVER: GLDepthFunc `{ return GL_NEVER; `} +fun gl_LESS: GLDepthFunc `{ return GL_LESS; `} +fun gl_EQUAL: GLDepthFunc `{ return GL_EQUAL; `} +fun gl_LEQUAL: GLDepthFunc `{ return GL_LEQUAL; `} +fun gl_GREATER: GLDepthFunc `{ return GL_GREATER; `} +fun gl_NOTEQUAL: GLDepthFunc `{ return GL_NOTEQUAL; `} +fun gl_GEQUAL: GLDepthFunc `{ return GL_GEQUAL; `} +fun gl_ALWAYS: GLDepthFunc `{ return GL_ALWAYS; `} + # Format of pixel data -# -# Used by `GLES::read_pixels` extern class GLPixelFormat super GLEnum - - new alpha `{ return GL_ALPHA; `} - new rgb `{ return GL_RGB; `} - new rgba `{ return GL_RGBA; `} end +fun gl_ALPHA: GLPixelFormat `{ return GL_ALPHA; `} +fun gl_RGB: GLPixelFormat `{ return GL_RGB; `} +fun gl_RGBA: GLPixelFormat `{ return GL_RGBA; `} + # Data type of pixel data -# -# Used by `GLES::read_pixels` extern class GLPixelType super GLEnum - - new unsigned_byte `{ return GL_UNSIGNED_BYTE; `} - new unsigned_short_5_6_5 `{ return GL_UNSIGNED_SHORT_5_6_5; `} - new unsigned_short_4_4_4_4 `{ return GL_UNSIGNED_SHORT_4_4_4_4; `} - new unsigned_short_5_5_5_1 `{ return GL_UNSIGNED_SHORT_5_5_5_1; `} end -# Set of buffers as a bitwise OR mask, used by `GLES::clear` -# -# ~~~ -# var buffers = (new GLBuffer).color.depth -# gl.clear buffers -# ~~~ +fun gl_UNSIGNED_BYTE: GLPixelType `{ return GL_UNSIGNED_BYTE; `} +fun gl_UNSIGNED_SHORT_5_6_5: GLPixelType `{ return GL_UNSIGNED_SHORT_5_6_5; `} +fun gl_UNSIGNED_SHORT_4_4_4_4: GLPixelType `{ return GL_UNSIGNED_SHORT_4_4_4_4; `} +fun gl_UNSIGNED_SHORT_5_5_5_1: GLPixelType `{ return GL_UNSIGNED_SHORT_5_5_5_1; `} + +# Set of buffers as a bitwise OR mask extern class GLBuffer `{ GLbitfield `} - # Get an empty set of buffers - new `{ return 0; `} + # Bitwise OR with `other` + fun |(other: GLBuffer): GLBuffer `{ return self | other; `} +end + +fun gl_DEPTH_BUFFER_BIT: GLBuffer `{ return GL_DEPTH_BUFFER_BIT; `} +fun gl_STENCIL_BUFFER_BIT: GLBuffer `{ return GL_STENCIL_BUFFER_BIT; `} +fun gl_COLOR_BUFFER_BIT: GLBuffer `{ return GL_COLOR_BUFFER_BIT; `} + +# Define front- and back-facing polygons, `gc_CCW` by default +fun glFrontFace(mode: GLFrontFaceMode) `{ glFrontFace(mode); `} - # Add the color buffer to the returned buffer set - fun color: GLBuffer `{ return self | GL_COLOR_BUFFER_BIT; `} +# Orientation of front-facing polygons +extern class GLFrontFaceMode + super GLEnum +end + +fun gl_CW: GLFrontFaceMode `{ return GL_CW; `} +fun gl_CCW: GLFrontFaceMode `{ return GL_CCW; `} - # Add the depth buffer to the returned buffer set - fun depth: GLBuffer `{ return self | GL_DEPTH_BUFFER_BIT; `} +# Specify whether front- or back-facing polygons can be culled, default is `back` only +fun glCullFace(mode: GLCullFaceMode) `{ glCullFace(mode); `} - # Add the stencil buffer to the returned buffer set - fun stencil: GLBuffer `{ return self | GL_STENCIL_BUFFER_BIT; `} +# Candidates for culling +extern class GLCullFaceMode + super GLEnum end + +fun gl_FRONT: GLCullFaceMode `{ return GL_FRONT; `} +fun gl_BACK: GLCullFaceMode `{ return GL_BACK; `} +fun gl_FRONT_AND_BACK: GLCullFaceMode `{ return GL_FRONT_AND_BACK; `} + +# Specify mapping of depth values from normalized device coordinates to window coordinates +# +# Default at 0.0, 1.0. +fun glDepthRangef(near, far: Float) `{ glDepthRangef(near, far); `} + +# Enable or disable writing into the depth buffer +fun glDepthMask(value: Bool) `{ glDepthMask(value); `} + +# Specify the value used for depth buffer comparisons +# +# Default value is `gl_LESS` +fun glDepthFunc(func: GLDepthFunc) `{ glDepthFunc(func); `} + +# Set the pixel arithmetic for the blending operations +# +# Default values: +# * `src_factor`: `gl_ONE` +# * `dst_factor`: `gl_ZERO` +fun glBlendFunc(src_factor, dst_factor: GLBlendFactor) `{ + glBlendFunc(src_factor, dst_factor); +`} + +# Set the scale and units used to calculate depth values +fun glPolygonOffset(factor, units: Float) `{ glPolygonOffset(factor, units); `} + +# Specify the width of rasterized lines +fun glLineWidth(width: Float) `{ glLineWidth(width); `} diff --git a/lib/ordered_tree.nit b/lib/ordered_tree.nit index 0b1d383..d1dde15 100644 --- a/lib/ordered_tree.nit +++ b/lib/ordered_tree.nit @@ -128,7 +128,15 @@ class OrderedTree[E: Object] do var old_parent = parents.get_or_null(e) if old_parent != null then - sub[old_parent].remove(e) + var subs = sub[old_parent] + subs.remove(e) + if subs.is_empty then + # remove the sub when all children are detached + # so that `==` and `hash` are sane + # Otherwise an empty array will be considered + # differently than no array. + sub.keys.remove(old_parent) + end else if roots.has(e) then roots.remove(e) end @@ -149,6 +157,7 @@ class OrderedTree[E: Object] do if not sub.has_key(e) then return var subs = sub[e] + if subs.is_empty then return var last = subs.last for e2 in subs do if e2 != last then diff --git a/lib/text_stat.ini b/lib/text_stat.ini new file mode 100644 index 0000000..fb0ab2b --- /dev/null +++ b/lib/text_stat.ini @@ -0,0 +1,11 @@ +[package] +name=text_stat +tags=debug,lib +maintainer=Lucas Bajolet +license=Apache-2.0 +[upstream] +browse=https://github.com/nitlang/nit/tree/master/lib/text_stat.nit +git=https://github.com/nitlang/nit.git +git.directory=lib/text_stat.nit +homepage=http://nitlanguage.org +issues=https://github.com/nitlang/nit/issues diff --git a/misc/vim/syntax/nit.vim b/misc/vim/syntax/nit.vim index 2930d81..b5d86ac 100644 --- a/misc/vim/syntax/nit.vim +++ b/misc/vim/syntax/nit.vim @@ -88,7 +88,7 @@ syn match NITComment "#.*" contains=NITTodo,@Spell " Keywords syn keyword NITKeyword abstract intern new syn keyword NITDefine private public protected intrude readable writable redef -syn keyword NITControl if while for assert and or in as isa once break continue return abort +syn keyword NITControl if while for with assert and or in as isa once break continue return abort syn keyword NITClass nullable syn keyword NITInclude special syn keyword NITTodo FIXME NOTE TODO XXX contained diff --git a/src/loader.nit b/src/loader.nit index a59ccf0..a914b56 100644 --- a/src/loader.nit +++ b/src/loader.nit @@ -323,7 +323,7 @@ redef class ModelBuilder fun identify_file(path: String): nullable ModulePath do # special case for not a nit file - if path.file_extension != "nit" then + if not path.has_suffix(".nit") then # search dirless files in known -I paths if not path.chars.has('/') then var res = search_module_in_paths(null, path, self.paths) @@ -352,10 +352,12 @@ redef class ModelBuilder end # Fast track, the path is already known - var pn = path.basename(".nit") + if identified_files_by_path.has_key(path) then return identified_files_by_path[path] var rp = module_absolute_path(path) if identified_files_by_path.has_key(rp) then return identified_files_by_path[rp] + var pn = path.basename(".nit") + # Search for a group var mgrouppath = path.join_path("..").simplify_path var mgroup = get_mgroup(mgrouppath) @@ -380,6 +382,7 @@ redef class ModelBuilder mgroup.module_paths.add(res) identified_files_by_path[rp] = res + identified_files_by_path[path] = res identified_files.add(res) return res end @@ -393,10 +396,15 @@ redef class ModelBuilder # Note: `paths` is also used to look for mgroups fun get_mgroup(dirpath: String): nullable MGroup do - if not dirpath.file_exists then do + var stat = dirpath.file_stat + + if stat == null then do + # search dirless directories in known -I paths + if dirpath.chars.has('/') then return null for p in paths do var try = p / dirpath - if try.file_exists then + stat = try.file_stat + if stat != null then dirpath = try break label end @@ -404,20 +412,19 @@ redef class ModelBuilder return null end label + # Filter out non-directories + if not stat.is_dir then + return null + end + + # Fast track, the path is already known var rdp = module_absolute_path(dirpath) if mgroups.has_key(rdp) then return mgroups[rdp] end - # Filter out non-directories - var stat = dirpath.file_stat - if stat == null or not stat.is_dir then - mgroups[rdp] = null - return null - end - # By default, the name of the package or group is the base_name of the directory - var pn = rdp.basename(".nit") + var pn = rdp.basename # Check `package.ini` that indicate a package var ini = null @@ -525,23 +532,24 @@ redef class ModelBuilder var fp = p/f var g = get_mgroup(fp) # Recursively scan for groups of the same package - if g != null and g.mpackage == mgroup.mpackage then + if g == null then + identify_file(fp) + else if g.mpackage == mgroup.mpackage then scan_group(g) end - identify_file(fp) end end # Transform relative paths (starting with '../') into absolute paths private fun module_absolute_path(path: String): String do - return getcwd.join_path(path).simplify_path + return path.realpath end # Try to load a module AST using a path. # Display an error if there is a problem (IO / lexer / parser) and return null fun load_module_ast(filename: String): nullable AModule do - if filename.file_extension != "nit" then + if not filename.has_suffix(".nit") then self.toolcontext.error(null, "Error: file `{filename}` is not a valid nit module.") return null end diff --git a/tests/sav/nitls_args1.res b/tests/sav/nitls_args1.res index 19b7801..eca970e 100644 --- a/tests/sav/nitls_args1.res +++ b/tests/sav/nitls_args1.res @@ -10,4 +10,3 @@ project1 (project1) `--subdir (project1/subdir) |--module4 (project1/subdir/module4.nit) `--module_0 (project1/subdir/module_0.nit) -project2 (project1/project2/project2.nit) diff --git a/tests/sav/nitls_args2.res b/tests/sav/nitls_args2.res index 19b7801..eca970e 100644 --- a/tests/sav/nitls_args2.res +++ b/tests/sav/nitls_args2.res @@ -10,4 +10,3 @@ project1 (project1) `--subdir (project1/subdir) |--module4 (project1/subdir/module4.nit) `--module_0 (project1/subdir/module_0.nit) -project2 (project1/project2/project2.nit) diff --git a/tests/sav/nitls_args4.res b/tests/sav/nitls_args4.res index a8b51a5..267bbdb 100644 --- a/tests/sav/nitls_args4.res +++ b/tests/sav/nitls_args4.res @@ -8,4 +8,3 @@ project1/subdir/module_0 (project1/subdir/module_0.nit) project1/module_01 (project1/module_01.nit) project1/module_02 (project1/module_02.nit) project1/project1 (project1/project1.nit) -project2/project2 (project1/project2/project2.nit) diff --git a/tests/sav/test_with.res b/tests/sav/test_with.res new file mode 100644 index 0000000..bd8974e --- /dev/null +++ b/tests/sav/test_with.res @@ -0,0 +1,9 @@ +1 +2 +3 +4 +1 +one +2 +two +# Regression test for the Nit project diff --git a/tests/test_with.nit b/tests/test_with.nit new file mode 100644 index 0000000..89757d4 --- /dev/null +++ b/tests/test_with.nit @@ -0,0 +1,32 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +var a = [1,2,3,4] +with i = a.iterator do while i.is_ok do + print i.item + i.next +end + +var m = new HashMap[Int, String] +m[1] = "one" +m[2] = "two" +with i = m.iterator do while i.is_ok do + print i.key + print i.item + i.next +end + +with f = "README.md".to_path.open_ro do + print f.read_line +end