mirror of https://github.com/mgba-emu/mgba.git
Scripting: Add struct setter
This commit is contained in:
parent
b0567832f8
commit
9ddada00f2
|
@ -579,6 +579,7 @@ void mScriptClassInit(struct mScriptTypeClass* cls);
|
||||||
void mScriptClassDeinit(struct mScriptTypeClass* cls);
|
void mScriptClassDeinit(struct mScriptTypeClass* cls);
|
||||||
|
|
||||||
bool mScriptObjectGet(struct mScriptValue* obj, const char* member, struct mScriptValue*);
|
bool mScriptObjectGet(struct mScriptValue* obj, const char* member, struct mScriptValue*);
|
||||||
|
bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScriptValue*);
|
||||||
|
|
||||||
bool mScriptPopS32(struct mScriptList* list, int32_t* out);
|
bool mScriptPopS32(struct mScriptList* list, int32_t* out);
|
||||||
bool mScriptPopU32(struct mScriptList* list, uint32_t* out);
|
bool mScriptPopU32(struct mScriptList* list, uint32_t* out);
|
||||||
|
|
|
@ -165,7 +165,7 @@ M_TEST_DEFINE(testALayout) {
|
||||||
assert_false(cls->init);
|
assert_false(cls->init);
|
||||||
}
|
}
|
||||||
|
|
||||||
M_TEST_DEFINE(testATranslation) {
|
M_TEST_DEFINE(testAGet) {
|
||||||
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls;
|
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls;
|
||||||
|
|
||||||
struct TestA s = {
|
struct TestA s = {
|
||||||
|
@ -200,6 +200,58 @@ M_TEST_DEFINE(testATranslation) {
|
||||||
assert_false(cls->init);
|
assert_false(cls->init);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(testASet) {
|
||||||
|
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls;
|
||||||
|
|
||||||
|
struct TestA s = {
|
||||||
|
.i = 1,
|
||||||
|
.i2 = 2,
|
||||||
|
.b8 = 3,
|
||||||
|
.hUnaligned = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mScriptValue sval = mSCRIPT_MAKE_S(TestA, &s);
|
||||||
|
struct mScriptValue val;
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(2);
|
||||||
|
assert_true(mScriptObjectSet(&sval, "i", &val));
|
||||||
|
assert_int_equal(s.i, 2);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(3);
|
||||||
|
assert_true(mScriptObjectSet(&sval, "i2", &val));
|
||||||
|
assert_int_equal(s.i2, 3);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(4);
|
||||||
|
assert_true(mScriptObjectSet(&sval, "b8", &val));
|
||||||
|
assert_int_equal(s.b8, 4);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(5);
|
||||||
|
assert_true(mScriptObjectSet(&sval, "hUnaligned", &val));
|
||||||
|
assert_int_equal(s.hUnaligned, 5);
|
||||||
|
|
||||||
|
sval = mSCRIPT_MAKE_CS(TestA, &s);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(3);
|
||||||
|
assert_false(mScriptObjectSet(&sval, "i", &val));
|
||||||
|
assert_int_equal(s.i, 2);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(4);
|
||||||
|
assert_false(mScriptObjectSet(&sval, "i2", &val));
|
||||||
|
assert_int_equal(s.i2, 3);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(5);
|
||||||
|
assert_false(mScriptObjectSet(&sval, "b8", &val));
|
||||||
|
assert_int_equal(s.b8, 4);
|
||||||
|
|
||||||
|
val = mSCRIPT_MAKE_S32(6);
|
||||||
|
assert_false(mScriptObjectSet(&sval, "hUnaligned", &val));
|
||||||
|
assert_int_equal(s.hUnaligned, 5);
|
||||||
|
|
||||||
|
assert_true(cls->init);
|
||||||
|
mScriptClassDeinit(cls);
|
||||||
|
assert_false(cls->init);
|
||||||
|
}
|
||||||
|
|
||||||
M_TEST_DEFINE(testAStatic) {
|
M_TEST_DEFINE(testAStatic) {
|
||||||
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls;
|
struct mScriptTypeClass* cls = mSCRIPT_TYPE_MS_S(TestA)->details.cls;
|
||||||
assert_false(cls->init);
|
assert_false(cls->init);
|
||||||
|
@ -442,6 +494,7 @@ M_TEST_DEFINE(testADynamic) {
|
||||||
|
|
||||||
M_TEST_SUITE_DEFINE(mScriptClasses,
|
M_TEST_SUITE_DEFINE(mScriptClasses,
|
||||||
cmocka_unit_test(testALayout),
|
cmocka_unit_test(testALayout),
|
||||||
cmocka_unit_test(testATranslation),
|
cmocka_unit_test(testAGet),
|
||||||
|
cmocka_unit_test(testASet),
|
||||||
cmocka_unit_test(testAStatic),
|
cmocka_unit_test(testAStatic),
|
||||||
cmocka_unit_test(testADynamic))
|
cmocka_unit_test(testADynamic))
|
||||||
|
|
|
@ -886,6 +886,85 @@ bool mScriptObjectGet(struct mScriptValue* obj, const char* member, struct mScri
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScriptValue* val) {
|
||||||
|
if (obj->type->base != mSCRIPT_TYPE_OBJECT || obj->type->isConst) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mScriptTypeClass* cls = obj->type->details.cls;
|
||||||
|
if (!cls) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mScriptClassInit(cls);
|
||||||
|
|
||||||
|
struct mScriptClassMember* m = HashTableLookup(&cls->instanceMembers, member);
|
||||||
|
if (!m) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* rawMember = (void *)((uintptr_t) obj->value.opaque + m->offset);
|
||||||
|
if (m->type != val->type) {
|
||||||
|
if (!mScriptCast(m->type, val, val)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m->type->base) {
|
||||||
|
case mSCRIPT_TYPE_SINT:
|
||||||
|
switch (m->type->size) {
|
||||||
|
case 1:
|
||||||
|
*(int8_t *) rawMember = val->value.s32;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(int16_t *) rawMember = val->value.s32;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(int32_t *) rawMember = val->value.s32;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
*(int64_t *) rawMember = val->value.s64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mSCRIPT_TYPE_UINT:
|
||||||
|
switch (m->type->size) {
|
||||||
|
case 1:
|
||||||
|
*(uint8_t *) rawMember = val->value.u32;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(uint16_t *) rawMember = val->value.u32;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(uint32_t *) rawMember = val->value.u32;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
*(uint64_t *) rawMember = val->value.u64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mSCRIPT_TYPE_FLOAT:
|
||||||
|
switch (m->type->size) {
|
||||||
|
case 4:
|
||||||
|
*(mSCRIPT_TYPE_C_F32 *) rawMember = val->value.f32;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
*(mSCRIPT_TYPE_C_F64 *) rawMember = val->value.f64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool mScriptPopS32(struct mScriptList* list, int32_t* out) {
|
bool mScriptPopS32(struct mScriptList* list, int32_t* out) {
|
||||||
mSCRIPT_POP(list, S32, val);
|
mSCRIPT_POP(list, S32, val);
|
||||||
*out = val;
|
*out = val;
|
||||||
|
|
Loading…
Reference in New Issue