mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-30 02:58:26 +08:00
add object_get_prop_by_path
This commit is contained in:
parent
d875b44f0c
commit
cb5cd61d99
@ -2,6 +2,8 @@
|
||||
|
||||
* 2019/09/19
|
||||
* 修改"color\_component" "digit\_clock" "mutable\_image"的注释,支持designer编辑(感谢大恒提供补丁)。
|
||||
* 增加object\_array
|
||||
* 增加object\_get\_prop\_by\_path
|
||||
|
||||
* 2019/09/18
|
||||
* 增加iostream\_mem。
|
||||
|
@ -90,10 +90,10 @@ object_t* object_ref(object_t* obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
ret_t object_get_prop(object_t* obj, const char* name, value_t* v) {
|
||||
static ret_t object_get_prop_by_name(object_t* obj, const char* name, value_t* v) {
|
||||
ret_t ret = RET_NOT_FOUND;
|
||||
return_value_if_fail(obj != NULL && obj->vt != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(obj != NULL && obj->vt != NULL && obj->ref_count >= 0, RET_BAD_PARAMS);
|
||||
|
||||
value_set_int(v, 0);
|
||||
if (obj->vt->get_prop != NULL) {
|
||||
@ -103,6 +103,51 @@ ret_t object_get_prop(object_t* obj, const char* name, value_t* v) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t object_get_prop_by_path(object_t* obj, const char* name, value_t* v) {
|
||||
char* p = NULL;
|
||||
uint32_t len = 0;
|
||||
char path[MAX_PATH + 1];
|
||||
ret_t ret = RET_NOT_FOUND;
|
||||
return_value_if_fail(obj != NULL && obj->vt != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(name != NULL && v != NULL, RET_BAD_PARAMS);
|
||||
|
||||
len = strlen(name);
|
||||
return_value_if_fail(len <= MAX_PATH, RET_BAD_PARAMS);
|
||||
|
||||
memcpy(path, name, len + 1);
|
||||
|
||||
name = path;
|
||||
do {
|
||||
p = strchr(name, '.');
|
||||
if (p != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
if (object_get_prop_by_name(obj, name, v) != RET_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
ret = RET_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
if (v->type == VALUE_TYPE_OBJECT) {
|
||||
obj = value_object(v);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
name = p + 1;
|
||||
} while (p != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t object_get_prop(object_t* obj, const char* name, value_t* v) {
|
||||
return object_get_prop_by_name(obj, name, v);
|
||||
}
|
||||
|
||||
const char* object_get_prop_str(object_t* obj, const char* name) {
|
||||
value_t v;
|
||||
if (object_get_prop(obj, name, &v) == RET_OK) {
|
||||
|
@ -465,6 +465,18 @@ ret_t object_exec(object_t* obj, const char* name, const char* args);
|
||||
*/
|
||||
ret_t object_notify_changed(object_t* obj);
|
||||
|
||||
/**
|
||||
* @method object_get_prop_by_path
|
||||
* 获取指定path属性的值。
|
||||
*
|
||||
* @param {object_t*} obj object对象。
|
||||
* @param {const char*} path 属性的path,各级之间用.分隔。
|
||||
* @param {value_t*} v 返回属性的值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t object_get_prop_by_path(object_t* obj, const char* path, value_t* v);
|
||||
|
||||
#define OBJECT(obj) ((object_t*)(obj))
|
||||
|
||||
END_C_DECLS
|
||||
|
@ -112,6 +112,7 @@ static ret_t object_array_remove_prop(object_t* obj, const char* name) {
|
||||
ret_t ret = RET_NOT_FOUND;
|
||||
int32_t index = tk_atoi(name);
|
||||
object_array_t* o = OBJECT_ARRAY(obj);
|
||||
return_value_if_fail(isdigit(*name), RET_NOT_FOUND);
|
||||
|
||||
if (index >= 0 && index < o->props_size) {
|
||||
value_t* iter = o->props + index;
|
||||
@ -129,7 +130,7 @@ static ret_t object_array_set_prop(object_t* obj, const char* name, const value_
|
||||
int32_t index = tk_atoi(name);
|
||||
return_value_if_fail(object_array_extend(obj) == RET_OK, RET_OOM);
|
||||
|
||||
if (index >= 0 && index < o->props_size) {
|
||||
if (isdigit(*name) && index >= 0 && index < o->props_size) {
|
||||
value_t* iter = o->props + index;
|
||||
value_reset(iter);
|
||||
ret = value_deep_copy(iter, v);
|
||||
@ -149,7 +150,7 @@ static ret_t object_array_get_prop(object_t* obj, const char* name, value_t* v)
|
||||
if (tk_str_eq(name, "length") || tk_str_eq(name, "size")) {
|
||||
value_set_int(v, o->props_size);
|
||||
ret = RET_OK;
|
||||
} else {
|
||||
} else if (isdigit(*name)) {
|
||||
int32_t index = tk_atoi(name);
|
||||
if (index >= 0 && index < o->props_size) {
|
||||
value_t* iter = o->props + index;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/object_default.h"
|
||||
#include "tkc/object_array.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdlib.h>
|
||||
@ -126,7 +127,7 @@ TEST(ObjectArray, dup) {
|
||||
ASSERT_EQ(object_set_prop(obj, "-1", value_set_int(&v, 3)), RET_OK);
|
||||
|
||||
dup = object_array_clone(OBJECT_ARRAY(obj));
|
||||
|
||||
|
||||
log = "";
|
||||
object_foreach_prop(dup, visit_dump, &log);
|
||||
ASSERT_EQ(log, "0123");
|
||||
@ -135,3 +136,49 @@ TEST(ObjectArray, dup) {
|
||||
object_unref(dup);
|
||||
}
|
||||
|
||||
TEST(ObjectArray, path) {
|
||||
value_t v;
|
||||
object_t* clone = NULL;
|
||||
object_t* root = object_default_create();
|
||||
object_t* obja = object_array_create();
|
||||
object_t* obja1 = object_default_create();
|
||||
object_t* obja2 = object_default_create();
|
||||
object_t* objb = object_array_create();
|
||||
object_t* objb1 = object_default_create();
|
||||
object_t* objb2 = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(root, "a", obja), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_object(root, "b", objb), RET_OK);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(obja, "-1", obja1), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(obja1, "value", 456), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "a.0.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 456);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(obja, "-1", obja2), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(obja2, "value", 56), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "a.1.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 56);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(objb, "-1", objb1), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(objb1, "value", 56), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "b.0.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 56);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(objb, "-1", objb2), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(objb2, "value", 156), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "b.1.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 156);
|
||||
|
||||
ASSERT_NE(object_get_prop_by_path(root, "a.a.value", &v), RET_OK);
|
||||
ASSERT_NE(object_get_prop_by_path(root, "b.a.value", &v), RET_OK);
|
||||
ASSERT_NE(object_get_prop_by_path(root, "c.value", &v), RET_OK);
|
||||
|
||||
object_unref(root);
|
||||
object_unref(obja);
|
||||
object_unref(obja1);
|
||||
object_unref(obja2);
|
||||
object_unref(objb);
|
||||
object_unref(objb1);
|
||||
object_unref(objb2);
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ static ret_t visit_dump(void* ctx, const void* data) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, events) {
|
||||
TEST(ObjectDefault, events) {
|
||||
value_t v;
|
||||
string log;
|
||||
object_t* obj = object_default_create();
|
||||
@ -47,7 +47,7 @@ TEST(ObejectDefault, events) {
|
||||
ASSERT_EQ(log, "6:6:8:8:destroy:");
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, basic) {
|
||||
TEST(ObjectDefault, basic) {
|
||||
value_t v;
|
||||
string log;
|
||||
object_t* obj = object_default_create();
|
||||
@ -189,7 +189,7 @@ static ret_t visit_test_busy(void* ctx, const void* data) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, visis_remove) {
|
||||
TEST(ObjectDefault, visis_remove) {
|
||||
value_t v;
|
||||
string log;
|
||||
object_t* obj = object_default_create();
|
||||
@ -226,7 +226,7 @@ TEST(ObejectDefault, visis_remove) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, random) {
|
||||
TEST(ObjectDefault, random) {
|
||||
value_t v;
|
||||
string log;
|
||||
char name[32];
|
||||
@ -248,7 +248,7 @@ TEST(ObejectDefault, random) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, set_name) {
|
||||
TEST(ObjectDefault, set_name) {
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
object_set_name(obj, "abc");
|
||||
@ -260,7 +260,7 @@ TEST(ObejectDefault, set_name) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, set_prop_int) {
|
||||
TEST(ObjectDefault, set_prop_int) {
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_set_prop_int(obj, "int", 123), RET_OK);
|
||||
@ -269,7 +269,7 @@ TEST(ObejectDefault, set_prop_int) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, set_prop_float) {
|
||||
TEST(ObjectDefault, set_prop_float) {
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_set_prop_float(obj, "float", 123), RET_OK);
|
||||
@ -278,7 +278,7 @@ TEST(ObejectDefault, set_prop_float) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, copy_prop) {
|
||||
TEST(ObjectDefault, copy_prop) {
|
||||
object_t* src = object_default_create();
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
@ -294,7 +294,7 @@ TEST(ObejectDefault, copy_prop) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, set_prop_str) {
|
||||
TEST(ObjectDefault, set_prop_str) {
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_set_prop_str(obj, "str", "123"), RET_OK);
|
||||
@ -303,7 +303,7 @@ TEST(ObejectDefault, set_prop_str) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, exec) {
|
||||
TEST(ObjectDefault, exec) {
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_can_exec(obj, "test", "123"), FALSE);
|
||||
@ -312,7 +312,7 @@ TEST(ObejectDefault, exec) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, has_prop) {
|
||||
TEST(ObjectDefault, has_prop) {
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_set_prop_float(obj, "a", 123), RET_OK);
|
||||
@ -322,7 +322,7 @@ TEST(ObejectDefault, has_prop) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, expr_number) {
|
||||
TEST(ObjectDefault, expr_number) {
|
||||
value_t v;
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
@ -337,7 +337,7 @@ TEST(ObejectDefault, expr_number) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, expr_str) {
|
||||
TEST(ObjectDefault, expr_str) {
|
||||
value_t v;
|
||||
object_t* obj = object_default_create();
|
||||
|
||||
@ -350,7 +350,7 @@ TEST(ObejectDefault, expr_str) {
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
TEST(ObejectDefault, clone) {
|
||||
TEST(ObjectDefault, clone) {
|
||||
value_t v;
|
||||
object_t* clone = NULL;
|
||||
object_t* obj = object_default_create();
|
||||
@ -366,3 +366,58 @@ TEST(ObejectDefault, clone) {
|
||||
object_unref(obj);
|
||||
object_unref(clone);
|
||||
}
|
||||
|
||||
TEST(ObjectDefault, path) {
|
||||
value_t v;
|
||||
object_t* clone = NULL;
|
||||
object_t* root = object_default_create();
|
||||
object_t* obja = object_default_create();
|
||||
object_t* obja1 = object_default_create();
|
||||
object_t* obja2 = object_default_create();
|
||||
object_t* objb = object_default_create();
|
||||
object_t* objb1 = object_default_create();
|
||||
object_t* objb2 = object_default_create();
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(root, "a", obja), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_object(root, "b", objb), RET_OK);
|
||||
|
||||
ASSERT_EQ(object_set_prop_int(obja, "value", 123), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "a.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 123);
|
||||
|
||||
ASSERT_EQ(object_set_prop_int(objb, "value", 123), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "b.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 123);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(obja, "1", obja1), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(obja1, "value", 456), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "a.1.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 456);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(obja, "2", obja2), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(obja2, "value", 56), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "a.2.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 56);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(objb, "1", objb1), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(objb1, "value", 56), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "b.1.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 56);
|
||||
|
||||
ASSERT_EQ(object_set_prop_object(objb, "2", objb2), RET_OK);
|
||||
ASSERT_EQ(object_set_prop_int(objb2, "value", 156), RET_OK);
|
||||
ASSERT_EQ(object_get_prop_by_path(root, "b.2.value", &v), RET_OK);
|
||||
ASSERT_EQ(value_int(&v), 156);
|
||||
|
||||
ASSERT_NE(object_get_prop_by_path(root, "a.a.value", &v), RET_OK);
|
||||
ASSERT_NE(object_get_prop_by_path(root, "b.a.value", &v), RET_OK);
|
||||
ASSERT_NE(object_get_prop_by_path(root, "c.value", &v), RET_OK);
|
||||
|
||||
object_unref(root);
|
||||
object_unref(obja);
|
||||
object_unref(obja1);
|
||||
object_unref(obja2);
|
||||
object_unref(objb);
|
||||
object_unref(objb1);
|
||||
object_unref(objb2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user