Beispiel #1
0
        static bool IsScriptable(Symbol s)
        {
            if (s.argList.Contains("["))
                return false;
            if (IsBadType(s.type))
                return false;
            foreach (Parameter p in s.parameters)
                if (IsBadType(p.type) || IsBadType(p.BasicType()))
                    return false;

            foreach (string str in s.Comments())
                if (str.Contains("[noscript]"))
                    return false;
            if (s.returnComment != null && s.returnComment.Contains("[noscript]"))
                return false;
            return true;
        }
Beispiel #2
0
/*
        static void GenerateScriptClass(Symbol Class, TextWriter tw)
        {
            tw.WriteLine("class " + Class.name + "_scriptclass : public QScriptClass");
            tw.WriteLine("{");
            tw.WriteLine("public:");
            tw.WriteLine(Indent(1) + "QScriptValue objectPrototype;");
            tw.WriteLine(Indent(1) + Class.name + "_scriptclass(QScriptEngine *engine):QScriptClass(engine){}");
            tw.WriteLine(Indent(1) + "QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id)");
            tw.WriteLine(Indent(1) + "{");
            tw.WriteLine(Indent(2) + Class.name + " *This = TypeFromQScriptValue<" + Class.name + "*>(object);");
            tw.WriteLine(Indent(2) + "if (!This) { printf(\"Error! Cannot convert QScriptValue to type " + Class.name + " in file %s, line %d!\\nTry using " + Class.name + ".get%s() and " + Class.name + ".set%s() to query the member variable '%s'!\\n\", __FILE__, __LINE__, Capitalize((QString)name).c_str(), Capitalize((QString)name).c_str(), ((QString)name).toStdString().c_str()); return QScriptValue(); }");
            tw.WriteLine(Indent(2) + "QString name_ = (QString)name;");
            foreach (Symbol v in Class.children)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public)
                {
//                    tw.Write(Indent(2) + "if ((QString)name == (QString)\"" + v.name + "\")");
// Experimental: Access members directly using 'foo.x_' and 'foo.x_ptr'.
                    if (v.isStatic)
                    {
                        //tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                        //tw.WriteLine(" return TypeToQScriptValue(engine(), This->" + v.name + ");");
                    }
                    else
                    {
                        tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\")");
                        tw.WriteLine(" return TypeToQScriptValue(engine(), This->" + v.name + ");");
                        if (!Symbol.IsPODType(v.type))
                        {
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_ptr\")");
                            tw.WriteLine(" return TypeToQScriptValue(engine(), &This->" + v.name + ");");
                        }
                    }
                }

            tw.WriteLine(Indent(2) + "return QScriptValue();");
            tw.WriteLine(Indent(1) + "}");

            tw.WriteLine(Indent(1) + "void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value)");
            tw.WriteLine(Indent(1) + "{");
            tw.WriteLine(Indent(2) + Class.name + " *This = TypeFromQScriptValue<" + Class.name + "*>(object);");
            tw.WriteLine(Indent(2) + "if (!This) { printf(\"Error! Cannot convert QScriptValue to type " + Class.name + " in file %s, line %d!\\nTry using " + Class.name + ".get%s() and " + Class.name + ".set%s() to query the member variable '%s'!\\n\", __FILE__, __LINE__, Capitalize((QString)name).c_str(), Capitalize((QString)name).c_str(), ((QString)name).toStdString().c_str()); return; }");
            tw.WriteLine(Indent(2) + "QString name_ = (QString)name;");

            foreach (Symbol v in Class.children)
                if (v.kind == "variable" && IsScriptable(v) && !v.IsConst() && v.visibilityLevel == VisibilityLevel.Public)
                {
//                    tw.Write(Indent(2) + "if (name_ == (QString)\"" + v.name + "\")");
//                    tw.WriteLine(" This->" + v.name + " = TypeFromQScriptValue<" + v.type + ">(value);");
                    // Experimental: Access members directly using 'foo.x_' and 'foo.x_ptr'.
                    if (v.isStatic)
                    {
                        //tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                       // tw.WriteLine(" This->" + v.name + " = TypeFromQScriptValue<" + v.type + ">(value);");
                    }
                    else
                    {
                        tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\")");
                        tw.WriteLine(" This->" + v.name + " = TypeFromQScriptValue<" + v.type + ">(value);");
                        if (!Symbol.IsPODType(v.type))
                        {
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_ptr\")");
                            tw.WriteLine(" This->" + v.name + " = *TypeFromQScriptValue<" + v.type + "*>(value);");
                        }
                    }
                }
            tw.WriteLine(Indent(1) + "}");

            tw.WriteLine(Indent(1) + "QueryFlags queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id)");
            tw.WriteLine(Indent(1) + "{");
            tw.WriteLine(Indent(2) + "QString name_ = (QString)name;");
            foreach (Symbol v in Class.children)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public)
                {
                    if (v.isStatic)
                    {
                        //tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                    }
                    else
                    {
                        //                    tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                        if (Symbol.IsPODType(v.type))
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\")");
                        else
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\" || name_ == \"" + v.name + "_ptr\")");
                        tw.WriteLine(" return flags;");
                    }
//                    tw.WriteLine(" return flags;");
                }
            tw.WriteLine(Indent(2) + "return 0;");
            tw.WriteLine(Indent(1) + "}");

            tw.WriteLine(Indent(1) + "QScriptValue prototype() const { return objectPrototype; }");
            tw.WriteLine("};");
        }
        */
        static void GenerateClassFunction(Symbol function, TextWriter tw)
        {
            Symbol Class = function.parent;

            tw.WriteLine("static QScriptValue " + GetScriptFunctionName(function) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");
            int argIdx = 0;

            bool isClassCtor = (function.name == Class.name);

            if (function.name != "toString") // Qt oddities: It seems sometimes the hardcoded toString is called with this as the first argument and not as 'this'.
                tw.WriteLine(Indent(1) + "if (context->argumentCount() != " + function.parameters.Count + ") { printf(\"Error! Invalid number of arguments passed to function " + GetScriptFunctionName(function) + " in file %s, line %d!\\nExpected " + function.parameters.Count + ", but got %d!\\n\", __FILE__, __LINE__, context->argumentCount()); PrintCallStack(context->backtrace()); return QScriptValue(); }");

            // Test that we have a valid this.
            if (!function.isStatic && !isClassCtor)
            {
//                tw.WriteLine(Indent(1) + Class.name + " *This = " + "TypeFromQScriptValue<" + Class.name + "*>(context->thisObject());");
//                tw.WriteLine(Indent(1) + Class.name + " *This = " + "qscriptvalue_cast<" + Class.name + "*>(context->thisObject());");
                if (function.name == "toString") // Qt oddities: It seems sometimes the hardcoded toString is called with this as the first argument and not as 'this'.
                {
                    tw.WriteLine(Indent(1) + Class.name + " This;");
                    tw.WriteLine(Indent(1) + "if (context->argumentCount() > 0) This = qscriptvalue_cast<" + Class.name + ">(context->argument(0)); // Qt oddity (bug?): Sometimes the built-in toString() function doesn't give us this from thisObject, but as the first argument.");
                    tw.WriteLine(Indent(1) + "else This = qscriptvalue_cast<" + Class.name + ">(context->thisObject());");

                }
                else
                    tw.WriteLine(Indent(1) + Class.name + " This = " + "qscriptvalue_cast<" + Class.name + ">(context->thisObject());");
                //                tw.WriteLine(Indent(1) + "if (!This && context->argumentCount() > 0) This = TypeFromQScriptValue<" + Class.name + "*>(context->argument(0)); // Qt oddity (bug?): Sometimes the built-in toString() function doesn't give us this from thisObject, but as the first argument.");
//                tw.WriteLine(Indent(1) + "if (!This) { printf(\"Error! Invalid context->thisObject in function " + GetScriptFunctionName(function) + " in file %s, line %d\\n!\", __FILE__, __LINE__); return QScriptValue(); }");
            }

            // Unmarshall all parameters to the function.
            foreach (Parameter p in function.parameters)
                tw.WriteLine(Indent(1) + p.BasicType() + " " + p.name + " = qscriptvalue_cast<" + p.BasicType() + ">(context->argument(" + (argIdx++) + "));");
//            tw.WriteLine(Indent(1) + p.BasicType() + " " + p.name + " = TypeFromQScriptValue<" + p.BasicType() + ">(context->argument(" + (argIdx++) + "));");

            if (isClassCtor) // Is this function a ctor of this class.
            {
                if (function.parameters.Count == 0)
                {
                    bool needInitMemory = false;
                    string initSymbol = "";

                    // Check if default constructor does not initialize the member variables
                    foreach (string str in function.Comments())
                        if (str.Contains("default constructor does not initialize") || str.Contains("default ctor does not initialize") || str.Contains("with uninitialized member values"))
                        {
                            needInitMemory = true;
                            break;
                        }

                    foreach (string str in function.notes)
                        if (str.Contains("default constructor does not initialize") || str.Contains("default ctor does not initialize") || str.Contains("with uninitialized member values"))
                        {
                            needInitMemory = true;
                            break;
                        }


                    if (needInitMemory)
                    {
                        // Prefer "identity" initializer if exists (Quat & matrices), otherwise "zero"
                        foreach (Symbol child in Class.children)
                        {
                            if (child.name == "identity" && child.isStatic)
                            {
                                initSymbol = child.name;
                                break;
                            }
                        }
                        if (initSymbol.Length == 0)
                        {
                            foreach (Symbol child in Class.children)
                            {
                                if (child.name == "zero" && child.isStatic)
                                {
                                    initSymbol = child.name;
                                    break;
                                }
                            }
                        }
                    }

                    if (initSymbol.Length > 0)
                        tw.WriteLine(Indent(1) + Class.name + " ret(" + Class.name + "::" + initSymbol + ");");
                    else
                    {
                        tw.WriteLine(Indent(1) + Class.name + " ret;"); // Create a new instance of this class, no parameters.
                        if (needInitMemory)
                            tw.WriteLine(Indent(1) + "memset(&ret, 0, sizeof ret);");
                    }
                }
                else
                    tw.Write(Indent(1) + Class.name + " ret("); // Create a new instance of this class, one or more parameters.
            }
            else
            {
                string instanceName = (function.isStatic ? (Class.name + "::") : "This.");
//                string instanceName = (function.isStatic ? (Class.name + "::") : "This->");
                if (function.type != "void")
                    tw.Write(Indent(1) + function.type + " ret = " + instanceName + function.name + "("); // Make the function call.
                else
                    tw.Write(Indent(1) + instanceName + function.name + "("); // Make the function call.
            }

            for (int i = 0; i < function.parameters.Count; ++i)
                tw.Write(function.parameters[i].name + (i + 1 < function.parameters.Count ? ", " : ""));
            if (!isClassCtor || function.parameters.Count > 0)
                tw.WriteLine(");");

            // If the function is non-const, regenerate the proper QScriptValue as the result.
            if (!function.IsConst() && !function.isStatic && function.name != Class.name)
                tw.WriteLine(Indent(1) + "ToExistingScriptValue_" + Class.name + "(engine, This, context->thisObject());");

            // Return the return value as QScriptValue.
            if (!isClassCtor)
            {
                if (function.type != "void")
//                    tw.WriteLine(Indent(1) + "return TypeToQScriptValue(engine, ret);");
                    tw.WriteLine(Indent(1) + "return qScriptValueFromValue(engine, ret);");
                else
                    tw.WriteLine(Indent(1) + "return QScriptValue();");
            }
            else
            {
//                tw.WriteLine(Indent(1) + "return TypeToQScriptValue(engine, ret);");
                tw.WriteLine(Indent(1) + "return qScriptValueFromValue(engine, ret);");
            }

            tw.WriteLine("}");
            tw.WriteLine("");
        }