覆盖Java / Gosu中的公共最终静态冻结集?

时间:2015-07-06 19:34:25

标签: java reflection set final gosu

我有一个声明为static final的集合,并且还被冻结。

//
//  RenderingEngineES2.cpp
//  Robots
//
//  Created by James Thorneycroft on 01/07/2015.
//  Copyright (c) 2015 James Thorneycroft. All rights reserved.
//

#include <stdio.h>

#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
#include "Interfaces.h"
#include "Matrix.h"
#include <iostream>

namespace ES2 {

#define STRINGIFY(A) #A
//#include "../Shaders/Simple.frag"
//#include "../Shaders/SimpleLighting.vert"
#include "../PixelLighting.vert"
#include "../Shaders/PixelLighting.frag"


    struct UniformHandles {
        GLuint Modelview;
        GLuint Projection;
        GLuint NormalMatrix;
        GLuint LightPosition;
        GLuint CameraAxis;
    };

    struct AttributeHandle {
        GLint Position;
        GLint Normal;
        GLint Ambient;
        GLint Diffuse;
        GLint Specular;
        GLint Shininess;
    };

    struct Drawable {
        GLuint VertexBuffer;
        GLuint IndexBuffer;
        int IndexCount;
    };

    class RenderingEngine : public IRenderingEngine {
    public:
        RenderingEngine();
        void Initialize(const vector<ISurface*>& surfaces);
        void Render(const vector<Visual>& visuals) const;

    private:
        GLuint BuildProgram(const char* vertexShaderSource, const char* fragmentShaderSource) const;
        GLuint BuildShader(const char* source, GLenum shaderType) const;

        vector<Drawable> m_drawables;
        GLuint m_depthRenderBuffer;
        GLuint m_colorRenderBuffer;

        UniformHandles m_uniforms;
        AttributeHandle m_attributes;
    };

    IRenderingEngine* CreateRenderingEngine() {
        return new RenderingEngine();
    }


    GLuint RenderingEngine::BuildShader(const char* source, GLenum shaderType) const
    {
        GLuint shaderHandle = glCreateShader(shaderType);
        glShaderSource(shaderHandle, 1, &source, 0);
        glCompileShader(shaderHandle);

        GLint compileSuccess;
        glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);

        if (compileSuccess == GL_FALSE) {
            GLchar messages[256];
            glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
            std::cout << messages;
            exit(1);
        }

        return shaderHandle;
    }

    GLuint RenderingEngine::BuildProgram(const char* vertexShaderSource,
                                         const char* fragmentShaderSource) const
    {
        GLuint vertexShader = BuildShader(vertexShaderSource, GL_VERTEX_SHADER);
        GLuint fragmentShader = BuildShader(fragmentShaderSource, GL_FRAGMENT_SHADER);

        GLuint programHandle = glCreateProgram();
        glAttachShader(programHandle, vertexShader);
        glAttachShader(programHandle, fragmentShader);
        glLinkProgram(programHandle);

        GLint linkSuccess;
        glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
        if (linkSuccess == GL_FALSE) {
            GLchar messages[256];
            glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
            std::cout << messages;
            exit(1);
        }

        return programHandle;
    }

    RenderingEngine::RenderingEngine() {
        glGenRenderbuffers(1, &m_colorRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderBuffer);
    }

    void RenderingEngine::Initialize(const vector<ISurface *> &surfaces) {
        m_cameraPosition = vec4(0,0,0,0);
        vector<ISurface*>::const_iterator surface;
        for (surface = surfaces.begin(); surface != surfaces.end(); ++surface) {
            vector<float> vertices;
            (*surface)->GenerateVertices(vertices, VertexFlagNormals);
            GLuint vertexBuffer;
            glGenBuffers(1, &vertexBuffer);
            glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
            glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);

            int indexCount = (*surface)->GetTriangleIndexCount();
            GLuint indexBuffer;
            if (!m_drawables.empty() && indexCount == m_drawables[0].IndexCount) {
                indexBuffer = m_drawables[0].IndexBuffer;
            } else {
                vector<GLushort> indices(indexCount);
                (*surface)->GenerateTriangleIndices(indices);
                glGenBuffers(1, &indexBuffer);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(GLushort), &indices[0], GL_STATIC_DRAW);
            }

            Drawable drawable = { vertexBuffer, indexBuffer, indexCount };
            m_drawables.push_back(drawable);
        }

        int height, width;
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);

        glGenRenderbuffers(1, &m_depthRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderBuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);

        GLuint framebuffer;
        glGenFramebuffers(1, &framebuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderBuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderBuffer);

        GLuint program = BuildProgram(PixelLightingVertexShader, PixelLightingFragmentShader);
        glUseProgram(program);

        m_attributes.Position = glGetAttribLocation(program, "Position");
        m_attributes.Normal = glGetAttribLocation(program, "Normal");
        m_attributes.Ambient = glGetUniformLocation(program, "AmbientMaterial");
        m_attributes.Diffuse = glGetAttribLocation(program, "DiffuseMaterial");
        m_attributes.Specular = glGetUniformLocation(program, "SpecularMaterial");
        m_attributes.Shininess = glGetUniformLocation(program, "Shininess");
        m_uniforms.Projection = glGetUniformLocation(program, "Projection");
        m_uniforms.Modelview = glGetUniformLocation(program, "Modelview");
        m_uniforms.NormalMatrix = glGetUniformLocation(program, "NormalMatrix");
        m_uniforms.LightPosition = glGetUniformLocation(program, "LightPosition");
        m_uniforms.CameraAxis = glGetUniformLocation(program, "CameraAxis");

        glUniform3f(m_attributes.Ambient, 0.15f, 0.15f, 0.15f);
        glUniform3f(m_attributes.Specular, 0.15f, 0.15f, 0.15f);
        glUniform1f(m_attributes.Shininess, 100.0f);

        glEnableVertexAttribArray(m_attributes.Position);
        glEnableVertexAttribArray(m_attributes.Normal);
        glEnable(GL_DEPTH_TEST);

        //m_cameraOrientation.Identity();

    }

    void RenderingEngine::Render(const vector<Visual> &visuals) const {
        glClearColor(0, 0.3f, 0.6f, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        vector<Visual>::const_iterator visual = visuals.begin();
        for (int visualIndex = 0; visual != visuals.end(); ++visual, ++visualIndex) {
            ivec2 size = visual->ViewportSize;
            ivec2 lowerLeft = visual->LowerLeft;
            glViewport(lowerLeft.x, lowerLeft.y, size.x, size.y);

            mat4 rotation = visual->Orientation.ToMatrix4();
            mat4 modelView = m_cameraOrientation.ToMatrix4() * mat4::Translate(vec3(m_cameraPosition.x,m_cameraPosition.y,m_cameraPosition.z-100)) * rotation * Quaternion::CreateFromAxisAngle(vec3(-1,0,0), 1.2f).ToMatrix4();
            glUniformMatrix4fv(m_uniforms.Modelview, 1, 0, modelView.Pointer());
            vec3 camAx = m_cameraOrientation.ToMatrix3() * visual->Orientation.ToMatrix3() * Quaternion::CreateFromAxisAngle(vec3(-1,0,0), 1.2f).ToMatrix3() * vec3(0,0,1);
            glUniform3f(m_uniforms.CameraAxis, camAx.x, camAx.y, camAx.z);

            vec4 lightPosition(0, 0, 1, 0);
            glUniform3fv(m_uniforms.LightPosition, 1, (modelView*lightPosition).Pointer());

            mat3 normalMatrix = modelView.ToMat3();
            glUniformMatrix3fv(m_uniforms.NormalMatrix, 1, 0, normalMatrix.Pointer());

            float h = 4.0f * size.y / size.x;
            mat4 projectionMatrix = mat4::Frustum(-2, 2, -h / 2, h / 2, 5, 1000);
            glUniformMatrix4fv(m_uniforms.Projection, 1, 0, projectionMatrix.Pointer());

            vec3 color = visual->Color * 0.75f;
            glVertexAttrib4f(m_attributes.Diffuse, color.x, color.y, color.z, 1);

            int stride = 2*sizeof(vec3);
            const GLvoid* offset = (const GLvoid*) sizeof(vec3);
            GLint position = m_attributes.Position;
            GLint normal = m_attributes.Normal;
            const Drawable& drawable = m_drawables[visualIndex];
            glBindBuffer(GL_ARRAY_BUFFER, drawable.VertexBuffer);
            glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, stride, 0);
            glVertexAttribPointer(normal, 3, GL_FLOAT, GL_FALSE, stride, offset);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawable.IndexBuffer);
            glDrawElements(GL_TRIANGLES, drawable.IndexCount, GL_UNSIGNED_SHORT, 0);
        }
    }
}

现在,因为MyParent.MY_FIELD是从多个位置调用来做一些神奇的东西,所以我希望接管它的优势并简单地覆盖集合本身。

class MyParent {
    public final static var MY_FIELDS : Set<MyParent> = {
        FIELD1, FIELD2, FIELD3, FIELD4, FIELD5
    }.freeze()
}

我也尝试使用class MyChild extends MyParent { public override static var MY_FIELDS : Set<MyChild> = { FIELD1, FIELD3, FIELD5, FIELD8, FIELD9, FIELD10 }.freeze() } 关键字,因为它是在.NET中完成的。

new

然而,到目前为止还没有解决方法。然后,我读到通过反思它是可行的。

然后,我无法访问class MyChild extends MyParent { public new static var MY_FIELDS : Set<MyChild> = { FIELD1, FIELD3, FIELD5, FIELD8, FIELD9, FIELD10 }.freeze() } 方法或getClass()类型的成员,也无法访问class

是否有任何解决方法可以让我实现这一目标,以及如何实现?

在Guidewire项目中使用Gosu 8.0。

2 个答案:

答案 0 :(得分:0)

  

然后,我无法访问getClass()方法或类成员   我的类型,不是MyParent的。

已经有一段时间了,但我记得Gosu / Guidewire 绝对支持这一点。它们与Java对应物的名称不同。

您可以在Gosu Scratchpad中尝试并使用Guidewire Studio的自动完成功能来查找必要的方法。或者只是在根类上使用反编译器来查看它们提供的功能,当然其中有一个 getClass

正如霍尔格所说,尽管使用反射方法可能也很麻烦和“hacky”。好吧,我承认我这样做了一次,使用反射在Contact Manager和Claim Center之间开发定制的Contact同步。虽然支持该解决方案的时间很长,但取得了一定的成功。

答案 1 :(得分:0)

我意识到这个问题有点老了,我正在使用gw v9,但我发现在Gosu中使用反射完全扩展(包括能够'setAccessible')的唯一方法是这样做:

var myClass = myObject.Type.getBackingClass()

有了这个,你可以继续像java一样,检索声明的构造函数/ fields /方法,静态与否,设置它们是否可访问以及所有其他你不应该做的事情。