Era-Dorta / gosu-android

A Gosu implementation for Android devices, undergraduate project
MIT License
31 stars 2 forks source link

Stack Level Too Deep Crash #1

Closed ashes999 closed 11 years ago

ashes999 commented 11 years ago

Hi,

I just installed gosu today via Ruby 1.9.3 (gem install ...) on Windows. I have confirmed that:

However, I can't get a working combination of the two. When I generate a new ruboto sample app and just add require 'gosu', I get this exception at runtime:

FATAL EXCEPTION: Thread-11 org.jruby.embed.EvalFailedException: (SystemStackError) stack level too deep .. at RUBY.JavaImports(file:/data/app/com.blastcube-1.apk!/lib/requires.rb:7

Full exception is pictured below. I followed the deployment instructions from the trunk branch

Screenshot below of logcat on Bluestacks.

logcat

Era-Dorta commented 11 years ago

Hi, First thanks for taking interest in this project. The problem appears because on Android you cannot use directly a relative file path to load stuff.

@background_image = Gosu::Image.new(self, "media/background.jpg", true)

So you have two options:

@background_image = Gosu::Image.new(self, "media/background.jpg", true)

to

@background_image = Gosu::Image.new(self, Ruboto::R::drawable::background, true)

and that should do the trick.

Anyway I'm still working to release a first stable version of gosu-android also, sometime soon I'll upload new samples and I'll create a wiki with more detailed information.

ashes999 commented 11 years ago

Hi,

Thanks for your reply. I don't think that's the problem, because I deleted all of that code -- I only have a standard, freshly-generated Ruboto app, with one additional line:

include 'gosu'

This is enough to show this error; I don't even load any images, sounds, etc. It may be because I'm using BlueStacks, so I'll see if I get a chance to try it on a real phone.

Cheers (great project by the way)!

Era-Dorta commented 11 years ago

I just realize that the error occurs when loading android openGL libraries.

java_import "javax.microedition.khronos.egl.EGL10" 

I don't have any experience in BlueStacks, could you add this line to your main.rb file an tell me the output? So far I've tested the code in a real device with Android 3.0 and in an emulator created with the android sdk.

ashes999 commented 11 years ago

Hi,

I have the OpenGL 3d rotating cube OpenGL sample that ships with Ruboto working (code is below). It works fine (the same as ruboto-irb). It uses Android OpenGL, and has the same line of code you asked me about.

#
# glsurfaceview.rb (by Scott Moyer)
#
# This demo ports the GLSurfaceView demo from the Android
# API Demos to Ruboto.
#
#######################################################

require 'ruboto/widget'
require 'ruboto/activity'

#require 'opengl'

java_import "javax.microedition.khronos.egl.EGL10"
java_import "javax.microedition.khronos.egl.EGLConfig"
java_import "javax.microedition.khronos.opengles.GL10"

java_import "java.nio.ByteBuffer"
java_import "java.nio.ByteOrder"
java_import "java.nio.IntBuffer"

ruboto_import_widget :GLSurfaceView, "android.opengl"

##########################
#
# Cube Class
#
# Needs to get set up before the Activity tries to use it
#

class Cube
  def initialize
    one = 0x10000
    vertices = [
      -one, -one, -one,
       one, -one, -one,
       one, one, -one,
      -one, one, -one,
      -one, -one, one,
       one, -one, one,
       one, one, one,
      -one, one, one,
    ]

    colors = [
        0, 0, 0, one,
      one, 0, 0, one,
      one, one, 0, one,
        0, one, 0, one,
        0, 0, one, one,
      one, 0, one, one,
      one, one, one, one,
        0, one, one, one,
     ]

    indices = [
      0, 4, 5, 0, 5, 1,
      1, 5, 6, 1, 6, 2,
      2, 6, 7, 2, 7, 3,
      3, 7, 4, 3, 4, 0,
      4, 7, 6, 4, 6, 5,
      3, 0, 1, 3, 1, 2
    ]

    vbb = ByteBuffer.allocateDirect(vertices.length*4)
    vbb.order(ByteOrder.nativeOrder)
    @vertex_buffer = vbb.asIntBuffer
    @vertex_buffer.put(vertices.to_java(:int))
    @vertex_buffer.position(0)

    cbb = ByteBuffer.allocateDirect(colors.length*4)
    cbb.order(ByteOrder.nativeOrder)
    @color_buffer = cbb.asIntBuffer
    @color_buffer.put(colors.to_java(:int))
    @color_buffer.position(0)

    @index_buffer = ByteBuffer.allocateDirect(indices.length)
    @index_buffer.put(indices.to_java(:byte))
    @index_buffer.position(0)
  end

  def draw(gl)
    gl.glFrontFace(GL10::GL_CW)
    gl.glVertexPointer(3, GL10::GL_FIXED, 0, @vertex_buffer)
    gl.glColorPointer(4, GL10::GL_FIXED, 0, @color_buffer)
    gl.glDrawElements(GL10::GL_TRIANGLES, 36, GL10::GL_UNSIGNED_BYTE, @index_buffer)
  end
end

#######################################################
#
# RubotoGLSurfaceViewRenderer
#
# The interface android.opengl.GLSurfaceView$Renderer
#

class RubotoGLSurfaceViewRenderer
  def initialize
    @translucent_background = false
    @cube = Cube.new
    @angle = 0.0
    @offset = 1.2
  end

  def onDrawFrame(gl)
    gl.glClear(GL10::GL_COLOR_BUFFER_BIT | GL10::GL_DEPTH_BUFFER_BIT)

    gl.glMatrixMode(GL10::GL_MODELVIEW)
    gl.glLoadIdentity
    gl.glTranslatef(0, 0, -3.0)
    gl.glRotatef(@angle, 0, 1, 0)
    gl.glRotatef(@angle*0.25, 1, 0, 0)

    gl.glEnableClientState(GL10::GL_VERTEX_ARRAY)
    gl.glEnableClientState(GL10::GL_COLOR_ARRAY)

    @cube.draw(gl)

    gl.glRotatef(@angle*2.0, 0, 1, 1)
    gl.glTranslatef(0.5, 0.5, 0.5)

    @cube.draw(gl)
    @angle += @offset
  end

  def onSurfaceChanged(gl, width, height)
    gl.glViewport(0, 0, width, height)
    ratio = width.to_f / height.to_f
    gl.glMatrixMode(GL10::GL_PROJECTION)
    gl.glLoadIdentity
    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10)
  end

  def onSurfaceCreated(gl, config)
    gl.glDisable(GL10::GL_DITHER)

    gl.glHint(GL10::GL_PERSPECTIVE_CORRECTION_HINT, GL10::GL_FASTEST)

    if (@translucent_background)
      gl.glClearColor(0,0,0,0)
    else
      gl.glClearColor(1,1,1,1)
    end
    gl.glEnable(GL10::GL_CULL_FACE)
    gl.glShadeModel(GL10::GL_SMOOTH)
    gl.glEnable(GL10::GL_DEPTH_TEST)
  end

  def change_angle
    @offset = -@offset
  end
end

class RubotoTestActivity
  def on_create(bundle)
    super

    begin
      action_bar.hide
    rescue
      set_title("GLSurfaceView Demo")
    end

    @renderer = RubotoGLSurfaceViewRenderer.new
    @surface_view = g_l_surface_view :renderer => @renderer, 
                                     :on_click_listener => (proc{@renderer.change_angle})

    self.content_view = @surface_view
  end 

  def on_resume
    super
    @surface_view.on_resume
  end

  def on_pause
    super
    @surface_view.on_pause
  end

end
ashes999 commented 11 years ago

Sorry, I should have just listened to you from the start.

Runs fine on my real phone. If I start importing stuff in my main .rb file before requiring gosu, eventually I'll get to the point where I java_import the color file and it needs a constant that's not defined (Gosu::Color). It seems like the Bluestacks emulator just has a poorly-sized stack frame limit.

On my real device, I can get a "hello world" ruboto app with require 'gosu' running. But as soon as I start adding any code, I run into this error again (the stack trace seems to be `require 'gosu' => reuiqre 'lib/main-window' => require 'lib/requires'). There seems to be some sort of infinite requires loop.

Here's the stack from Bluestacks:

org.jruby.embed.EvalFailedException: (SystemStackError) stack level too deep
  at org.jruby.embed.internal.EmbedEvaultUnitImpl.run(EmbedEvaultUnitImpl.java:133)
  at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1264)
  at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1257)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:507)
  at org.ruboto.JRubyAdapter.runScriptlet(JRubyAdapter.java:213)
  at org.ruboto.ScriptLoader$1.run(ScriptLoader.java:82)
  at java.lang.Thread.run(Thread.java:1019)
Caused by: org.jruby.exceptions.RaiseException: (SystemStackError) stack level too deep
  at org.jruby.RubyArray.map(org/jruby/RubyArray.java:2361)
  at RUBY.java_import(file:/data/app/org.ruboto.core-1.apk!/jruby/java/core_ext/object.rb:22)
  at RUBY.JavaImports(file:/data.app/com.blastcube-1.apk!/lib/requires.rb:7)
  at RUBY.(root)(file:/data/app/com.blastcube-1.apk!/lib/requires.rb:3)

  at org.jruby.RubyKernel.require(org/jruby/RubyKernel.java:1027)
  at RUBY.(root)(jar:file:/data/app/org.ruboto.core-1.apk!/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1)
  at RUBY.(root)(jar:file:/data/app/org.ruboto.core-1.apk!/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36)
  at org.jruby.RubyKernel.require(org/jruby/RubyKernel.java:1027)
  at RUBY.(root)(jar:/data/app/com.blastcube-1.apk!/lib/main-window.rb:1)
  at RUBY.(root)(jar:file:/data/app/org.ruboto.core-1.apk!/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1)
  at org.jruby.RubyKernel.require(org/jruby/RubyKernel.java:1027)
  at RUBY.(root)(jar:file:/data/app/org.ruboto.core-1.apk!/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36)
  at RUBY.(root)(file:/data/app/com.blastcube-1.apk!/gosu.rb:1)

Notice the last section (which I spaced out). You have RubyKernal:1027 > custom_require.rb:1 > custom_require.rb:36 > RubyKernal:1027 > main-window:1 > custom_require:1 > custom_require:36 > ...

This might be a core gosu bug. It seems like requiring gems with a lot of dependencies eventually errors out because the stack is too small. I'll open an issue on the gosu repository and we'll see how it goes.

ashes999 commented 11 years ago

This was fixed with the underlying Ruboto fix (require gosu in a large stack thread).