diff options
author | 2011-12-22 13:11:48 -0800 | |
---|---|---|
committer | 2011-12-22 13:11:48 -0800 | |
commit | 3aac0abe7965ce9e2078c7d5796805d83e39df7c (patch) | |
tree | d562c10f687ce53cbd3fd11d47722803225c260a | |
parent | a6db9389bd429e8d894209473301475159829b52 (diff) |
Adding tests for element/mesh getters.
Fixing bugs found by tests.
Change-Id: I6592a3b65f16b21255e7788fe8ee8aaafe268638
8 files changed, 485 insertions, 29 deletions
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index d76c20965c9f..110eceb0be13 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -48,11 +48,36 @@ public class Element extends BaseObj { int[] mArraySizes; int[] mOffsetInBytes; + int[] mVisibleElementMap; + DataType mType; DataKind mKind; boolean mNormalized; int mVectorSize; + private void updateVisibleSubElements() { + if (mElements == null) { + return; + } + + int noPaddingFieldCount = 0; + int fieldCount = mElementNames.length; + // Find out how many elements are not padding + for (int ct = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].charAt(0) != '#') { + noPaddingFieldCount ++; + } + } + mVisibleElementMap = new int[noPaddingFieldCount]; + + // Make a map that points us at non-padding elements + for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].charAt(0) != '#') { + mVisibleElementMap[ctNoPadding ++] = ct; + } + } + } + /** * @hide * @return element size in bytes @@ -77,6 +102,11 @@ public class Element extends BaseObj { * RS_* objects. 32 bit opaque handles. */ public enum DataType { + /** + * @hide + * new enum + */ + NONE (0, 0), //FLOAT_16 (1, 2), FLOAT_32 (2, 4), FLOAT_64 (3, 8), @@ -163,10 +193,10 @@ public class Element extends BaseObj { * @return number of sub-elements in this element */ public int getSubElementCount() { - if (mElements == null) { + if (mVisibleElementMap == null) { return 0; } - return mElements.length; + return mVisibleElementMap.length; } /** @@ -175,13 +205,13 @@ public class Element extends BaseObj { * @return sub-element in this element at given index */ public Element getSubElement(int index) { - if (mElements == null) { + if (mVisibleElementMap == null) { throw new RSIllegalArgumentException("Element contains no sub-elements"); } - if (index < 0 || index >= mElements.length) { + if (index < 0 || index >= mVisibleElementMap.length) { throw new RSIllegalArgumentException("Illegal sub-element index"); } - return mElements[index]; + return mElements[mVisibleElementMap[index]]; } /** @@ -190,13 +220,13 @@ public class Element extends BaseObj { * @return sub-element in this element at given index */ public String getSubElementName(int index) { - if (mElements == null) { + if (mVisibleElementMap == null) { throw new RSIllegalArgumentException("Element contains no sub-elements"); } - if (index < 0 || index >= mElements.length) { + if (index < 0 || index >= mVisibleElementMap.length) { throw new RSIllegalArgumentException("Illegal sub-element index"); } - return mElementNames[index]; + return mElementNames[mVisibleElementMap[index]]; } /** @@ -205,13 +235,13 @@ public class Element extends BaseObj { * @return array size of sub-element in this element at given index */ public int getSubElementArraySize(int index) { - if (mElements == null) { + if (mVisibleElementMap == null) { throw new RSIllegalArgumentException("Element contains no sub-elements"); } - if (index < 0 || index >= mElements.length) { + if (index < 0 || index >= mVisibleElementMap.length) { throw new RSIllegalArgumentException("Illegal sub-element index"); } - return mArraySizes[index]; + return mArraySizes[mVisibleElementMap[index]]; } /** @@ -220,13 +250,13 @@ public class Element extends BaseObj { * @return offset in bytes of sub-element in this element at given index */ public int getSubElementOffsetBytes(int index) { - if (mElements == null) { + if (mVisibleElementMap == null) { throw new RSIllegalArgumentException("Element contains no sub-elements"); } - if (index < 0 || index >= mElements.length) { + if (index < 0 || index >= mVisibleElementMap.length) { throw new RSIllegalArgumentException("Illegal sub-element index"); } - return mOffsetInBytes[index]; + return mOffsetInBytes[mVisibleElementMap[index]]; } /** @@ -696,11 +726,14 @@ public class Element extends BaseObj { mElements = e; mElementNames = n; mArraySizes = as; + mType = DataType.NONE; + mKind = DataKind.USER; mOffsetInBytes = new int[mElements.length]; for (int ct = 0; ct < mElements.length; ct++ ) { mOffsetInBytes[ct] = mSize; mSize += mElements[ct].mSize * mArraySizes[ct]; } + updateVisibleSubElements(); } Element(int id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) { @@ -765,7 +798,7 @@ public class Element extends BaseObj { mSize += mElements[i].mSize * mArraySizes[i]; } } - + updateVisibleSubElements(); } /** diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index 1e022cfc251d..24c873822387 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -27,6 +27,7 @@ Element::Element(Context *rsc) : ObjectBase(rsc) { mFields = NULL; mFieldCount = 0; mHasReference = false; + memset(&mHal, 0, sizeof(mHal)); } Element::~Element() { @@ -176,16 +177,23 @@ void Element::compute() { return; } - mHal.state.fields = new const Element*[mFieldCount]; - mHal.state.fieldArraySizes = new uint32_t[mFieldCount]; - mHal.state.fieldNames = new const char*[mFieldCount]; - mHal.state.fieldNameLengths = new uint32_t[mFieldCount]; - mHal.state.fieldOffsetBytes = new uint32_t[mFieldCount]; - mHal.state.fieldsCount = mFieldCount; + uint32_t noPaddingFieldCount = 0; + for (uint32_t ct = 0; ct < mFieldCount; ct ++) { + if (mFields[ct].name.string()[0] != '#') { + noPaddingFieldCount ++; + } + } + + mHal.state.fields = new const Element*[noPaddingFieldCount]; + mHal.state.fieldArraySizes = new uint32_t[noPaddingFieldCount]; + mHal.state.fieldNames = new const char*[noPaddingFieldCount]; + mHal.state.fieldNameLengths = new uint32_t[noPaddingFieldCount]; + mHal.state.fieldOffsetBytes = new uint32_t[noPaddingFieldCount]; + mHal.state.fieldsCount = noPaddingFieldCount; size_t bits = 0; size_t bitsUnpadded = 0; - for (size_t ct=0; ct < mFieldCount; ct++) { + for (size_t ct = 0, ctNoPadding = 0; ct < mFieldCount; ct++) { mFields[ct].offsetBits = bits; mFields[ct].offsetBitsUnpadded = bitsUnpadded; bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize; @@ -195,11 +203,17 @@ void Element::compute() { mHasReference = true; } - mHal.state.fields[ct] = mFields[ct].e.get(); - mHal.state.fieldArraySizes[ct] = mFields[ct].arraySize; - mHal.state.fieldNames[ct] = mFields[ct].name.string(); - mHal.state.fieldNameLengths[ct] = mFields[ct].name.length() + 1; // to include 0 - mHal.state.fieldOffsetBytes[ct] = mFields[ct].offsetBits >> 3; + if (mFields[ct].name.string()[0] == '#') { + continue; + } + + mHal.state.fields[ctNoPadding] = mFields[ct].e.get(); + mHal.state.fieldArraySizes[ctNoPadding] = mFields[ct].arraySize; + mHal.state.fieldNames[ctNoPadding] = mFields[ct].name.string(); + mHal.state.fieldNameLengths[ctNoPadding] = mFields[ct].name.length() + 1; // to include 0 + mHal.state.fieldOffsetBytes[ctNoPadding] = mFields[ct].offsetBits >> 3; + + ctNoPadding ++; } mHal.state.elementSizeBytes = getSizeBytes(); diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh index c9bb4dc85f54..e1c8650ddc66 100644 --- a/libs/rs/scriptc/rs_types.rsh +++ b/libs/rs/scriptc/rs_types.rsh @@ -435,8 +435,8 @@ typedef enum { */ typedef enum { RS_TYPE_NONE, - RS_TYPE_FLOAT_16, - RS_TYPE_FLOAT_32, + //RS_TYPE_FLOAT_16, + RS_TYPE_FLOAT_32 = 2, RS_TYPE_FLOAT_64, RS_TYPE_SIGNED_8, RS_TYPE_SIGNED_16, diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java index 4466e59b62e1..b3486abe0699 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java @@ -64,6 +64,8 @@ public class RSTestCore { unitTests = new ArrayList<UnitTest>(); + unitTests.add(new UT_mesh(this, mRes, mCtx)); + unitTests.add(new UT_element(this, mRes, mCtx)); unitTests.add(new UT_sampler(this, mRes, mCtx)); unitTests.add(new UT_program_store(this, mRes, mCtx)); unitTests.add(new UT_program_raster(this, mRes, mCtx)); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java new file mode 100644 index 000000000000..942f63406a1f --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Element.*; +import android.renderscript.Element.DataKind.*; +import android.renderscript.Element.DataType.*; + +public class UT_element extends UnitTest { + private Resources mRes; + + Element simpleElem; + Element complexElem; + + final String subElemNames[] = { + "subElem0", + "subElem1", + "subElem2", + "arrayElem0", + "arrayElem1", + "subElem3", + "subElem4", + "subElem5", + "subElem6", + "subElem_7", + }; + + final int subElemArraySizes[] = { + 1, + 1, + 1, + 2, + 5, + 1, + 1, + 1, + 1, + 1, + }; + + final int subElemOffsets[] = { + 0, + 4, + 8, + 12, + 20, + 40, + 44, + 48, + 64, + 80, + }; + + protected UT_element(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Element", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_element s) { + simpleElem = Element.F32_3(RS); + complexElem = ScriptField_ComplexStruct.createElement(RS); + s.set_simpleElem(simpleElem); + s.set_complexElem(complexElem); + + ScriptField_ComplexStruct data = new ScriptField_ComplexStruct(RS, 1); + s.bind_complexStruct(data); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_element s = new ScriptC_element(pRS, mRes, R.raw.element); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_element_test(); + pRS.finish(); + waitForMessage(); + } + + private void testJavaSide(RenderScript RS) { + + int subElemCount = simpleElem.getSubElementCount(); + _RS_ASSERT("subElemCount == 0", subElemCount == 0); + _RS_ASSERT("simpleElem.getDataKind() == USER", + simpleElem.getDataKind() == DataKind.USER); + _RS_ASSERT("simpleElem.getDataType() == FLOAT_32", + simpleElem.getDataType() == DataType.FLOAT_32); + + subElemCount = complexElem.getSubElementCount(); + _RS_ASSERT("subElemCount == 10", subElemCount == 10); + _RS_ASSERT("complexElem.getDataKind() == USER", + complexElem.getDataKind() == DataKind.USER); + _RS_ASSERT("complexElemsimpleElem.getDataType() == NONE", + complexElem.getDataType() == DataType.NONE); + _RS_ASSERT("complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof", + complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof); + + for (int i = 0; i < subElemCount; i ++) { + _RS_ASSERT("complexElem.getSubElement(i) != null", + complexElem.getSubElement(i) != null); + _RS_ASSERT("complexElem.getSubElementName(i).equals(subElemNames[i])", + complexElem.getSubElementName(i).equals(subElemNames[i])); + _RS_ASSERT("complexElem.getSubElementArraySize(i) == subElemArraySizes[i]", + complexElem.getSubElementArraySize(i) == subElemArraySizes[i]); + _RS_ASSERT("complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]", + complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]); + } + + updateUI(); + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testScriptSide(pRS); + testJavaSide(pRS); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java new file mode 100644 index 000000000000..2ea9f17fbd38 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Mesh.*; + +public class UT_mesh extends UnitTest { + private Resources mRes; + + Mesh mesh; + + protected UT_mesh(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Mesh", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_mesh s) { + Allocation vAlloc0 = Allocation.createSized(RS, Element.F32(RS), 10); + Allocation vAlloc1 = Allocation.createSized(RS, Element.F32_2(RS), 10); + + Allocation iAlloc0 = Allocation.createSized(RS, Element.I16(RS), 10); + Allocation iAlloc2 = Allocation.createSized(RS, Element.I16(RS), 10); + + Mesh.AllocationBuilder mBuilder = new Mesh.AllocationBuilder(RS); + mBuilder.addVertexAllocation(vAlloc0); + mBuilder.addVertexAllocation(vAlloc1); + + mBuilder.addIndexSetAllocation(iAlloc0, Primitive.POINT); + mBuilder.addIndexSetType(Primitive.LINE); + mBuilder.addIndexSetAllocation(iAlloc2, Primitive.TRIANGLE); + + s.set_mesh(mBuilder.create()); + s.set_vertexAlloc0(vAlloc0); + s.set_vertexAlloc1(vAlloc1); + s.set_indexAlloc0(iAlloc0); + s.set_indexAlloc2(iAlloc2); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_mesh s = new ScriptC_mesh(pRS, mRes, R.raw.mesh); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_mesh_test(); + pRS.finish(); + waitForMessage(); + } + + private void testJavaSide(RenderScript RS) { + updateUI(); + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testScriptSide(pRS); + testJavaSide(pRS); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs new file mode 100644 index 000000000000..c0bd36e5d717 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs @@ -0,0 +1,141 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_element simpleElem; +rs_element complexElem; +typedef struct ComplexStruct { + float subElem0; + float subElem1; + int subElem2; + float arrayElem0[2]; + int arrayElem1[5]; + char subElem3; + float subElem4; + float2 subElem5; + float3 subElem6; + float4 subElem_7; +} ComplexStruct_t; + +ComplexStruct_t *complexStruct; + +static const char *subElemNames[] = { + "subElem0", + "subElem1", + "subElem2", + "arrayElem0", + "arrayElem1", + "subElem3", + "subElem4", + "subElem5", + "subElem6", + "subElem_7", +}; + +static uint32_t subElemNamesSizes[] = { + 8, + 8, + 8, + 10, + 10, + 8, + 8, + 8, + 8, + 9, +}; + +static uint32_t subElemArraySizes[] = { + 1, + 1, + 1, + 2, + 5, + 1, + 1, + 1, + 1, + 1, +}; + +static void resetStruct() { + uint8_t *bytePtr = (uint8_t*)complexStruct; + uint32_t sizeOfStruct = sizeof(*complexStruct); + for(uint32_t i = 0; i < sizeOfStruct; i ++) { + bytePtr[i] = 0; + } +} + +static bool equals(const char *name0, const char * name1, uint32_t len) { + for (uint32_t i = 0; i < len; i ++) { + if (name0[i] != name1[i]) { + return false; + } + } + return true; +} + +static bool test_element_getters() { + bool failed = false; + + uint32_t subElemOffsets[10]; + uint32_t index = 0; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem0 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem1 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem2 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem0 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem1 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem3 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem4 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem5 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem6 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem_7 - (uint32_t)complexStruct; + + uint32_t subElemCount = rsElementGetSubElementCount(simpleElem); + _RS_ASSERT(subElemCount == 0); + _RS_ASSERT(rsElementGetDataKind(simpleElem) == RS_KIND_USER); + _RS_ASSERT(rsElementGetDataType(simpleElem) == RS_TYPE_FLOAT_32); + + subElemCount = rsElementGetSubElementCount(complexElem); + _RS_ASSERT(subElemCount == 10); + _RS_ASSERT(rsElementGetDataKind(complexElem) == RS_KIND_USER); + _RS_ASSERT(rsElementGetDataType(complexElem) == RS_TYPE_NONE); + _RS_ASSERT(rsElementGetSizeBytes(complexElem) == sizeof(*complexStruct)); + + char buffer[64]; + for (uint32_t i = 0; i < subElemCount; i ++) { + rs_element subElem = rsElementGetSubElement(complexElem, i); + _RS_ASSERT(rsIsObject(subElem)); + + _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, i) == subElemNamesSizes[i] + 1); + + uint32_t written = rsElementGetSubElementName(complexElem, i, buffer, 64); + rsDebug(subElemNames[i], subElemNames[i]); + _RS_ASSERT(written == subElemNamesSizes[i]); + _RS_ASSERT(equals(buffer, subElemNames[i], written)); + + _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, i) == subElemArraySizes[i]); + _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, i) == subElemOffsets[i]); + } + + if (failed) { + rsDebug("test_element_getters FAILED", 0); + } + else { + rsDebug("test_element_getters PASSED", 0); + } + + return failed; +} + +void element_test() { + bool failed = false; + failed |= test_element_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs new file mode 100644 index 000000000000..4d2b25533aa4 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs @@ -0,0 +1,58 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_mesh mesh; +rs_allocation vertexAlloc0; +rs_allocation vertexAlloc1; + +rs_allocation indexAlloc0; +rs_allocation indexAlloc2; + +static bool test_mesh_getters() { + bool failed = false; + + _RS_ASSERT(rsMeshGetVertexAllocationCount(mesh) == 2); + _RS_ASSERT(rsMeshGetPrimitiveCount(mesh) == 3); + + rs_allocation meshV0 = rsMeshGetVertexAllocation(mesh, 0); + rs_allocation meshV1 = rsMeshGetVertexAllocation(mesh, 1); + rs_allocation meshV2 = rsMeshGetVertexAllocation(mesh, 2); + _RS_ASSERT(meshV0.p == vertexAlloc0.p); + _RS_ASSERT(meshV1.p == vertexAlloc1.p); + _RS_ASSERT(!rsIsObject(meshV2)); + + rs_allocation meshI0 = rsMeshGetIndexAllocation(mesh, 0); + rs_allocation meshI1 = rsMeshGetIndexAllocation(mesh, 1); + rs_allocation meshI2 = rsMeshGetIndexAllocation(mesh, 2); + rs_allocation meshI3 = rsMeshGetIndexAllocation(mesh, 3); + _RS_ASSERT(meshI0.p == indexAlloc0.p); + _RS_ASSERT(!rsIsObject(meshI1)); + _RS_ASSERT(meshI2.p == indexAlloc2.p); + _RS_ASSERT(!rsIsObject(meshI3)); + + rs_primitive p0 = rsMeshGetPrimitive(mesh, 0); + rs_primitive p1 = rsMeshGetPrimitive(mesh, 1); + rs_primitive p2 = rsMeshGetPrimitive(mesh, 2); + + if (failed) { + rsDebug("test_mesh_getters FAILED", 0); + } + else { + rsDebug("test_mesh_getters PASSED", 0); + } + + return failed; +} + +void mesh_test() { + bool failed = false; + failed |= test_mesh_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + |