diff --git a/GaiaXAnalyze/GXAnalyzeAndroid/src/androidTest/kotlin/com/alibaba/gaiax/analyze/GXAnalyzeTest.kt b/GaiaXAnalyze/GXAnalyzeAndroid/src/androidTest/kotlin/com/alibaba/gaiax/analyze/GXAnalyzeTest.kt index e25523859..f1d6ac1a5 100644 --- a/GaiaXAnalyze/GXAnalyzeAndroid/src/androidTest/kotlin/com/alibaba/gaiax/analyze/GXAnalyzeTest.kt +++ b/GaiaXAnalyze/GXAnalyzeAndroid/src/androidTest/kotlin/com/alibaba/gaiax/analyze/GXAnalyzeTest.kt @@ -34,11 +34,11 @@ class GXAnalyzeTest { GXAnalyze.createValueMap(JSONObject()) } else if (valuePath == "data.null") { GXAnalyze.createValueNull() - } else if (valuePath == "data.stringEmpty") { + } else if (valuePath == "data.stringEmpty") { GXAnalyze.createValueString(""); - } else if (valuePath == "data.true") { + } else if (valuePath == "data.true") { GXAnalyze.createValueBool(true); - } else if (valuePath == "data.false") { + } else if (valuePath == "data.false") { GXAnalyze.createValueBool(false); } else { GXAnalyze.createValueFloat64(8F) @@ -64,7 +64,24 @@ class GXAnalyzeTest { (value.getValue() as? JSONArray)?.let { return GXAnalyze.createValueFloat64(it.size.toFloat()) } - }else{ + } else { + return GXAnalyze.createValueFloat64(0f) + } + } else if (functionName == "size" && params.size == 3) { + val value = GXAnalyze.wrapAsGXValue(params[0]) + if (value is GXString) { + value.getString()?.let { + return GXAnalyze.createValueFloat64(it.length.toFloat()) + } + } else if (value is GXMap) { + (value.getValue() as? JSONObject)?.let { + return GXAnalyze.createValueFloat64(it.size.toFloat()) + } + } else if (value is GXArray) { + (value.getValue() as? JSONArray)?.let { + return GXAnalyze.createValueFloat64(it.size.toFloat()) + } + } else { return GXAnalyze.createValueFloat64(0f) } } @@ -77,221 +94,292 @@ class GXAnalyzeTest { } @Test - fun empty_test(){ - Assert.assertEquals("", instance.getResult("\$data.stringEmpty", testData)) - Assert.assertEquals("test", instance.getResult("\$data.stringEmpty + 'test'", testData)) - Assert.assertEquals("", instance.getResult("''", testData)) - Assert.assertEquals(null, instance.getResult("", testData)) - Assert.assertEquals(null, instance.getResult("null", testData)) - Assert.assertEquals(0f, instance.getResult("size(null)", testDataNull)) - + fun empty_test() { + repeat(100) { + Assert.assertEquals("", instance.getResult("\$data.stringEmpty", testData)) + Assert.assertEquals("test", instance.getResult("\$data.stringEmpty + 'test'", testData)) + Assert.assertEquals("", instance.getResult("''", testData)) + Assert.assertEquals(null, instance.getResult("", testData)) + Assert.assertEquals(null, instance.getResult("null", testData)) + Assert.assertEquals(0f, instance.getResult("size(null)", testDataNull)) + } } @Test - fun num_test(){ - Assert.assertEquals(10000f, instance.getResult("10000", testData)) - Assert.assertEquals(10f, instance.getResult("10.000", testData)) - Assert.assertEquals(100f, instance.getResult("100.00", testData)) - Assert.assertEquals(1000f, instance.getResult("1000.0", testData)) - Assert.assertEquals(1001f, instance.getResult("1001.0", testData)) - Assert.assertEquals(1111f, instance.getResult("1111", testData)) - Assert.assertEquals(11110f, instance.getResult("11110", testData)) - Assert.assertEquals(20000f, instance.getResult("10000+10000", testData)) + fun num_test() { + repeat(100) { + Assert.assertEquals(10000f, instance.getResult("10000", testData)) + Assert.assertEquals(10f, instance.getResult("10.000", testData)) + Assert.assertEquals(100f, instance.getResult("100.00", testData)) + Assert.assertEquals(1000f, instance.getResult("1000.0", testData)) + Assert.assertEquals(1001f, instance.getResult("1001.0", testData)) + Assert.assertEquals(1111f, instance.getResult("1111", testData)) + Assert.assertEquals(11110f, instance.getResult("11110", testData)) + Assert.assertEquals(20000f, instance.getResult("10000+10000", testData)) + Assert.assertEquals( + 26f, + instance.getResult("1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1", testData) + ) + } } @Test fun function_test() { - Assert.assertEquals(4f, instance.getResult("size('1234')", testData)) - Assert.assertEquals(0f, instance.getResult("size(\$data.map)", testData)) - Assert.assertEquals(0f, instance.getResult("size(\$data.array)", testData)) - Assert.assertEquals(2f, instance.getResult("size(\$\$)", testData)) + repeat(100) { + Assert.assertEquals(4f, instance.getResult("size('1234')", testData)) + Assert.assertEquals(0f, instance.getResult("size(\$data.map)", testData)) + Assert.assertEquals(0f, instance.getResult("size(\$data.array)", testData)) + Assert.assertEquals(2f, instance.getResult("size(\$\$)", testData)) + Assert.assertEquals(5f, instance.getResult("size('1234')+1", testData)) + Assert.assertEquals(5f, instance.getResult("size('1234','1','2')+1", testData)) + Assert.assertEquals( + 7f, + instance.getResult("size('1234','1','2')+1 + size(\$\$)", testData) + ) + Assert.assertEquals(3f, instance.getResult("size(\$\$) + 1", testData)) + Assert.assertEquals(5f, instance.getResult("size(\$\$) + 3", testData)) + Assert.assertEquals(4f, instance.getResult("size(\$\$) + size(\$\$)", testData)) + Assert.assertEquals( + 6f, + instance.getResult("size(\$\$) + size(\$\$) + size(\$\$)", testData) + ) + Assert.assertEquals( + 10f, + instance.getResult("size(\$\$) + size(\$\$) + size(\$\$) + size('1234')", testData) + ) + Assert.assertEquals( + 6f, + instance.getResult( + "size(\$\$) + size(\$\$) + size(\$\$) + size(\$data.map)", + testData + ) + ) + } } @Test fun map_or_array() { - val map = instance.getResult("\$data.map", testData) - assert(map is JSONObject) - val array = instance.getResult("\$data.array", testData) - assert(array is JSONArray) + repeat(100) { + Assert.assertEquals(10f, instance.getResult("\$data+2", testData)) + val map = instance.getResult("\$data.map", testData) + assert(map is JSONObject) + val array = instance.getResult("\$data.array", testData) + assert(array is JSONArray) + } } + // @Test fun mod_calculate() { - Assert.assertEquals(0f, instance.getResult("2%2", testData)) - Assert.assertEquals(0f, instance.getResult("3%-1", testData)) - Assert.assertEquals(1f, instance.getResult("3%2", testData)) + repeat(100) { + Assert.assertEquals(0f, instance.getResult("2%2", testData)) + Assert.assertEquals(0f, instance.getResult("3%-1", testData)) + Assert.assertEquals(1f, instance.getResult("3%2", testData)) + } } + // @Test fun add_calculate() { - Assert.assertEquals(10f, instance.getResult("1+2+3+4", testData)) - Assert.assertEquals(1f, instance.getResult("0+1", testData)) - Assert.assertEquals("abcd", instance.getResult("'ab'+'cd'", testData)) - Assert.assertEquals(10f, instance.getResult("\$data+2", testData)) - Assert.assertEquals(16f, instance.getResult("\$data+\$data", testData)) - Assert.assertEquals("1231", instance.getResult("'123' + 1", testData)) - Assert.assertEquals("1231", instance.getResult("'1' + 231", testData)) - Assert.assertEquals("1231", instance.getResult("'123' + 1.000", testData)) - Assert.assertEquals("1231.001", instance.getResult("'123' + 1.001", testData)) - Assert.assertEquals("1231.001", instance.getResult("'123' + 1.001000", testData)) - Assert.assertEquals("123.001.001", instance.getResult("'123.00' + 1.001000", testData)) - Assert.assertEquals("1230", instance.getResult("'123' + 0.000", testData)) - Assert.assertEquals("1230.001", instance.getResult("'123' + 0.001", testData)) - Assert.assertEquals("1231", instance.getResult("123.000 + '1'", testData)) - Assert.assertEquals("123.0011", instance.getResult("123.001 + '1'", testData)) - Assert.assertEquals("123.0011.0", instance.getResult("123.001 + '1.0'", testData)) + repeat(100) { + Assert.assertEquals(10f, instance.getResult("1+2+3+4", testData)) + Assert.assertEquals(1f, instance.getResult("0+1", testData)) + Assert.assertEquals("abcd", instance.getResult("'ab'+'cd'", testData)) + Assert.assertEquals(10f, instance.getResult("\$data+2", testData)) + Assert.assertEquals(16f, instance.getResult("\$data+\$data", testData)) + Assert.assertEquals("1231", instance.getResult("'123' + 1", testData)) + Assert.assertEquals("1231", instance.getResult("'1' + 231", testData)) + Assert.assertEquals("1231", instance.getResult("'123' + 1.000", testData)) + Assert.assertEquals("1231.001", instance.getResult("'123' + 1.001", testData)) + Assert.assertEquals("1231.001", instance.getResult("'123' + 1.001000", testData)) + Assert.assertEquals("123.001.001", instance.getResult("'123.00' + 1.001000", testData)) + Assert.assertEquals("1230", instance.getResult("'123' + 0.000", testData)) + Assert.assertEquals("1230.001", instance.getResult("'123' + 0.001", testData)) + Assert.assertEquals("1231", instance.getResult("123.000 + '1'", testData)) + Assert.assertEquals("123.0011", instance.getResult("123.001 + '1'", testData)) + Assert.assertEquals("123.0011.0", instance.getResult("123.001 + '1.0'", testData)) + } } @Test fun subtract_calculate() { - Assert.assertEquals(3f, instance.getResult("4-1", testData)) - Assert.assertEquals(-1f, instance.getResult("1-2", testData)) - Assert.assertEquals(-1f, instance.getResult("0-1", testData)) - Assert.assertEquals(-2f, instance.getResult("\$data-10", testData)) - Assert.assertEquals(2f, instance.getResult("10-\$data", testData)) - Assert.assertEquals(0f, instance.getResult("8-\$data", testData)) - Assert.assertEquals(-8f, instance.getResult("0-\$data", testData)) - Assert.assertEquals(0f, instance.getResult("\$data-\$data", testData)) + repeat(100) { + Assert.assertEquals(3f, instance.getResult("4-1", testData)) + Assert.assertEquals(-1f, instance.getResult("1-2", testData)) + Assert.assertEquals(-1f, instance.getResult("0-1", testData)) + Assert.assertEquals(-2f, instance.getResult("\$data-10", testData)) + Assert.assertEquals(2f, instance.getResult("10-\$data", testData)) + Assert.assertEquals(0f, instance.getResult("8-\$data", testData)) + Assert.assertEquals(-8f, instance.getResult("0-\$data", testData)) + Assert.assertEquals(0f, instance.getResult("\$data-\$data", testData)) + } } + // @Test fun multiply_calculate() { - Assert.assertEquals(0f, instance.getResult("0*2", testData)) - Assert.assertEquals(-2f, instance.getResult("-1*2", testData)) - Assert.assertEquals(-2f, instance.getResult("2*-1", testData)) - Assert.assertEquals(-1f, instance.getResult("+1*-1", testData)) - Assert.assertEquals(2f, instance.getResult("2*+1", testData)) - Assert.assertEquals(4.4f, instance.getResult("2.2*2", testData)) - Assert.assertEquals(-4.4f, instance.getResult("-2.2*2", testData)) - Assert.assertEquals(-8f, instance.getResult("\$data*-1", testData)) - Assert.assertEquals(64f, instance.getResult("\$data*\$data", testData)) - Assert.assertEquals(16f, instance.getResult("\$data*2", testData)) - Assert.assertEquals(1f, instance.getResult("1*1", testData)) - Assert.assertEquals(true, instance.getResult("(1+1)>1 ? 1>0 : 2<3", testData)) - Assert.assertEquals( - 2f, - instance.getResult("(\$data.b>(\$data.a-2)-1) ? ((\$data.b*1)/2)/2 : 1", testData) - ) - Assert.assertEquals(true, instance.getResult("\$data.size+1>1 ? true : false ", testData)) - Assert.assertEquals( - 2f, - instance.getResult("(\$data.b>(\$data.a-2)-1) ? ((\$data.b*1)/2)/2 : 1", testData) - ) - Assert.assertEquals(true, instance.getResult("5%3 == 2", testData)) - Assert.assertEquals(true, instance.getResult("0-2==-2", testData)) - Assert.assertEquals(true, instance.getResult("1/2 == 0.5", testData)) - Assert.assertEquals(null, instance.getResult("\$\$", null)) - Assert.assertEquals(null, instance.getResult("\$data.null", null)) + repeat(100) { + Assert.assertEquals(0f, instance.getResult("0*2", testData)) + Assert.assertEquals(-2f, instance.getResult("-1*2", testData)) + Assert.assertEquals(-2f, instance.getResult("2*-1", testData)) + Assert.assertEquals(-1f, instance.getResult("+1*-1", testData)) + Assert.assertEquals(2f, instance.getResult("2*+1", testData)) + Assert.assertEquals(4.4f, instance.getResult("2.2*2", testData)) + Assert.assertEquals(-4.4f, instance.getResult("-2.2*2", testData)) + Assert.assertEquals(-8f, instance.getResult("\$data*-1", testData)) + Assert.assertEquals(64f, instance.getResult("\$data*\$data", testData)) + Assert.assertEquals(16f, instance.getResult("\$data*2", testData)) + Assert.assertEquals(1f, instance.getResult("1*1", testData)) + Assert.assertEquals(true, instance.getResult("(1+1)>1 ? 1>0 : 2<3", testData)) + Assert.assertEquals( + 2f, + instance.getResult("(\$data.b>(\$data.a-2)-1) ? ((\$data.b*1)/2)/2 : 1", testData) + ) + Assert.assertEquals( + true, + instance.getResult("\$data.size+1>1 ? true : false ", testData) + ) + Assert.assertEquals( + 2f, + instance.getResult("(\$data.b>(\$data.a-2)-1) ? ((\$data.b*1)/2)/2 : 1", testData) + ) + Assert.assertEquals(true, instance.getResult("5%3 == 2", testData)) + Assert.assertEquals(true, instance.getResult("0-2==-2", testData)) + Assert.assertEquals(true, instance.getResult("1/2 == 0.5", testData)) + Assert.assertEquals(null, instance.getResult("\$\$", null)) + Assert.assertEquals(null, instance.getResult("\$data.null", null)) + } } @Test fun divide_calculate() { - Assert.assertEquals(-0.5f, instance.getResult("-1/2", testData)) - Assert.assertEquals(0.5f, instance.getResult("1/2", testData)) - Assert.assertEquals(1f, instance.getResult("1/1", testData)) - Assert.assertEquals(1f, instance.getResult("-1/-1", testData)) - Assert.assertEquals(-8f, instance.getResult("\$data/-1", testData)) - Assert.assertEquals(1f, instance.getResult("\$data/\$data", testData)) + repeat(100) { + Assert.assertEquals(-0.5f, instance.getResult("-1/2", testData)) + Assert.assertEquals(0.5f, instance.getResult("1/2", testData)) + Assert.assertEquals(1f, instance.getResult("1/1", testData)) + Assert.assertEquals(1f, instance.getResult("-1/-1", testData)) + Assert.assertEquals(-8f, instance.getResult("\$data/-1", testData)) + Assert.assertEquals(1f, instance.getResult("\$data/\$data", testData)) + } } + // @Test fun multi_calculate() { - Assert.assertEquals(8f, instance.getResult("1+1*2+3+4/2", testData)) - Assert.assertEquals(-1f, instance.getResult("(1+1-3)", testData)) - Assert.assertEquals(-2f, instance.getResult("(1+1)-2*2", testData)) - Assert.assertEquals(-4f, instance.getResult("(1-3)*2", testData)) - Assert.assertEquals(4f, instance.getResult("1+1*3", testData)) - Assert.assertEquals(4f, instance.getResult("1+2*3/2", testData)) - Assert.assertEquals(4f, instance.getResult("(1+1)*2", testData)) - Assert.assertEquals(2f, instance.getResult("(1+3)/2", testData)) + repeat(100) { + Assert.assertEquals(8f, instance.getResult("1+1*2+3+4/2", testData)) + Assert.assertEquals(-1f, instance.getResult("(1+1-3)", testData)) + Assert.assertEquals(-2f, instance.getResult("(1+1)-2*2", testData)) + Assert.assertEquals(-4f, instance.getResult("(1-3)*2", testData)) + Assert.assertEquals(4f, instance.getResult("1+1*3", testData)) + Assert.assertEquals(4f, instance.getResult("1+2*3/2", testData)) + Assert.assertEquals(4f, instance.getResult("(1+1)*2", testData)) + Assert.assertEquals(2f, instance.getResult("(1+3)/2", testData)) + } } @Test fun single_op_expression() { - Assert.assertEquals(1f, instance.getResult("+1", testData)) - Assert.assertEquals(-1f, instance.getResult("-1", testData)) - Assert.assertEquals(true, instance.getResult("!false", testData)) - Assert.assertEquals(false, instance.getResult("!true", testData)) + repeat(100) { + Assert.assertEquals(1f, instance.getResult("+1", testData)) + Assert.assertEquals(-1f, instance.getResult("-1", testData)) + Assert.assertEquals(true, instance.getResult("!false", testData)) + Assert.assertEquals(false, instance.getResult("!true", testData)) + } } @Test fun not_equal() { - Assert.assertEquals(false, instance.getResult("null != null", testData)) - Assert.assertEquals(true, instance.getResult("1 != null", testData)) - Assert.assertEquals(true, instance.getResult("'string'!='s2tring'", testData)) - Assert.assertEquals(false, instance.getResult("1 != 1.0", testData)) - Assert.assertEquals(true, instance.getResult("1!=1.1", testData)) - Assert.assertEquals(true, instance.getResult("true != 'false'", testData)) - Assert.assertEquals(false, instance.getResult("true != 'true'", testData)) + repeat(100) { + Assert.assertEquals(false, instance.getResult("null != null", testData)) + Assert.assertEquals(true, instance.getResult("1 != null", testData)) + Assert.assertEquals(true, instance.getResult("'string'!='s2tring'", testData)) + Assert.assertEquals(false, instance.getResult("1 != 1.0", testData)) + Assert.assertEquals(true, instance.getResult("1!=1.1", testData)) + Assert.assertEquals(true, instance.getResult("true != 'false'", testData)) + Assert.assertEquals(false, instance.getResult("true != 'true'", testData)) + } } @Test fun equal() { - Assert.assertEquals(false, instance.getResult("true == false", testData)) - Assert.assertEquals(true, instance.getResult("null == null", testData)) - Assert.assertEquals(true, instance.getResult("\$data == 8", testData)) - Assert.assertEquals(false, instance.getResult("1==2", testData)) - Assert.assertEquals(true, instance.getResult("1==1.0", testData)) - Assert.assertEquals(false, instance.getResult("'string'==1.0", testData)) - Assert.assertEquals(true, instance.getResult("'string'=='string'", testData)) - Assert.assertEquals(true, instance.getResult("1+1 == 2", testData)) - Assert.assertEquals(true, instance.getResult("true == 'true'", testData)) - Assert.assertEquals(false, instance.getResult("3 == 2", testData)) - Assert.assertEquals(false, instance.getResult("'string' == 2", testData)) + repeat(100) { + Assert.assertEquals(false, instance.getResult("true == false", testData)) + Assert.assertEquals(true, instance.getResult("null == null", testData)) + Assert.assertEquals(true, instance.getResult("\$data == 8", testData)) + Assert.assertEquals(false, instance.getResult("1==2", testData)) + Assert.assertEquals(true, instance.getResult("1==1.0", testData)) + Assert.assertEquals(false, instance.getResult("'string'==1.0", testData)) + Assert.assertEquals(true, instance.getResult("'string'=='string'", testData)) + Assert.assertEquals(true, instance.getResult("1+1 == 2", testData)) + Assert.assertEquals(true, instance.getResult("true == 'true'", testData)) + Assert.assertEquals(false, instance.getResult("3 == 2", testData)) + Assert.assertEquals(false, instance.getResult("'string' == 2", testData)) + } } @Test fun greater_than() { - Assert.assertEquals(true, instance.getResult("3 > 2", testData)) - Assert.assertEquals(false, instance.getResult("'string' > 2", testData)) - Assert.assertEquals(false, instance.getResult("1+1 > 2", testData)) - Assert.assertEquals(true, instance.getResult("1+1 >= 2", testData)) - Assert.assertEquals(false, instance.getResult("'string' >= 2", testData)) + repeat(100) { + Assert.assertEquals(true, instance.getResult("3 > 2", testData)) + Assert.assertEquals(false, instance.getResult("'string' > 2", testData)) + Assert.assertEquals(false, instance.getResult("1+1 > 2", testData)) + Assert.assertEquals(true, instance.getResult("1+1 >= 2", testData)) + Assert.assertEquals(false, instance.getResult("'string' >= 2", testData)) + } } @Test fun less_than() { - Assert.assertEquals(false, instance.getResult("'string' < 2", testData)) - Assert.assertEquals(false, instance.getResult("3 < 2", testData)) - Assert.assertEquals(true, instance.getResult("2 < 3", testData)) - Assert.assertEquals(false, instance.getResult("'string' <= 2", testData)) - Assert.assertEquals(false, instance.getResult("1+1 < 2", testData)) + repeat(100) { + Assert.assertEquals(false, instance.getResult("'string' < 2", testData)) + Assert.assertEquals(false, instance.getResult("3 < 2", testData)) + Assert.assertEquals(true, instance.getResult("2 < 3", testData)) + Assert.assertEquals(false, instance.getResult("'string' <= 2", testData)) + Assert.assertEquals(false, instance.getResult("1+1 < 2", testData)) + } } @Test fun double_or() { - Assert.assertEquals(true, instance.getResult("true || true", testData)) - Assert.assertEquals(false, instance.getResult("false || false", testData)) - Assert.assertEquals(true, instance.getResult("true || false", testData)) + repeat(100) { + Assert.assertEquals(true, instance.getResult("true || true", testData)) + Assert.assertEquals(false, instance.getResult("false || false", testData)) + Assert.assertEquals(true, instance.getResult("true || false", testData)) + } } @Test fun double_and() { - Assert.assertEquals(false, instance.getResult("true && false", testData)) - Assert.assertEquals(true, instance.getResult("true && true", testData)) - Assert.assertEquals(false, instance.getResult("false && false", testData)) + repeat(100) { + Assert.assertEquals(false, instance.getResult("true && false", testData)) + Assert.assertEquals(true, instance.getResult("true && true", testData)) + Assert.assertEquals(false, instance.getResult("false && false", testData)) + } } @Test fun ternary() { - Assert.assertEquals(null, instance.getResult("false ? \$data : null", testData)) - Assert.assertEquals(0f, instance.getResult("false ? 1 : 0", testData)) - Assert.assertEquals(1f, instance.getResult("\$data ? 1 : 0", testData)) - Assert.assertEquals(1f, instance.getResult("true ? 1 : 0", testData)) - Assert.assertEquals(1f, instance.getResult("true ? 1 : 0", testData)) - Assert.assertEquals(true, instance.getResult("true ?: 1", testData)) - Assert.assertEquals(1f, instance.getResult("false ?: 1", testData)) - Assert.assertEquals(true, instance.getResult("true ?: \$data", testData)) - Assert.assertEquals("123", instance.getResult("true ? '123' : '456'", testData)) - Assert.assertEquals("123", instance.getResult("'true' ? '123' : '456'", testData)) - Assert.assertEquals(null, instance.getResult("true ? null : \$data", testData)) - Assert.assertEquals(1f, instance.getResult("false ? \$\$ : 1", testData)) - Assert.assertEquals(testData, instance.getResult("true ? \$\$ : 1", testData)) - Assert.assertEquals(testData, instance.getResult("\$\$ ?: 0", testData)) - Assert.assertEquals(1f, instance.getResult("\$data.true?1:2", testData)) - Assert.assertEquals(2f, instance.getResult("\$data.false?1:2", testData)) - Assert.assertEquals(2f, instance.getResult("($$!=null)?size($$):0", testData)) + repeat(100) { + Assert.assertEquals(null, instance.getResult("false ? \$data : null", testData)) + Assert.assertEquals(0f, instance.getResult("false ? 1 : 0", testData)) + Assert.assertEquals(1f, instance.getResult("\$data ? 1 : 0", testData)) + Assert.assertEquals(1f, instance.getResult("true ? 1 : 0", testData)) + Assert.assertEquals(1f, instance.getResult("true ? 1 : 0", testData)) + Assert.assertEquals(true, instance.getResult("true ?: 1", testData)) + Assert.assertEquals(1f, instance.getResult("false ?: 1", testData)) + Assert.assertEquals(true, instance.getResult("true ?: \$data", testData)) + Assert.assertEquals("123", instance.getResult("true ? '123' : '456'", testData)) + Assert.assertEquals("123", instance.getResult("'true' ? '123' : '456'", testData)) + Assert.assertEquals(null, instance.getResult("true ? null : \$data", testData)) + Assert.assertEquals(1f, instance.getResult("false ? \$\$ : 1", testData)) + Assert.assertEquals(testData, instance.getResult("true ? \$\$ : 1", testData)) + Assert.assertEquals(testData, instance.getResult("\$\$ ?: 0", testData)) + Assert.assertEquals(1f, instance.getResult("\$data.true?1:2", testData)) + Assert.assertEquals(2f, instance.getResult("\$data.false?1:2", testData)) +// Assert.assertEquals(2f, instance.getResult("($$!=null)?size($$):0", testData)) + } } @Test diff --git a/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.cpp b/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.cpp index 5986f35fd..d029bdbdb 100644 --- a/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.cpp +++ b/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.cpp @@ -21,5 +21,13 @@ GXATSNode &GXATSNode::operator=(const GXATSNode &node) { GXATSNode::name = node.name; GXATSNode::detail = node.detail; GXATSNode::token = node.token; + GXATSNode::count = node.count; return *this; } + +GXATSNode::GXATSNode(string name, string detail, string token, int count) { + GXATSNode::name = name; //字段 + GXATSNode::detail = detail; //code + GXATSNode::token = token; //类型 + GXATSNode::count = count; +} diff --git a/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.h b/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.h index 1f4cf2615..f0297b8ef 100644 --- a/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.h +++ b/GaiaXAnalyze/GXAnalyzeCore/GXATSNode.h @@ -9,12 +9,14 @@ class GXATSNode { public: GXATSNode(); //无参构造函数 GXATSNode(string name, string detail, string token); //有参构造函数 + GXATSNode(string name, string detail, string token,int count); //有参构造函数 ~GXATSNode(); //析构函数 GXATSNode &operator=(const GXATSNode &node); string name; //字段 string token; //类型 string detail; + int count; private: }; diff --git a/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp b/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp index 924b87e69..b9f51950b 100644 --- a/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp +++ b/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp @@ -30,6 +30,7 @@ struct CLOSURE { //闭包CLOSURE static vector cloArray; static unordered_map CtoS; //Char to String static unordered_map StoC; //String to Char +static unordered_map cache; //初始化终结符和非终结符 void init_SAndC() { @@ -383,7 +384,8 @@ void init_Terminal() { } void init() { - if (isInit == false) { + if (!isInit) { + cache.reserve(1024); isInit = true; read_G(); get_First(); @@ -748,6 +750,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -772,6 +777,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -801,6 +809,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -830,6 +841,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -897,11 +911,14 @@ long GXAnalyze::getValue(string expression, void *source) { int inputLength = expression.length(); input = new char[inputLength + 2]; vector array; + vector arrayNum; array.reserve(128); + arrayNum.reserve(128); string result = "#"; strcpy(input, expression.c_str()); int p = 0; int synCode; + int countNode = 0; while (p < strlen(input)) { if (input[p] == ' ') { p++; @@ -912,19 +929,332 @@ long GXAnalyze::getValue(string expression, void *source) { } else { result = result + Vn[token.detail]; } + GXATSNode tokenNum; + if (token.token == "value" || token.token == "data") { + long res = this->getSourceValue(token.name, source); + GXValue *gxv = (GXValue *) res; + if (gxv->tag == GX_TAG_FLOAT) { + tokenNum.name = to_string(gxv->float64); + tokenNum.token = "num"; + } else if (gxv->tag == GX_TAG_STRING) { + tokenNum.name = gxv->str; + tokenNum.token = "string"; + } else if (gxv->tag == GX_TAG_BOOL) { + if (gxv->int32 == 1) { + tokenNum.name = "true"; + } else { + tokenNum.name = "false"; + } + tokenNum.token = "bool"; + } else if (gxv->tag == GX_TAG_ARRAY) { + tokenNum.name = to_string((long) (gxv->ptr)); + tokenNum.token = "array"; + } else if (gxv->tag == GX_TAG_MAP) { + tokenNum.name = to_string((long) (gxv->ptr)); + tokenNum.token = "map"; + } else if (gxv->tag == GX_TAG_NULL) { + tokenNum.name = "null"; + tokenNum.token = "null"; + } + if (gxv->tag == GX_TAG_STRING && gxv->str != NULL) { + delete[] gxv->str; + gxv->str = NULL; + } + delete gxv; + } else { + tokenNum = token; + } + if (token.token != "op") { + token.count = countNode; + tokenNum.count = countNode; + countNode++; + arrayNum.push_back(tokenNum); + } array.push_back(token); } } //释放s的内存空间 delete[]input; result = result + "#"; - long Res = check(result, array, this, source, expression); + long Res; + if (cache.count(result) != 0) { + if (cache[result] == "(0)") { + GXATSNode res = arrayNum[0]; + GXValue *pointer; + if (res.token == "string") { + pointer = new GXValue(GX_TAG_STRING, res.name); + } else if (res.token == "bool") { + if (res.name == "true") { + pointer = new GXValue(GX_TAG_BOOL, 1); + } else { + pointer = new GXValue(GX_TAG_BOOL, 0); + } + } else if (res.token == "num") { + if (res.name.find('.') != -1) { + regex e("0+?$"); + regex e2("[.]$"); + res.name = regex_replace(res.name, e, ""); + res.name = regex_replace(res.name, e2, ""); + } + pointer = new GXValue(GX_TAG_FLOAT, (float) atof(res.name.c_str())); + } else if (res.token == "map") { + pointer = new GXValue(GX_TAG_MAP, (void *) atol(res.name.c_str())); + } else if (res.token == "array") { + pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(res.name.c_str())); + } else if (res.token == "null") { + pointer = new GXValue(GX_TAG_NULL, 1); + } + Res = (long) pointer; + } else { + Res = calculateCache(cache[result], arrayNum, this, source); + } + } else { + Res = check(result, array, this, source, expression); + } array.clear(); return Res; } +bool isNumber(char ch) { + if (ch >= '0' && ch <= '9') + return true; + else + return false; +} + +//计算缓存格式的表达式 +long +GXAnalyze::calculateCache(string cache, vector array, void *p_analyze, void *source) { + long *paramsStack; + int paramsSize = 0; + bool isFunction = false; + vector paramsTempArray; + bool hasNum2 = false; + bool isNum1 = true; + int num1 = -1; + int num2 = -1; + GXATSNode res; + string op = ""; + for (int i = 0; i < cache.length(); i++) { + if (cache[i] == '(') { + continue; + } + if (cache[i] == ')') { + if (op == "") { + res = array[num1]; + } else if (hasNum2) { + array[num2] = doubleCalculate(array[num1], array[num2], op); + res = array[num2]; + } else { + array[num1] = singleCalculate(array[num1], op); + res = array[num1]; + } + num1 = -1; + num2 = -1; + hasNum2 = false; + isNum1 = true; + op = ""; + continue; + } + if (isNumber(cache[i])) { + if (isNum1) { + if (num1 == -1) { + num1 = cache[i] - '0'; + } else { + num1 = num1 * 10 + (cache[i] - '0'); + } + } else { + hasNum2 = true; + if (num2 == -1) { + num2 = cache[i] - '0'; + } else { + num2 = num2 * 10 + (cache[i] - '0'); + } + } + } else { + if (cache[i] == ',') { + //函数参数 + if (!isFunction) { + paramsStack = new long[array.size() + 2]; + isFunction = true; + } + GXATSNode node = array[num1]; + if (node.token == "num") { + GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "string") { + GXValue *par = new GXValue(GX_TAG_STRING, + node.name.c_str()); + paramsTempArray.push_back((long) par); + } else if (node.token == "bool") { + if (node.name == "true") { + GXValue *par = new GXValue(GX_TAG_BOOL, 1); + paramsTempArray.push_back((long) par); + } else { + GXValue *par = new GXValue(GX_TAG_BOOL, 0); + paramsTempArray.push_back((long) par); + } + } else if (node.token == "map") { + GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "array") { + GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "null") { + GXValue *par = new GXValue(GX_TAG_NULL, 1); + paramsTempArray.push_back((long) par); + } + num1 = -1; + } else if (cache[i] == 'g') { + //函数名 + if (cache[i - 1] != '(') { + if (!isFunction) { + paramsStack = new long[array.size() + 2]; + isFunction = true; + } + GXATSNode node = array[num1]; + num1 = -1; + if (node.token == "num") { + GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "string") { + GXValue *par = new GXValue(GX_TAG_STRING, + node.name.c_str()); + paramsTempArray.push_back((long) par); + } else if (node.token == "bool") { + if (node.name == "true") { + GXValue *par = new GXValue(GX_TAG_BOOL, 1); + paramsTempArray.push_back((long) par); + } else { + GXValue *par = new GXValue(GX_TAG_BOOL, 0); + paramsTempArray.push_back((long) par); + } + } else if (node.token == "map") { + GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "array") { + GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "null") { + GXValue *par = new GXValue(GX_TAG_NULL, 1); + paramsTempArray.push_back((long) par); + } + } + int numFunction = -1; + for (int x = i + 1; x < cache.length(); x++) { + if (isNumber(cache[x])) { + if (numFunction == -1) { + numFunction = cache[x] - '0'; + } else { + numFunction = numFunction * 10 + (cache[x] - '0'); + } + i++; + } else { + i++; + break; + } + } + for (int paramsIndex = paramsTempArray.size() - 1; + paramsIndex >= 0; paramsIndex--) { + paramsStack[paramsSize] = paramsTempArray[paramsIndex]; + ++paramsSize; + } + paramsTempArray.clear(); + //有参数 + long funVal = this->getFunctionValue(array[numFunction].name, + paramsStack, + paramsSize, ""); + GXValue *fun = (GXValue *) funVal; + GXATSNode node = array[numFunction]; + //取出结果 + if (fun->tag == GX_TAG_FLOAT) { + node.name = to_string(fun->float64); + node.token = "num"; + } else if (fun->tag == GX_TAG_BOOL) { + if (fun->int32 == 1) { + node.name = "true"; + node.token = "bool"; + } else { + node.name = "false"; + node.token = "bool"; + } + } else if (fun->tag == GX_TAG_STRING) { + node.name = fun->str; + node.token = "string"; + } else if (fun->tag == GX_TAG_MAP) { + node.name = to_string((long) fun->ptr); + node.token = "map"; + } else if (fun->tag == GX_TAG_ARRAY) { + node.name = to_string((long) fun->ptr); + node.token = "array"; + } else if (fun->tag == GX_TAG_NULL) { + node.name = "null"; + node.token = "null"; + } + array[numFunction] = node; + res = array[numFunction]; + if (fun->tag == GX_TAG_STRING && fun->str != NULL) { + delete[] fun->str; + fun->str = NULL; + } + delete fun; + if (isFunction) { + isFunction = false; + delete[] paramsStack; + } + paramsSize = 0; + } else { + //操作符 + isNum1 = false; + op = op + cache[i]; + if (!isNumber(cache[i + 1]) && cache[i + 1] != ')') { + op = op + cache[i + 1]; + i++; + } + } + } + } + GXValue *pointer; + if (res.token == "string") { + pointer = new GXValue(GX_TAG_STRING, res.name); + } else if (res.token == "bool") { + if (res.name == "true") { + pointer = new GXValue(GX_TAG_BOOL, 1); + } else { + pointer = new GXValue(GX_TAG_BOOL, 0); + } + } else if (res.token == "num") { + if (res.name.find('.') != -1) { + regex e("0+?$"); + regex e2("[.]$"); + res.name = regex_replace(res.name, e, ""); + res.name = regex_replace(res.name, e2, ""); + } + pointer = new GXValue(GX_TAG_FLOAT, (float) atof(res.name.c_str())); + } else if (res.token == "map") { + pointer = new GXValue(GX_TAG_MAP, (void *) atol(res.name.c_str())); + } else if (res.token == "array") { + pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(res.name.c_str())); + } else if (res.token == "null") { + pointer = new GXValue(GX_TAG_NULL, 1); + } + + return (long) pointer; +} + + long GXAnalyze::check(string s, vector array, void *p_analyze, void *source, string expression) { + string tree; + if (array.size() == 1) { + tree = "(0)"; + } GXValue *pointer; GXAnalyze *analyze = (GXAnalyze *) p_analyze; string temp = "\0"; //需要分析的语句 @@ -938,6 +1268,7 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * long *paramsStack = new long[sentence.size() + 2]; int paramsSize = 0; int valueStep = 0; //数值数 + vector paramsTempArray; bool isFunction = false; string valueType; symbolStack[symbolSize] = '#'; @@ -982,6 +1313,9 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * delete[] symbolStack; delete[] valueStack; delete[] paramsStack; + if (cache.count(s) == 0) { + cache[s] = tree; + } return (long) pointer; } else if (new_status[0] == 's') { @@ -1004,6 +1338,7 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * if (temp == "value" || temp == "data") { long res = analyze->getSourceValue(array[valueStep].name, source); GXValue *gxv = (GXValue *) res; + t1.count = array[valueStep].count; if (gxv->tag == GX_TAG_FLOAT) { t1.name = to_string(gxv->float64); t1.token = "num"; @@ -1109,13 +1444,27 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * tempR2 = t2; valueSize = valueSize - 2; } else if (op == ")") { + int ParamsSize = valueSize - 1; for (int i = valueSize - 1; i >= 0; i--) { + if (i == ParamsSize) { + tree = tree + '('; + } if (valueStack[i].token == "id") { + //需要翻转一遍,否则取到的参数顺序是反过来的 + for (int paramsIndex = paramsTempArray.size() - 1; + paramsIndex >= 0; paramsIndex--) { + paramsStack[paramsSize] = paramsTempArray[paramsIndex]; + ++paramsSize; + } + paramsTempArray.clear(); + //这里特别注意,g是函数的识别符,需要和运算符做区分 + tree = tree + "g" + to_string(valueStack[i].count) + ")"; //在这里调用获取函数结果方法 long funVal = analyze->getFunctionValue(valueStack[i].name, paramsStack, paramsSize, ""); GXValue *fun = (GXValue *) funVal; + tempR.count = valueStack[i].count; //取出结果 if (fun->tag == GX_TAG_FLOAT) { tempR.name = to_string(fun->float64); @@ -1151,41 +1500,39 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * delete fun; break; } else { + if (valueStack[i - 1].token != "id") { + tree = tree + to_string(valueStack[i].count) + ","; + } else { + tree = tree + to_string(valueStack[i].count); + } //往vector逐个扔进去参数,然后通过id调用 if (valueStack[i].token == "num") { GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( valueStack[i].name.c_str())); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "string") { GXValue *par = new GXValue(GX_TAG_STRING, valueStack[i].name.c_str()); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "bool") { if (valueStack[i].name == "true") { GXValue *par = new GXValue(GX_TAG_BOOL, 1); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_BOOL, 0); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } } else if (valueStack[i].token == "map") { GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( valueStack[i].name.c_str())); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "array") { GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( valueStack[i].name.c_str())); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "null") { GXValue *par = new GXValue(GX_TAG_NULL, 1); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } --valueSize; } @@ -1201,6 +1548,9 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * } else { valueSize = valueSize - 2; tempR = doubleCalculate(t1, t2, op); + tempR.count = t2.count; + tree = tree + '(' + to_string(t1.count) + op + to_string(t2.count) + + ')'; if (tempR.token == "error") { delete[] statusStack; delete[] symbolStack; @@ -1223,6 +1573,10 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * t1 = valueStack[valueSize - 1]; --valueSize; tempR = singleCalculate(t1, op); + tempR.count = t1.count; + if (op != ")" && op != ",") { + tree = tree + '(' + to_string(t1.count) + op + ')'; + } if (tempR.token == "error") { analyze->throwError(tempR.name); return 0L; @@ -1260,3 +1614,5 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * } } } + + diff --git a/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.h b/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.h index 083b98cb9..f0870a692 100644 --- a/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.h +++ b/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.h @@ -40,8 +40,9 @@ class GXAnalyze { //获取单个数值计算的结果 GXATSNode singleCalculate(GXATSNode value1, string op); + long check(string s, vector array, void *p_analyze, void* source,string expression); - long check(string s, vector array, void *p_analyze, void *source, string expression); + long calculateCache(string cache,vector array,void *p_analyze, void* source); }; #endif /*include _GXAnalyze__H_*/ diff --git a/GaiaXAndroid/src/main/kotlin/com/alibaba/gaiax/render/view/GXViewExt.kt b/GaiaXAndroid/src/main/kotlin/com/alibaba/gaiax/render/view/GXViewExt.kt index 83078c047..eefd81d99 100644 --- a/GaiaXAndroid/src/main/kotlin/com/alibaba/gaiax/render/view/GXViewExt.kt +++ b/GaiaXAndroid/src/main/kotlin/com/alibaba/gaiax/render/view/GXViewExt.kt @@ -57,7 +57,7 @@ fun View.setRoundCornerRadiusAndRoundCornerBorder(style: GXStyle?) { // 2022/09/13 // Fix a ui bug - // Remove logic of radius increase because it will caused corner dim + // Remove logic of radius increase because it will cause corner dim // if (cornerRadius != null && cornerRadius.size == 8 && // borderRadius != null && borderWidth != null && borderColor != null // ) { diff --git a/GaiaXiOS/GaiaXiOS.podspec b/GaiaXiOS/GaiaXiOS.podspec index 957c4bf8a..2943d0531 100644 --- a/GaiaXiOS/GaiaXiOS.podspec +++ b/GaiaXiOS/GaiaXiOS.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "GaiaXiOS" - s.version = "0.2.7" + s.version = "0.2.8" s.platform = :ios, "9.0" s.summary = "dynamic template engine is a lightweight cross-end solution of pure native dynamic card" diff --git a/GaiaXiOS/GaiaXiOS.xcodeproj/project.pbxproj b/GaiaXiOS/GaiaXiOS.xcodeproj/project.pbxproj index cf44c9176..05d29bfe3 100644 --- a/GaiaXiOS/GaiaXiOS.xcodeproj/project.pbxproj +++ b/GaiaXiOS/GaiaXiOS.xcodeproj/project.pbxproj @@ -653,16 +653,16 @@ isa = PBXGroup; children = ( 8DB609F827F4764E0038BE13 /* GXAnalyzeCore */, - 8DB609F427F4764E0038BE13 /* GXAnalyzeBridge.h */, + 8DB60A0F27F4764E0038BE13 /* GXValueParser.h */, 8DB609F727F4764E0038BE13 /* GXValueParser.m */, 8DB60A0727F4764E0038BE13 /* GXObject.h */, 8DB60A0E27F4764E0038BE13 /* GXObject.m */, 8DB60A0827F4764E0038BE13 /* GXContext.h */, 8DB609F527F4764E0038BE13 /* GXContext.mm */, - 8DB60A0A27F4764E0038BE13 /* GXAnalyzeImpl.mm */, 8DB60A0B27F4764E0038BE13 /* GXAnalyzeImpl.hpp */, + 8DB60A0A27F4764E0038BE13 /* GXAnalyzeImpl.mm */, + 8DB609F427F4764E0038BE13 /* GXAnalyzeBridge.h */, 8DB60A0C27F4764E0038BE13 /* GXAnalyzeBridge.m */, - 8DB60A0F27F4764E0038BE13 /* GXValueParser.h */, 8DB60A1027F4764E0038BE13 /* GXFunction.h */, 8DB60A0927F4764E0038BE13 /* GXFunction.m */, 8DB60A0D27F4764E0038BE13 /* GXNativeAnalyze.h */, diff --git a/GaiaXiOS/GaiaXiOS.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate b/GaiaXiOS/GaiaXiOS.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate index 638101462..dd928a276 100644 Binary files a/GaiaXiOS/GaiaXiOS.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate and b/GaiaXiOS/GaiaXiOS.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.cpp b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.cpp index 5986f35fd..d029bdbdb 100644 --- a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.cpp +++ b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.cpp @@ -21,5 +21,13 @@ GXATSNode &GXATSNode::operator=(const GXATSNode &node) { GXATSNode::name = node.name; GXATSNode::detail = node.detail; GXATSNode::token = node.token; + GXATSNode::count = node.count; return *this; } + +GXATSNode::GXATSNode(string name, string detail, string token, int count) { + GXATSNode::name = name; //字段 + GXATSNode::detail = detail; //code + GXATSNode::token = token; //类型 + GXATSNode::count = count; +} diff --git a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.h b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.h index 1f4cf2615..f0297b8ef 100644 --- a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.h +++ b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXATSNode.h @@ -9,12 +9,14 @@ class GXATSNode { public: GXATSNode(); //无参构造函数 GXATSNode(string name, string detail, string token); //有参构造函数 + GXATSNode(string name, string detail, string token,int count); //有参构造函数 ~GXATSNode(); //析构函数 GXATSNode &operator=(const GXATSNode &node); string name; //字段 string token; //类型 string detail; + int count; private: }; diff --git a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.cpp b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.cpp index 924b87e69..b9f51950b 100644 --- a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.cpp +++ b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.cpp @@ -30,6 +30,7 @@ struct CLOSURE { //闭包CLOSURE static vector cloArray; static unordered_map CtoS; //Char to String static unordered_map StoC; //String to Char +static unordered_map cache; //初始化终结符和非终结符 void init_SAndC() { @@ -383,7 +384,8 @@ void init_Terminal() { } void init() { - if (isInit == false) { + if (!isInit) { + cache.reserve(1024); isInit = true; read_G(); get_First(); @@ -748,6 +750,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -772,6 +777,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -801,6 +809,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -830,6 +841,9 @@ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; + } else if (left.token == "null" || right.token == "null") { + result.name = "null"; + result.token = "null"; } else if (right.token == "num") { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + @@ -897,11 +911,14 @@ long GXAnalyze::getValue(string expression, void *source) { int inputLength = expression.length(); input = new char[inputLength + 2]; vector array; + vector arrayNum; array.reserve(128); + arrayNum.reserve(128); string result = "#"; strcpy(input, expression.c_str()); int p = 0; int synCode; + int countNode = 0; while (p < strlen(input)) { if (input[p] == ' ') { p++; @@ -912,19 +929,332 @@ long GXAnalyze::getValue(string expression, void *source) { } else { result = result + Vn[token.detail]; } + GXATSNode tokenNum; + if (token.token == "value" || token.token == "data") { + long res = this->getSourceValue(token.name, source); + GXValue *gxv = (GXValue *) res; + if (gxv->tag == GX_TAG_FLOAT) { + tokenNum.name = to_string(gxv->float64); + tokenNum.token = "num"; + } else if (gxv->tag == GX_TAG_STRING) { + tokenNum.name = gxv->str; + tokenNum.token = "string"; + } else if (gxv->tag == GX_TAG_BOOL) { + if (gxv->int32 == 1) { + tokenNum.name = "true"; + } else { + tokenNum.name = "false"; + } + tokenNum.token = "bool"; + } else if (gxv->tag == GX_TAG_ARRAY) { + tokenNum.name = to_string((long) (gxv->ptr)); + tokenNum.token = "array"; + } else if (gxv->tag == GX_TAG_MAP) { + tokenNum.name = to_string((long) (gxv->ptr)); + tokenNum.token = "map"; + } else if (gxv->tag == GX_TAG_NULL) { + tokenNum.name = "null"; + tokenNum.token = "null"; + } + if (gxv->tag == GX_TAG_STRING && gxv->str != NULL) { + delete[] gxv->str; + gxv->str = NULL; + } + delete gxv; + } else { + tokenNum = token; + } + if (token.token != "op") { + token.count = countNode; + tokenNum.count = countNode; + countNode++; + arrayNum.push_back(tokenNum); + } array.push_back(token); } } //释放s的内存空间 delete[]input; result = result + "#"; - long Res = check(result, array, this, source, expression); + long Res; + if (cache.count(result) != 0) { + if (cache[result] == "(0)") { + GXATSNode res = arrayNum[0]; + GXValue *pointer; + if (res.token == "string") { + pointer = new GXValue(GX_TAG_STRING, res.name); + } else if (res.token == "bool") { + if (res.name == "true") { + pointer = new GXValue(GX_TAG_BOOL, 1); + } else { + pointer = new GXValue(GX_TAG_BOOL, 0); + } + } else if (res.token == "num") { + if (res.name.find('.') != -1) { + regex e("0+?$"); + regex e2("[.]$"); + res.name = regex_replace(res.name, e, ""); + res.name = regex_replace(res.name, e2, ""); + } + pointer = new GXValue(GX_TAG_FLOAT, (float) atof(res.name.c_str())); + } else if (res.token == "map") { + pointer = new GXValue(GX_TAG_MAP, (void *) atol(res.name.c_str())); + } else if (res.token == "array") { + pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(res.name.c_str())); + } else if (res.token == "null") { + pointer = new GXValue(GX_TAG_NULL, 1); + } + Res = (long) pointer; + } else { + Res = calculateCache(cache[result], arrayNum, this, source); + } + } else { + Res = check(result, array, this, source, expression); + } array.clear(); return Res; } +bool isNumber(char ch) { + if (ch >= '0' && ch <= '9') + return true; + else + return false; +} + +//计算缓存格式的表达式 +long +GXAnalyze::calculateCache(string cache, vector array, void *p_analyze, void *source) { + long *paramsStack; + int paramsSize = 0; + bool isFunction = false; + vector paramsTempArray; + bool hasNum2 = false; + bool isNum1 = true; + int num1 = -1; + int num2 = -1; + GXATSNode res; + string op = ""; + for (int i = 0; i < cache.length(); i++) { + if (cache[i] == '(') { + continue; + } + if (cache[i] == ')') { + if (op == "") { + res = array[num1]; + } else if (hasNum2) { + array[num2] = doubleCalculate(array[num1], array[num2], op); + res = array[num2]; + } else { + array[num1] = singleCalculate(array[num1], op); + res = array[num1]; + } + num1 = -1; + num2 = -1; + hasNum2 = false; + isNum1 = true; + op = ""; + continue; + } + if (isNumber(cache[i])) { + if (isNum1) { + if (num1 == -1) { + num1 = cache[i] - '0'; + } else { + num1 = num1 * 10 + (cache[i] - '0'); + } + } else { + hasNum2 = true; + if (num2 == -1) { + num2 = cache[i] - '0'; + } else { + num2 = num2 * 10 + (cache[i] - '0'); + } + } + } else { + if (cache[i] == ',') { + //函数参数 + if (!isFunction) { + paramsStack = new long[array.size() + 2]; + isFunction = true; + } + GXATSNode node = array[num1]; + if (node.token == "num") { + GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "string") { + GXValue *par = new GXValue(GX_TAG_STRING, + node.name.c_str()); + paramsTempArray.push_back((long) par); + } else if (node.token == "bool") { + if (node.name == "true") { + GXValue *par = new GXValue(GX_TAG_BOOL, 1); + paramsTempArray.push_back((long) par); + } else { + GXValue *par = new GXValue(GX_TAG_BOOL, 0); + paramsTempArray.push_back((long) par); + } + } else if (node.token == "map") { + GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "array") { + GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "null") { + GXValue *par = new GXValue(GX_TAG_NULL, 1); + paramsTempArray.push_back((long) par); + } + num1 = -1; + } else if (cache[i] == 'g') { + //函数名 + if (cache[i - 1] != '(') { + if (!isFunction) { + paramsStack = new long[array.size() + 2]; + isFunction = true; + } + GXATSNode node = array[num1]; + num1 = -1; + if (node.token == "num") { + GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "string") { + GXValue *par = new GXValue(GX_TAG_STRING, + node.name.c_str()); + paramsTempArray.push_back((long) par); + } else if (node.token == "bool") { + if (node.name == "true") { + GXValue *par = new GXValue(GX_TAG_BOOL, 1); + paramsTempArray.push_back((long) par); + } else { + GXValue *par = new GXValue(GX_TAG_BOOL, 0); + paramsTempArray.push_back((long) par); + } + } else if (node.token == "map") { + GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "array") { + GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( + node.name.c_str())); + paramsTempArray.push_back((long) par); + } else if (node.token == "null") { + GXValue *par = new GXValue(GX_TAG_NULL, 1); + paramsTempArray.push_back((long) par); + } + } + int numFunction = -1; + for (int x = i + 1; x < cache.length(); x++) { + if (isNumber(cache[x])) { + if (numFunction == -1) { + numFunction = cache[x] - '0'; + } else { + numFunction = numFunction * 10 + (cache[x] - '0'); + } + i++; + } else { + i++; + break; + } + } + for (int paramsIndex = paramsTempArray.size() - 1; + paramsIndex >= 0; paramsIndex--) { + paramsStack[paramsSize] = paramsTempArray[paramsIndex]; + ++paramsSize; + } + paramsTempArray.clear(); + //有参数 + long funVal = this->getFunctionValue(array[numFunction].name, + paramsStack, + paramsSize, ""); + GXValue *fun = (GXValue *) funVal; + GXATSNode node = array[numFunction]; + //取出结果 + if (fun->tag == GX_TAG_FLOAT) { + node.name = to_string(fun->float64); + node.token = "num"; + } else if (fun->tag == GX_TAG_BOOL) { + if (fun->int32 == 1) { + node.name = "true"; + node.token = "bool"; + } else { + node.name = "false"; + node.token = "bool"; + } + } else if (fun->tag == GX_TAG_STRING) { + node.name = fun->str; + node.token = "string"; + } else if (fun->tag == GX_TAG_MAP) { + node.name = to_string((long) fun->ptr); + node.token = "map"; + } else if (fun->tag == GX_TAG_ARRAY) { + node.name = to_string((long) fun->ptr); + node.token = "array"; + } else if (fun->tag == GX_TAG_NULL) { + node.name = "null"; + node.token = "null"; + } + array[numFunction] = node; + res = array[numFunction]; + if (fun->tag == GX_TAG_STRING && fun->str != NULL) { + delete[] fun->str; + fun->str = NULL; + } + delete fun; + if (isFunction) { + isFunction = false; + delete[] paramsStack; + } + paramsSize = 0; + } else { + //操作符 + isNum1 = false; + op = op + cache[i]; + if (!isNumber(cache[i + 1]) && cache[i + 1] != ')') { + op = op + cache[i + 1]; + i++; + } + } + } + } + GXValue *pointer; + if (res.token == "string") { + pointer = new GXValue(GX_TAG_STRING, res.name); + } else if (res.token == "bool") { + if (res.name == "true") { + pointer = new GXValue(GX_TAG_BOOL, 1); + } else { + pointer = new GXValue(GX_TAG_BOOL, 0); + } + } else if (res.token == "num") { + if (res.name.find('.') != -1) { + regex e("0+?$"); + regex e2("[.]$"); + res.name = regex_replace(res.name, e, ""); + res.name = regex_replace(res.name, e2, ""); + } + pointer = new GXValue(GX_TAG_FLOAT, (float) atof(res.name.c_str())); + } else if (res.token == "map") { + pointer = new GXValue(GX_TAG_MAP, (void *) atol(res.name.c_str())); + } else if (res.token == "array") { + pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(res.name.c_str())); + } else if (res.token == "null") { + pointer = new GXValue(GX_TAG_NULL, 1); + } + + return (long) pointer; +} + + long GXAnalyze::check(string s, vector array, void *p_analyze, void *source, string expression) { + string tree; + if (array.size() == 1) { + tree = "(0)"; + } GXValue *pointer; GXAnalyze *analyze = (GXAnalyze *) p_analyze; string temp = "\0"; //需要分析的语句 @@ -938,6 +1268,7 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * long *paramsStack = new long[sentence.size() + 2]; int paramsSize = 0; int valueStep = 0; //数值数 + vector paramsTempArray; bool isFunction = false; string valueType; symbolStack[symbolSize] = '#'; @@ -982,6 +1313,9 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * delete[] symbolStack; delete[] valueStack; delete[] paramsStack; + if (cache.count(s) == 0) { + cache[s] = tree; + } return (long) pointer; } else if (new_status[0] == 's') { @@ -1004,6 +1338,7 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * if (temp == "value" || temp == "data") { long res = analyze->getSourceValue(array[valueStep].name, source); GXValue *gxv = (GXValue *) res; + t1.count = array[valueStep].count; if (gxv->tag == GX_TAG_FLOAT) { t1.name = to_string(gxv->float64); t1.token = "num"; @@ -1109,13 +1444,27 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * tempR2 = t2; valueSize = valueSize - 2; } else if (op == ")") { + int ParamsSize = valueSize - 1; for (int i = valueSize - 1; i >= 0; i--) { + if (i == ParamsSize) { + tree = tree + '('; + } if (valueStack[i].token == "id") { + //需要翻转一遍,否则取到的参数顺序是反过来的 + for (int paramsIndex = paramsTempArray.size() - 1; + paramsIndex >= 0; paramsIndex--) { + paramsStack[paramsSize] = paramsTempArray[paramsIndex]; + ++paramsSize; + } + paramsTempArray.clear(); + //这里特别注意,g是函数的识别符,需要和运算符做区分 + tree = tree + "g" + to_string(valueStack[i].count) + ")"; //在这里调用获取函数结果方法 long funVal = analyze->getFunctionValue(valueStack[i].name, paramsStack, paramsSize, ""); GXValue *fun = (GXValue *) funVal; + tempR.count = valueStack[i].count; //取出结果 if (fun->tag == GX_TAG_FLOAT) { tempR.name = to_string(fun->float64); @@ -1151,41 +1500,39 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * delete fun; break; } else { + if (valueStack[i - 1].token != "id") { + tree = tree + to_string(valueStack[i].count) + ","; + } else { + tree = tree + to_string(valueStack[i].count); + } //往vector逐个扔进去参数,然后通过id调用 if (valueStack[i].token == "num") { GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( valueStack[i].name.c_str())); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "string") { GXValue *par = new GXValue(GX_TAG_STRING, valueStack[i].name.c_str()); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "bool") { if (valueStack[i].name == "true") { GXValue *par = new GXValue(GX_TAG_BOOL, 1); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_BOOL, 0); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } } else if (valueStack[i].token == "map") { GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( valueStack[i].name.c_str())); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "array") { GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( valueStack[i].name.c_str())); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "null") { GXValue *par = new GXValue(GX_TAG_NULL, 1); - paramsStack[paramsSize] = (long) par; - ++paramsSize; + paramsTempArray.push_back((long) par); } --valueSize; } @@ -1201,6 +1548,9 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * } else { valueSize = valueSize - 2; tempR = doubleCalculate(t1, t2, op); + tempR.count = t2.count; + tree = tree + '(' + to_string(t1.count) + op + to_string(t2.count) + + ')'; if (tempR.token == "error") { delete[] statusStack; delete[] symbolStack; @@ -1223,6 +1573,10 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * t1 = valueStack[valueSize - 1]; --valueSize; tempR = singleCalculate(t1, op); + tempR.count = t1.count; + if (op != ")" && op != ",") { + tree = tree + '(' + to_string(t1.count) + op + ')'; + } if (tempR.token == "error") { analyze->throwError(tempR.name); return 0L; @@ -1260,3 +1614,5 @@ long GXAnalyze::check(string s, vector array, void *p_analyze, void * } } } + + diff --git a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.h b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.h index 083b98cb9..f0870a692 100644 --- a/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.h +++ b/GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.h @@ -40,8 +40,9 @@ class GXAnalyze { //获取单个数值计算的结果 GXATSNode singleCalculate(GXATSNode value1, string op); + long check(string s, vector array, void *p_analyze, void* source,string expression); - long check(string s, vector array, void *p_analyze, void *source, string expression); + long calculateCache(string cache,vector array,void *p_analyze, void* source); }; #endif /*include _GXAnalyze__H_*/ diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXCustomNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXCustomNode.m index 4cf0126b1..158943555 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXCustomNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXCustomNode.m @@ -103,7 +103,23 @@ - (void)bindData:(NSDictionary *)data{ } -//处理extend属性 +#pragma mark - 计算 + +//计算布局 +- (void)calculateWithData:(NSDictionary *)data{ + //赋值 + if ([GXUtils isDictionary:data]) { + //处理extend + NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; + if (extend) { + [self handleExtend:extend isCalculate:YES]; + } + } +} + + +#pragma mark - 处理extend属性 + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //更新布局属性 & 标记 BOOL isMark = [self updateLayoutStyle:extend]; @@ -128,21 +144,6 @@ - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ } -#pragma mark - 计算 - -//计算布局 -- (void)calculateWithData:(NSDictionary *)data{ - //赋值 - if ([GXUtils isDictionary:data]) { - //处理extend - NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; - if (extend) { - [self handleExtend:extend isCalculate:YES]; - } - } -} - - #pragma mark - 属性解析 //处理json中的属性 diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXGridNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXGridNode.m index 264db7a3d..74ce2a4e4 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXGridNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXGridNode.m @@ -153,7 +153,31 @@ - (void)bindData:(NSDictionary *)data{ } -// 处理extend + +#pragma mark - 计算高度 + +- (void)calculateWithData:(NSDictionary *)data{ + //处理数据 + NSArray *dataArray = nil; + NSDictionary *extend = nil; + + if ([GXUtils isValidDictionary:data]) { + //获取为{"value":[]}类型 + dataArray = [data gx_arrayForKey:@"value"]; + //处理extend + extend = [data gx_dictionaryForKey:@"extend"]; + } + + //赋值 + [self processListData:dataArray]; + + //处理extend属性 + [self handleExtend:extend isCalculate:YES]; +} + + +#pragma mark - 处理extend + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //更新布局属性 & 标记 @@ -273,27 +297,6 @@ - (void)calculateItemSize{ _itemSize = [TheGXTemplateEngine sizeWithTemplateItem:self.subTemplateItem measureSize:CGSizeMake(measureWidth, measureHeight)]; } -#pragma mark - 计算高度 - -- (void)calculateWithData:(NSDictionary *)data{ - //处理数据 - NSArray *dataArray = nil; - NSDictionary *extend = nil; - - if ([GXUtils isValidDictionary:data]) { - //获取为{"value":[]}类型 - dataArray = [data gx_arrayForKey:@"value"]; - //处理extend - extend = [data gx_dictionaryForKey:@"extend"]; - } - - //赋值 - [self processListData:dataArray]; - - //处理extend属性 - [self handleExtend:extend isCalculate:YES]; -} - #pragma mark - 属性设置 diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXIconFontNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXIconFontNode.m index d52af873e..00fe1f6ec 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXIconFontNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXIconFontNode.m @@ -126,6 +126,20 @@ - (void)bindData:(NSDictionary *)data{ } + +#pragma mark - 计算 + +- (void)calculateWithData:(NSDictionary *)data{ + //用于计算 & 避免走到父类计算 + if ([GXUtils isValidDictionary:data]) { + NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; + if (extend.count) { + [self handleExtend:extend isCalculate:YES]; + } + } +} + + #pragma mark - 处理extend //处理扩展属性 @@ -226,18 +240,6 @@ - (NSString *)utf8ToUnicode:(NSString *)string { } -#pragma mark - 计算 - -- (void)calculateWithData:(NSDictionary *)data{ - //用于计算 & 避免走到父类计算 - if ([GXUtils isValidDictionary:data]) { - NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; - if (extend.count) { - [self handleExtend:extend isCalculate:YES]; - } - } -} - #pragma mark - 读取属性 //读取属性 - (void)configureStyleInfo:(NSDictionary *)styleJson{ diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXImageNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXImageNode.m index 316c2b7a3..d71f379c1 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXImageNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXImageNode.m @@ -149,7 +149,22 @@ - (void)bindData:(id)imgData{ } -//处理扩展属性 + +#pragma mark - 计算Size + +- (void)calculateWithData:(NSDictionary *)data{ + //用于计算 & 避免走到父类计算 + if ([GXUtils isValidDictionary:data]) { + NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; + if (extend.count) { + [self handleExtend:extend isCalculate:YES]; + } + } +} + + +#pragma mark - 处理扩展属性 + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //更新布局属性 BOOL isMark = [self updateLayoutStyle:extend]; @@ -268,19 +283,6 @@ - (void)setImageView:(GXImageView *)imgView withImageInfo:(NSDictionary *)imageI } -#pragma mark - 计算Size - -- (void)calculateWithData:(NSDictionary *)data{ - //用于计算 & 避免走到父类计算 - if ([GXUtils isValidDictionary:data]) { - NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; - if (extend.count) { - [self handleExtend:extend isCalculate:YES]; - } - } -} - - #pragma mark - 解析属性 - (void)configureStyleInfo:(NSDictionary *)styleJson{ diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXRichTextNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXRichTextNode.m index df1b0d2de..fb910b467 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXRichTextNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXRichTextNode.m @@ -161,7 +161,33 @@ - (void)bindData:(NSDictionary *)data{ } -//处理扩展属性 +#pragma mark - 计算Size + +- (void)calculateWithData:(NSDictionary *)data{ + NSString *text = nil; + NSDictionary *extend = nil; + + // 读取属性赋值 + if ([GXUtils isValidDictionary:data]) { + //读取text + text = [data gx_stringForKey:@"value"]; + //读取扩展属性 + extend = [data gx_dictionaryForKey:@"extend"]; + //处理扩展属性 + if (extend || self.fitContent) { + [self handleExtend:extend isCalculate:YES]; + } + } else { + text = nil; + } + + //生成对应的文本 + [self processText:text]; +} + + +#pragma mark - 处理扩展属性 + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //是否刷新布局标志位 & fitContent属性 BOOL isMark = [self updateLayoutStyle:extend]; @@ -345,29 +371,4 @@ + (NSDictionary *)regexMap } -#pragma mark - 计算Size - -- (void)calculateWithData:(NSDictionary *)data{ - NSString *text = nil; - NSDictionary *extend = nil; - - // 读取属性赋值 - if ([GXUtils isValidDictionary:data]) { - //读取text - text = [data gx_stringForKey:@"value"]; - //读取扩展属性 - extend = [data gx_dictionaryForKey:@"extend"]; - //处理扩展属性 - if (extend.count) { - [self handleExtend:extend isCalculate:YES]; - } - } else { - text = nil; - } - - //生成对应的文本 - [self processText:text]; -} - - @end diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXScrollNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXScrollNode.m index 004ab991e..f7a178d55 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXScrollNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXScrollNode.m @@ -153,7 +153,29 @@ - (void)bindData:(NSDictionary *)data{ [scrollView reloadData]; } -// 处理extend + +#pragma mark - 计算高度 + +- (void)calculateWithData:(NSDictionary *)data{ + //数据 + NSArray *dataArray = nil; + NSDictionary *extend = nil; + if ([GXUtils isValidDictionary:data]) { + //获取为{"value":[]}类型 & extend + dataArray = [data gx_arrayForKey:@"value"]; + extend = [data gx_dictionaryForKey:@"extend"]; + } + + //赋值items + [self processListData:dataArray]; + + //计算extend + [self handleExtend:extend isCalculate:YES]; +} + + +#pragma mark - 处理extend + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //更新布局属性 & 标记 BOOL isMark = [self updateLayoutStyle:extend]; @@ -328,26 +350,6 @@ - (void)calculateItemSize:(NSDictionary *)extend{ } -#pragma mark - 计算高度 - -- (void)calculateWithData:(NSDictionary *)data{ - //数据 - NSArray *dataArray = nil; - NSDictionary *extend = nil; - if ([GXUtils isValidDictionary:data]) { - //获取为{"value":[]}类型 & extend - dataArray = [data gx_arrayForKey:@"value"]; - extend = [data gx_dictionaryForKey:@"extend"]; - } - - //赋值items - [self processListData:dataArray]; - - //计算extend - [self handleExtend:extend isCalculate:YES]; -} - - #pragma mark - 处理数据源 //将原始数据转化GXTemplateData diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXSliderNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXSliderNode.m index 569a3d980..1b9953ae5 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXSliderNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXSliderNode.m @@ -178,7 +178,29 @@ - (void)bindData:(NSDictionary *)data{ [scrollView reloadData]; } -// 处理extend + +#pragma mark - 计算高度 + +- (void)calculateWithData:(NSDictionary *)data{ + //数据 + NSArray *dataArray = nil; + NSDictionary *extend = nil; + if ([GXUtils isValidDictionary:data]) { + //获取为{"value":[]}类型 & extend + dataArray = [data gx_arrayForKey:@"value"]; + extend = [data gx_dictionaryForKey:@"extend"]; + } + + //赋值items + [self processListData:dataArray]; + + //计算extend + [self handleExtend:extend isCalculate:YES]; +} + + +#pragma mark - 处理extend + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //更新布局属性 & 标记 BOOL isMark = [self updateLayoutStyle:extend]; @@ -362,25 +384,6 @@ - (CGFloat)itemWidthForRule{ return width; } -#pragma mark - 计算高度 - -- (void)calculateWithData:(NSDictionary *)data{ - //数据 - NSArray *dataArray = nil; - NSDictionary *extend = nil; - if ([GXUtils isValidDictionary:data]) { - //获取为{"value":[]}类型 & extend - dataArray = [data gx_arrayForKey:@"value"]; - extend = [data gx_dictionaryForKey:@"extend"]; - } - - //赋值items - [self processListData:dataArray]; - - //计算extend - [self handleExtend:extend isCalculate:YES]; -} - #pragma mark - 处理数据源 diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXTextNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXTextNode.m index d07ec185a..71ec779a1 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXTextNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXTextNode.m @@ -184,7 +184,34 @@ - (void)bindData:(NSDictionary *)data{ } -//处理扩展属性 + +#pragma mark - 计算Size + +- (void)calculateWithData:(NSDictionary *)data{ + NSString *text = nil; + NSDictionary *extend = nil; + + // 读取属性赋值 + if ([GXUtils isValidDictionary:data]) { + //读取text + text = [data gx_stringForKey:@"value"]; + //读取扩展属性 + extend = [data gx_dictionaryForKey:@"extend"]; + //处理扩展属性 + if (extend || self.fitContent) { + [self handleExtend:extend isCalculate:YES]; + } + } else { + text = nil; + } + + //最终赋值 + self.text = text; +} + + +#pragma mark - 处理扩展属性 + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //是否刷新布局标志位 & fitContent属性 BOOL isMark = [self updateLayoutStyle:extend]; @@ -484,31 +511,6 @@ - (CGSize)labelSizeForFont:(UIFont *)font } -#pragma mark - 计算Size - -- (void)calculateWithData:(NSDictionary *)data{ - NSString *text = nil; - NSDictionary *extend = nil; - - // 读取属性赋值 - if ([GXUtils isValidDictionary:data]) { - //读取text - text = [data gx_stringForKey:@"value"]; - //读取扩展属性 - extend = [data gx_dictionaryForKey:@"extend"]; - //处理扩展属性 - if (extend.count) { - [self handleExtend:extend isCalculate:YES]; - } - } else { - text = nil; - } - - //最终赋值 - self.text = text; -} - - #pragma mark - 文字渐变 - (void)setupTextGradientColor:(UILabel *)view{ diff --git a/GaiaXiOS/GaiaXiOS/Component/Node/GXViewNode.m b/GaiaXiOS/GaiaXiOS/Component/Node/GXViewNode.m index 06393151d..2f67fcea5 100644 --- a/GaiaXiOS/GaiaXiOS/Component/Node/GXViewNode.m +++ b/GaiaXiOS/GaiaXiOS/Component/Node/GXViewNode.m @@ -108,7 +108,21 @@ - (void)bindData:(NSDictionary *)data{ } } -// 处理扩展处理 +#pragma mark - 计算高度 + +- (void)calculateWithData:(NSDictionary *)data{ + //赋值 + if ([GXUtils isValidDictionary:data]) { + NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; + if (extend) { + [self handleExtend:extend isCalculate:YES]; + } + } +} + + +#pragma mark - 扩展处理 + - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ //更新布局属性 & 标记 BOOL isMark = [self updateLayoutStyle:extend]; @@ -133,20 +147,6 @@ - (void)handleExtend:(NSDictionary *)extend isCalculate:(BOOL)isCalculate{ } -#pragma mark - 计算高度 - -- (void)calculateWithData:(NSDictionary *)data{ - //赋值 - if ([GXUtils isValidDictionary:data]) { - NSDictionary *extend = [data gx_dictionaryForKey:@"extend"]; - if (extend) { - [self handleExtend:extend isCalculate:YES]; - } - } -} - - - #pragma mark - 属性解析 //读取属性 diff --git a/GaiaXiOS/GaiaXiOS/Core/Render/GXLayoutManager.m b/GaiaXiOS/GaiaXiOS/Core/Render/GXLayoutManager.m index 7b57384e0..bc351d31e 100644 --- a/GaiaXiOS/GaiaXiOS/Core/Render/GXLayoutManager.m +++ b/GaiaXiOS/GaiaXiOS/Core/Render/GXLayoutManager.m @@ -47,7 +47,6 @@ - (CGSize)sizeWithTemplateItem:(GXTemplateItem *)templateItem //模板有效性 if ([templateItem isAvailable]) { - //获取节点 NSString *templateKey = [NSString stringWithFormat:@"%@-%f",templateItem.identifier, measureSize.width]; GXNode *rootNode = (GXNode *)[self.templateCache objectForKey:templateKey]; @@ -98,7 +97,6 @@ - (CGSize)sizeWithTemplateItem:(GXTemplateItem *)templateItem //模板有效性 if ([templateItem isAvailable]) { - //获取节点 NSString *templateKey = [NSString stringWithFormat:@"%@-%f",templateItem.identifier, measureSize.width]; GXNode *rootNode = (GXNode *)[self.templateCache objectForKey:templateKey]; diff --git a/GaiaXiOSDemo/GaiaXiOSDemo.xcodeproj/project.pbxproj b/GaiaXiOSDemo/GaiaXiOSDemo.xcodeproj/project.pbxproj index 05b0848b0..e425c07b8 100644 --- a/GaiaXiOSDemo/GaiaXiOSDemo.xcodeproj/project.pbxproj +++ b/GaiaXiOSDemo/GaiaXiOSDemo.xcodeproj/project.pbxproj @@ -23,6 +23,8 @@ 8D5D29AE276AD6A1005FD699 /* recommend.json in Resources */ = {isa = PBXBuildFile; fileRef = 8D5D29A9276AD6A1005FD699 /* recommend.json */; }; 8D5D29AF276AD6A1005FD699 /* uper-top.json in Resources */ = {isa = PBXBuildFile; fileRef = 8D5D29AA276AD6A1005FD699 /* uper-top.json */; }; 8D5D29B0276AD6A1005FD699 /* uper.json in Resources */ = {isa = PBXBuildFile; fileRef = 8D5D29AB276AD6A1005FD699 /* uper.json */; }; + 8D7570F828D0AF2A004AF92D /* RecycleListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D7570F528D0AF2A004AF92D /* RecycleListViewController.m */; }; + 8D7570F928D0AF2A004AF92D /* RecycleTemplateListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D7570F728D0AF2A004AF92D /* RecycleTemplateListCell.m */; }; 8D88D4C22788349F004F1614 /* GaiaXJSONRPCConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D88D4C12788349F004F1614 /* GaiaXJSONRPCConstants.m */; }; 8D88D4C5278834AF004F1614 /* GaiaXSocketRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D88D4C3278834AF004F1614 /* GaiaXSocketRequest.m */; }; 8D88D4C927883574004F1614 /* GaiaXPreviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D88D4C827883574004F1614 /* GaiaXPreviewViewController.m */; }; @@ -72,6 +74,10 @@ 8D5D29AA276AD6A1005FD699 /* uper-top.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "uper-top.json"; sourceTree = ""; }; 8D5D29AB276AD6A1005FD699 /* uper.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = uper.json; sourceTree = ""; }; 8D678A4628066EC40036A7D0 /* GaiaXiOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = GaiaXiOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D7570F428D0AF29004AF92D /* RecycleListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecycleListViewController.h; sourceTree = ""; }; + 8D7570F528D0AF2A004AF92D /* RecycleListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecycleListViewController.m; sourceTree = ""; }; + 8D7570F628D0AF2A004AF92D /* RecycleTemplateListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecycleTemplateListCell.h; sourceTree = ""; }; + 8D7570F728D0AF2A004AF92D /* RecycleTemplateListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecycleTemplateListCell.m; sourceTree = ""; }; 8D88D4C02788349F004F1614 /* GaiaXJSONRPCConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GaiaXJSONRPCConstants.h; sourceTree = ""; }; 8D88D4C12788349F004F1614 /* GaiaXJSONRPCConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GaiaXJSONRPCConstants.m; sourceTree = ""; }; 8D88D4C3278834AF004F1614 /* GaiaXSocketRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GaiaXSocketRequest.m; sourceTree = ""; }; @@ -141,6 +147,10 @@ 8D57F1D627733F0B00FF8CC3 /* ListViewController.m */, 8D57F1D82773412700FF8CC3 /* TemplateListCell.h */, 8D57F1D92773412700FF8CC3 /* TemplateListCell.m */, + 8D7570F428D0AF29004AF92D /* RecycleListViewController.h */, + 8D7570F528D0AF2A004AF92D /* RecycleListViewController.m */, + 8D7570F628D0AF2A004AF92D /* RecycleTemplateListCell.h */, + 8D7570F728D0AF2A004AF92D /* RecycleTemplateListCell.m */, ); path = Render; sourceTree = ""; @@ -384,6 +394,8 @@ files = ( 8D88D4C22788349F004F1614 /* GaiaXJSONRPCConstants.m in Sources */, 8D2180E12771AAA5001401C8 /* NestViewController.m in Sources */, + 8D7570F828D0AF2A004AF92D /* RecycleListViewController.m in Sources */, + 8D7570F928D0AF2A004AF92D /* RecycleTemplateListCell.m in Sources */, 8D88D4C927883574004F1614 /* GaiaXPreviewViewController.m in Sources */, 8DB52186275A0DCF00EB8126 /* ViewController.m in Sources */, 8D57F1DA2773412700FF8CC3 /* TemplateListCell.m in Sources */, @@ -620,7 +632,7 @@ "-weak_framework", "\"XCTest\"", ); - PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.GaiaXiOSDemo.zjc1; + PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.GaiaXiOSDemo.zjc1233; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "GaiaXiOSDemo/GaiaXiOSDemo-Bridging-Header.h"; @@ -688,7 +700,7 @@ "-weak_framework", "\"XCTest\"", ); - PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.GaiaXiOSDemo.zjc1; + PRODUCT_BUNDLE_IDENTIFIER = com.alibaba.GaiaXiOSDemo.zjc1233; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "GaiaXiOSDemo/GaiaXiOSDemo-Bridging-Header.h"; diff --git a/GaiaXiOSDemo/GaiaXiOSDemo.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate b/GaiaXiOSDemo/GaiaXiOSDemo.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate index be1e10b13..91cf655f5 100644 Binary files a/GaiaXiOSDemo/GaiaXiOSDemo.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate and b/GaiaXiOSDemo/GaiaXiOSDemo.xcworkspace/xcuserdata/zhangjc.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleListViewController.h b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleListViewController.h new file mode 100644 index 000000000..f91f377a6 --- /dev/null +++ b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleListViewController.h @@ -0,0 +1,27 @@ +// +// RecycleListViewController.h +// GaiaXiOSDemo +// +// Copyright (c) 2021, Alibaba Group Holding Limited. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RecycleListViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleListViewController.m b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleListViewController.m new file mode 100644 index 000000000..2e24ee69d --- /dev/null +++ b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleListViewController.m @@ -0,0 +1,131 @@ +// +// RecycleListViewController.m +// GaiaXiOSDemo +// +// Copyright (c) 2021, Alibaba Group Holding Limited. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "RecycleListViewController.h" +#import +#import "GaiaXHelper.h" +#import "RecycleTemplateListCell.h" + +@interface RecycleListViewController (){ + CGFloat _itemWidth; +} + +@property (nonatomic, strong) NSMutableArray *dataArray; +@property (nonatomic, strong) NSMutableArray *heights; +@property (nonatomic, strong) UICollectionView *collectionView; + +@end + +@implementation RecycleListViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = [UIColor whiteColor]; + [self.view addSubview:self.collectionView]; + _itemWidth = self.view.frame.size.width; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + //处理数据 + [self processTemplateInfo]; + + dispatch_async(dispatch_get_main_queue(), ^{ + //刷新UI + [self.collectionView reloadData]; + }); + }); +} + + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ + return self.dataArray.count; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { + CGFloat height = [self.heights[indexPath.item] floatValue]; + return CGSizeMake(_itemWidth, height); +} + + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath { + //重用标识 + RecycleTemplateListCell *cell = (RecycleTemplateListCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; + + //数据绑定 + GXTemplateData *data = [self.dataArray objectAtIndex:indexPath.item]; + [cell setupData:data]; + + return cell; +} + + +#pragma mark - data + +- (void)processTemplateInfo{ + GXTemplateItem *item = [[GXTemplateItem alloc] init]; + item.templateId = @"gx-subscribe-item"; + item.bizId = [GaiaXHelper bizId]; + + + for (int i = 0; i < 10; i++) { + //data + GXTemplateData *data = [[GXTemplateData alloc] init]; + data.data = [GaiaXHelper jsonWithFileName:@"subscribe-item"]; + + //高度 + CGFloat height = [TheGXTemplateEngine sizeWithTemplateItem:item measureSize:CGSizeMake(_itemWidth, NAN) data:data].height; + [self.heights addObject:@(height)]; + + //data + [self.dataArray addObject:data]; + } +} + +#pragma mark - lazy load + +- (UICollectionView *)collectionView{ + if (!_collectionView) { + UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; + flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; + flowLayout.minimumInteritemSpacing = 10; + + _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout]; + _collectionView.backgroundColor = [UIColor whiteColor]; + _collectionView.delegate = self; + _collectionView.dataSource = self; + [_collectionView registerClass:RecycleTemplateListCell.class forCellWithReuseIdentifier:@"cell"]; + } + return _collectionView; +} + +- (NSMutableArray *)dataArray{ + if (!_dataArray) { + _dataArray = [NSMutableArray array]; + } + return _dataArray; +} + +- (NSMutableArray *)heights{ + if (!_heights) { + _heights = [NSMutableArray array]; + } + return _heights; +} + + +@end diff --git a/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleTemplateListCell.h b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleTemplateListCell.h new file mode 100644 index 000000000..78acecd8b --- /dev/null +++ b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleTemplateListCell.h @@ -0,0 +1,32 @@ +// +// RecycleTemplateListCell.h +// GaiaXiOSDemo +// +// Copyright (c) 2021, Alibaba Group Holding Limited. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class GXTemplateData; +@interface RecycleTemplateListCell : UICollectionViewCell + +@property (nonatomic, strong) UIView *templateView; + +- (void)setupData:(GXTemplateData *)data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleTemplateListCell.m b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleTemplateListCell.m new file mode 100644 index 000000000..cc71c9d16 --- /dev/null +++ b/GaiaXiOSDemo/GaiaXiOSDemo/Render/RecycleTemplateListCell.m @@ -0,0 +1,43 @@ +// +// RecycleTemplateListCell.m +// GaiaXiOSDemo +// +// Copyright (c) 2021, Alibaba Group Holding Limited. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "RecycleTemplateListCell.h" +#import +#import "GaiaXHelper.h" + + +@implementation RecycleTemplateListCell + +- (instancetype)initWithFrame:(CGRect)frame{ + if (self = [super initWithFrame:frame]) { + GXTemplateItem *item = [[GXTemplateItem alloc] init]; + item.templateId = @"gx-subscribe-item"; + item.bizId = [GaiaXHelper bizId]; + _templateView = [TheGXTemplateEngine creatViewByTemplateItem:item measureSize:CGSizeMake([UIScreen mainScreen].bounds.size.width, NAN)]; + [self.contentView addSubview:_templateView]; + } + return self; +} + +- (void)setupData:(GXTemplateData *)data{ + //绑定数据 + [TheGXTemplateEngine bindData:data onView:_templateView]; + _templateView.backgroundColor = [UIColor greenColor]; +} + +@end diff --git a/GaiaXiOSDemo/GaiaXiOSDemo/Resource/en.lproj/FunctionList.plist b/GaiaXiOSDemo/GaiaXiOSDemo/Resource/en.lproj/FunctionList.plist index b8f976d39..75ba8725b 100644 --- a/GaiaXiOSDemo/GaiaXiOSDemo/Resource/en.lproj/FunctionList.plist +++ b/GaiaXiOSDemo/GaiaXiOSDemo/Resource/en.lproj/FunctionList.plist @@ -33,10 +33,17 @@ EventViewController + New item + + title + Template List + class + ListViewController + title - Template List + Recycle Template List class - ListViewController + RecycleListViewController diff --git a/GaiaXiOSDemo/GaiaXiOSDemo/Resource/zh-Hans.lproj/FunctionList.plist b/GaiaXiOSDemo/GaiaXiOSDemo/Resource/zh-Hans.lproj/FunctionList.plist index faf119342..4db843143 100644 --- a/GaiaXiOSDemo/GaiaXiOSDemo/Resource/zh-Hans.lproj/FunctionList.plist +++ b/GaiaXiOSDemo/GaiaXiOSDemo/Resource/zh-Hans.lproj/FunctionList.plist @@ -33,10 +33,17 @@ EventViewController + New item + + title + 模板列表 + class + ListViewController + title - 模板列表 + 复用模板列表 class - ListViewController + RecycleListViewController