我在scala中遇到了一些相当烦人的问题.问题是,我可以完美地编译小scala项目,但是当项目更大时,编译器会因StackOverflowException而崩溃.显然,我必须增加编译器的堆栈大小,但是,这可能是我的主要问题,我不知道如何.
我正在使用这些参数启动netbeans:
netbeans_default_options="-J-client -J-Xmx512m -J-Xss8m -J-Xms512m -J-XX:PermSize=128m -J-XX:MaxPermSize=512m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true"
Run Code Online (Sandbox Code Playgroud)
所以,据我所知,-J-Xss8m应该将线程堆栈大小增加到8 MB.但是,这似乎不会影响编译器.所以我尝试使用编译器标志直接将相同的参数传递给编译器,我可以在netbeans中设置,导致:
-deprecation -J-Xss8m
Run Code Online (Sandbox Code Playgroud)
但同样,这没有帮助,我仍然得到例外.我搜索了netbeans文档,但我找到的只是netbeans启动参数,我已经设置了.我希望有人可以给我更多关于如何处理这个问题的信息.
更多信息:所以,经过一天我终于有机会在另一台机器上尝试一切.我使用相同的设置和相同的编译器,但令我惊讶的是,我没有得到相同的结果.意思是,在他的机器上,编译器编译整个代码,没有任何异常.我的计算机与他的唯一区别在于,他有更多的RAM和CPU能力,但这不应该达成协议,因为我们都使用具有相同启动选项的netbeans.
到现在为止,我甚至试过了2.9 scala编译器的RC,它没有多大帮助.另外,我检查了我是否安装了正确的scala插件,因为在使用2.8插件和2.9编译器时可能会出现问题,反之亦然.但是,我正在使用2.9插件和2.9编译器,所以没关系.
现在,我正在建模一些小的OpenGL库,无处不在于图形编程等.因此,我正在使用类来包围特定的OpenGL函数调用,如纹理创建,着色器创建等,到目前为止,这么好.
我的问题:
所有OpenGL调用必须由拥有创建的OpenGL上下文的线程完成(至少在Windows下,每个其他线程将不执行任何操作并创建OpenGL错误).因此,为了获得OpenGL上下文,我首先创建一个窗口类的实例(只是Win API调用的另一个包装器),最后为该窗口创建一个OpenGL上下文.这对我来说听起来很合乎逻辑.(如果我的设计中已经有一个让你尖叫的瑕疵,请告诉我......)
如果我想创建一个纹理或任何其他需要OpenGL调用来创建的对象,我基本上就是这样做的(OpenGL对象的被调用构造函数,例如):
opengl_object()
{
//do necessary stuff for object initialisation
//pass object to the OpenGL thread for final contruction
//wait until object is constructed by the OpenGL thread
}
Run Code Online (Sandbox Code Playgroud)
所以,换句话说,我创建一个像任何其他对象一样的对象
opengl_object obj;
Run Code Online (Sandbox Code Playgroud)
然后,在其构造函数中,将自身置于由OpenGL上下文线程创建的OpenGL对象的队列中.然后,OpenGL上下文线程调用一个虚拟函数,该函数在所有OpenGL对象中实现,并包含必要的OpenGL调用以最终创建对象.
我真的认为,这种处理这个问题的方式会很好.但是,现在,我觉得我错了.
情况是,尽管上面的方法到目前为止工作得非常好,但是一旦类层次结构变深,我就会遇到麻烦.例如(这不完美,但它显示了我的问题):
比方说,我有一个名为sprite的类,显然代表了一个Sprite.它有自己的OpenGL线程创建函数,其中顶点和纹理坐标被加载到图形卡内存中等等.到目前为止,这没问题.让我们进一步说,我想有两种渲染精灵的方法.一个实例和另一个方式.所以,我最终会得到2个类,sprite_instanced和sprite_not_instanced.两者都是从sprite类派生的,因为它们都是sprite,它们只是以不同的方式呈现.但是,sprite_instanced和sprite_not_instanced在其create函数中需要进一步的OpenGL调用.
到目前为止我的解决方案(我觉得它非常糟糕!)
我对c ++中的对象生成如何工作以及它如何影响虚函数有一些了解.所以我决定只使用类精灵的虚拟创建函数将顶点数据等加载到图形内存中.然后,sprite_instanced的虚拟create方法将执行准备以呈现该实例的sprite.所以,如果我想写
sprite_instanced s;
Run Code Online (Sandbox Code Playgroud)
首先,调用sprite构造函数,在一些初始化之后,构造线程将对象传递给OpenGL线程.此时,传递的对象只是一个普通的精灵,所以将调用sprite :: create,OpenGL线程将创建一个普通的精灵.之后,构造线程将调用sprite_instanced的构造函数,再次进行一些初始化并将对象传递给OpenGL线程.但是这一次,它是一个sprite_instanced,因此将调用sprite_instanced :: create.
所以,如果我对上述假设是正确的,那么一切都应该完全按照我的情况发生,至少在我的情况下.我花了最后一小时阅读关于从构造函数调用虚函数以及如何构建v-table等等.我已经运行了一些测试来检查我的假设,但这可能是编译器特定的所以我不依赖它们100% .此外,它只是感觉很糟糕,像一个可怕的黑客.
另一种方案
另一种可能性是在OpenGL线程类中实现工厂方法来处理它.所以我可以在这些对象的构造函数中进行所有OpenGL调用.但是,在这种情况下,我需要很多函数(或者一种基于模板的方法),当OpenGL线程需要做的事情多于它需要时,感觉可能会丢失潜在的渲染时间......
我的问题
可以按照我上面描述的方式处理它吗?或者我应该抛弃那些东西并做其他事情?