2012-01-07 26 views
26

Tôi có một dự án Qt sử dụng mô-đun QtScript để làm cho một số thành phần của ứng dụng của tôi có thể chạy được. Sau một vài lần thử làm cho các lớp hiện có có thể sử dụng trực tiếp trong QtScript, tôi đã chọn các lớp bao bọc thừa kế QObject và QScriptable (chủ yếu là vì tôi có một số lớp không có qobject được thừa kế bởi những lớp khác hoặc kế thừa QObject hoặc không và do đó tôi không thể đối xử với tất cả các lớp của mình một cách thống nhất).Ví dụ QtScript với lớp tùy chỉnh ném lỗi liên quan đến mẫu thử nghiệm

Tôi hiện đang cố gắng sử dụng kế thừa dựa trên nguyên mẫu.

Tôi phải tham gia các lớp học DrawableMeshDrawable có trình bao bọc tương ứng Wrapper_DrawableWrapper_MeshDrawable. MeshDrawable kế thừa DrawableWrapper_MeshDrawable kế thừa Wrapper_Drawable.

tôi làm cho cả lớp biết đến động cơ kịch bản (m_scriptEngine):

Wrapper_Drawable* wrapper_drawable = new Wrapper_Drawable(); 
QScriptValue wrapper_drawable_obj = m_scriptEngine->newQObject(wrapper_drawable); 
m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_Drawable*>(), 
            wrapper_drawable_obj); 

Wrapper_MeshDrawable* wrapper_meshDrawable = new Wrapper_MeshDrawable(); 
QScriptValue wrapper_meshDrawable_obj = m_scriptEngine->newQObject(wrapper_meshDrawable); 
m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_MeshDrawable*>(), 
            wrapper_meshDrawable_obj); 

Nếu tôi không nhầm, doc nói rằng động cơ kịch bản sẽ áp dụng nguyên mẫu của Wrapper_Drawable đến đối tượng thuộc loại Wrapper_MeshDrawable như họ có một mối quan hệ thừa kế trong C++.

Tôi có phương thức Wrapper_Drawable::drawables() trả về tất cả các con của số Wrapper_Drawable (thực ra là con của Drawable được bọc trong Wrapper_Drawable). Vì Drawable là một lớp trừu tượng, tất cả trẻ em thực sự là MeshDrawable s.

Như tôi muốn người dùng "tin" rằng ông sử dụng Drawable s và không Wrapper_Drawable s, tôi đã tuyên bố:

m_scriptEngine->globalObject().setProperty("Drawable", wrapper_drawable_obj); 

nơi wrapper_drawable_obj được khai báo bên trên.


tôi muốn kiểm tra xem động cơ nhận Wrapper_MeshDrawable s ngay cả khi chúng được khai báo trong một mảng của Wrapper_Drawable s.

curChildren = myDrawable.drawables()[0]; 
print(curChildren instanceof Drawable); 

Đáng buồn thay, instanceof ném lỗi này:

TypeError: instanceof called on an object with an invalid prototype property. 

nếu tôi cố gắng làm curChildren instanceof Number nó trả về false vì vậy tôi đoán các vấn đề có liên quan đến Wrapper_Drawable nhưng tôi không thể tìm ra những gì nó chính xác là.

Cảm ơn bạn trước sự giúp đỡ của bạn.

EDIT> Tôi đã thêm mã ScriptManager (xử lý công cụ tập lệnh và khai báo nhiều loại), Wrapper_Drawable (chỉ một số phương thức, nếu không tôi không thể đăng thông báo này) và Wrapper_MeshDrawable.

Tôi cũng đã kiểm tra lại rằng instanceof trên đối tượng Wrapper_Drawable, trả về false bằng Số, đúng với đối tượng và ném lỗi được đề cập ở trên với Drawable (có nghĩa là, không giống như tên cho biết, đối tượng Wrapper_Drawable).

Vì vậy, có lớp Wrapper_Drawable mã:

#ifndef WRAPPER_DRAWABLE_H 
#define WRAPPER_DRAWABLE_H 

#include <QObject> 
#include <QScriptable> 

#include "../drawable.h" 

class Wrapper_Drawable : public QObject, public QScriptable 
{ 
    Q_OBJECT 
public: 
    explicit Wrapper_Drawable(Drawable* drawable = 0, QObject *parent = 0); 

    virtual Drawable* drawable() const; 
signals: 

public slots: 
    QScriptValue visible() const; 

    virtual QScriptValue loadData(); 

    QScriptValue rotate(); 
    QScriptValue translate(); 
    QScriptValue scale(); 

    QScriptValue modelMatrix() const; 
    QScriptValue completeModelMatrix() const; 

    QScriptValue name() const; 
    QScriptValue setName(); 

    QScriptValue shaderProgramName() const; 
    QScriptValue setShaderProgramName(); 

    QScriptValue row() const; 

     QScriptValue childCount() const; 

    QScriptValue child() const; 
    QScriptValue appendChild(); 
    QScriptValue insertChildren(); 
    QScriptValue insertChild(); 
    QScriptValue removeChildren(); 

    QScriptValue children() const; 
    QScriptValue visibleChildren() const; 

    QScriptValue parent() const; 
    QScriptValue setParent(); 

protected: 
    Drawable* m_drawable; 
}; 

Q_DECLARE_METATYPE(QList<Wrapper_Drawable*>) 
Q_DECLARE_METATYPE(Wrapper_Drawable*) 

#endif // WRAPPER_DRAWABLE_H 

CPP:

#include "wrapper_drawable.h" 

Wrapper_Drawable::Wrapper_Drawable(Drawable *drawable, QObject *parent) : 
    QObject(parent), m_drawable(drawable) 
{ 
} 

Drawable* Wrapper_Drawable::drawable() const { 
    return m_drawable; 
} 

QScriptValue Wrapper_Drawable::removeChildren() { 
    Wrapper_Drawable* wrapper_drawable = qscriptvalue_cast<Wrapper_Drawable*>(context()->thisObject()); 

    if(!wrapper_drawable) 
     return context()->throwError(QScriptContext::TypeError, "Drawable.insertChildren: this object is not a Drawable"); 

    Drawable* drawable = wrapper_drawable->drawable(); 

    if(!drawable) 
     return context()->throwError(QScriptContext::TypeError, "Drawable.insertChildren: no Drawable wrapped"); 

    if(argumentCount() != 1) 
     return context()->throwError(QScriptContext::SyntaxError, "Drawable.insertChildren takes exactly 1 argument"); 

    // TODO: maybe allow multiple arguments 

    if(!argument(0).isNumber()) 
     return context()->throwError(QScriptContext::TypeError, "Drawable.insertChildren: argument 0 should be a number"); 

    unsigned int position = argument(0).toNumber(); 

    if(!argument(1).isNumber()) 
     return context()->throwError(QScriptContext::TypeError, "Drawable.insertChildren: argument 1 should be a number"); 

    unsigned int count = argument(1).toNumber(); 

    return engine()->toScriptValue(drawable->removeChildren(position, count)); 
} 

QScriptValue Wrapper_Drawable::visibleChildren() const { 
    Wrapper_Drawable* wrapper_drawable = qscriptvalue_cast<Wrapper_Drawable*>(context()->thisObject()); 

    if(!wrapper_drawable) 
     return context()->throwError(QScriptContext::TypeError, "Drawable.children: this object is not a Drawable"); 

    Drawable* drawable = wrapper_drawable->drawable(); 

    if(!drawable) 
     return context()->throwError(QScriptContext::TypeError, "Drawable.children: no Drawable wrapped"); 

    if(argumentCount() > 0) 
     return context()->throwError(QScriptContext::SyntaxError, "Drawable.children does not take any argument"); 

    QList<Drawable*> drawables = drawable->visibleChildren(); 
    QList<Wrapper_Drawable*> wrapper_drawables; 
    for(QList<Drawable*>::const_iterator it = drawables.constBegin(), end = drawables.constEnd(); 
     it != end; ++it) 
    { 
     wrapper_drawables.append(new Wrapper_Drawable(*it)); 
    } 

    return engine()->toScriptValue(wrapper_drawables); 
} 

MeshDrawable:

#ifndef WRAPPER_MESHDRAWABLE_H 
#define WRAPPER_MESHDRAWABLE_H 

#include "wrapper_drawable.h" 

#include "../meshdrawable.h" 

class Wrapper_MeshDrawable : public Wrapper_Drawable 
{ 
    Q_OBJECT 
public: 
    Wrapper_MeshDrawable(MeshDrawable* meshDrawable = 0, QObject *parent = 0); 

    virtual MeshDrawable* drawable() const; 

public slots: 
    QScriptValue addTri(); 
    QScriptValue addQuad(); 
    QScriptValue setSmoothing(); 
}; 

Q_DECLARE_METATYPE(Wrapper_MeshDrawable*) 

#endif // WRAPPER_MESHDRAWABLE_H 

CPP:

#include "wrapper_meshdrawable.h" 

Wrapper_MeshDrawable::Wrapper_MeshDrawable(MeshDrawable *meshDrawable, QObject *parent) : 
    Wrapper_Drawable(meshDrawable, parent) 
{ 
} 

MeshDrawable* Wrapper_MeshDrawable::drawable() const { 
    return static_cast<MeshDrawable*>(Wrapper_Drawable::drawable()); 
} 

QScriptValue Wrapper_MeshDrawable::addTri() { 

} 

QScriptValue Wrapper_MeshDrawable::addQuad() { 

} 

QScriptValue Wrapper_MeshDrawable::setSmoothing() { 

} 

Và cuối cùng ScriptManager (nơi tôi tuyên bố các loại khác nhau để động cơ script):

#ifndef SCRIPTMANAGER_H 
#define SCRIPTMANAGER_H 

#include <QtScript/QScriptEngine> 
#include <QtScriptTools/QScriptEngineDebugger> 
#include <QtScriptTools/QtScriptTools> 
#include <QStringList> 
#include <QObject> 

#include "utility.h" 

class ScriptManager : public QObject { 
    Q_OBJECT 
public: 
    ScriptManager(); 

public slots: 
    QString interprete(QString command); 

private: 
    void initializeFunctions(); 

    QScriptEngine* m_scriptEngine; 

    QScriptEngineDebugger* m_scriptEngineDebugger; 
}; 

#endif // SCRIPTMANAGER_H 

CPP

#include "scriptmanager.h" 
#include "scenegraph.h" 

#include "meshdrawable.h" 
#include "objdrawable.h" 

#include <QScriptValueIterator> 

#include "wrappers/wrapper_camera.h" 
#include "wrappers/wrapper_cameramanager.h" 
#include "wrappers/wrapper_drawable.h" 
#include "wrappers/wrapper_meshdrawable.h" 
#include "wrappers/wrapper_drawablemanager.h" 
#include "wrappers/wrapper_scenegraph.h" 
#include "wrappers/wrapper_shadermanager.h" 

QString ScriptManager::returnString = QString(); 

ScriptManager::ScriptManager() : m_scriptEngine(new QScriptEngine()) 
{ 
    initializeFunctions(); 
} 

void ScriptManager::initializeFunctions() { 
    qScriptRegisterQObjectMetaType<QGLShaderProgram*>(m_scriptEngine); 

    qScriptRegisterSequenceMetaType<QList<Wrapper_Drawable*> >(m_scriptEngine); 

    QScriptValue function_ls = m_scriptEngine->newFunction(scriptFunction_ls); 
    m_scriptEngine->globalObject().setProperty("ls", function_ls); 

    QScriptValue function_print = m_scriptEngine->newFunction(scriptFunction_print); 
    m_scriptEngine->globalObject().setProperty("print", function_print); 

// m_scriptEngine->setDefaultPrototype(qMetaTypeId<Observer*>(), 
//          Observer::getDefaultPrototype(m_scriptEngine)); 

    Wrapper_Drawable* wrapper_drawable = new Wrapper_Drawable(); 
    QScriptValue wrapper_drawable_obj = m_scriptEngine->newQObject(wrapper_drawable); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_Drawable*>(), 
             wrapper_drawable_obj); 
    m_scriptEngine->globalObject().setProperty("Drawable", wrapper_drawable_obj); 

    Wrapper_MeshDrawable* wrapper_meshDrawable = new Wrapper_MeshDrawable(); 
    QScriptValue wrapper_meshDrawable_obj = m_scriptEngine->newQObject(wrapper_meshDrawable); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_MeshDrawable*>(), 
             wrapper_meshDrawable_obj); 
    m_scriptEngine->globalObject().setProperty("MeshDrawable", wrapper_meshDrawable_obj); 

    Wrapper_Camera* wrapper_camera = new Wrapper_Camera(); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_Camera*>(), 
             m_scriptEngine->newQObject(wrapper_camera)); 

    Wrapper_CameraManager* wrapper_cameraManager = new Wrapper_CameraManager(); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_CameraManager*>(), 
             m_scriptEngine->newQObject(wrapper_cameraManager)); 

    Wrapper_DrawableManager* wrapper_drawableManager = new Wrapper_DrawableManager(); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_DrawableManager*>(), 
             m_scriptEngine->newQObject(wrapper_drawableManager)); 

    Wrapper_SceneGraph* wrapper_sceneGraph = new Wrapper_SceneGraph(SceneGraph::instance()); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_SceneGraph*>(), 
             m_scriptEngine->newQObject(wrapper_sceneGraph)); 

    QScriptValue object_sceneGraph = m_scriptEngine->newQObject("sceneGraph", wrapper_sceneGraph); 
    m_scriptEngine->globalObject().setProperty("sceneGraph", object_sceneGraph); 

    Wrapper_ShaderManager* wrapper_shaderManager = new Wrapper_ShaderManager(); 
    m_scriptEngine->setDefaultPrototype(qMetaTypeId<Wrapper_ShaderManager*>(), 
             m_scriptEngine->newQObject(wrapper_shaderManager)); 

    m_scriptEngineDebugger = new QScriptEngineDebugger(); 
    m_scriptEngineDebugger->attachTo(m_scriptEngine); 
} 
+1

Bạn có thể đăng một số mã thực không? –

+0

Bắt đầu với một cá thể đơn giản của đối tượng có thể viết, xác minh toán tử 'instanceof' với đối tượng này, sau đó dần dần mô phỏng các mối quan hệ thừa kế có trong đối tượng Drawable của bạn cho đến khi lỗi xuất hiện, điều này ít nhất sẽ xác định nguồn gốc của sự cố –

+0

@VJovic , Tối nay tôi sẽ đăng thêm mã. @ Gearoid Murphy, đây chính xác là những gì tôi đã làm. Tôi đã thử nghiệm 'myDrawable instanceof Number' trả về' false', sau đó 'myDrawable instanceof Object' trả về' true' và cuối cùng 'myDrawable instanceof Drawable' mà ném lỗi. – ixM

Trả lời

Các vấn đề liên quan