mirror of
https://github.com/InfiniTimeOrg/InfiniTime.git
synced 2024-10-22 23:21:53 +02:00
Use inheritance for values
This commit is contained in:
parent
7ac66dc237
commit
bf13db05ce
|
@ -72,31 +72,31 @@ void ASM::run() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Push0:
|
case Push0:
|
||||||
push(std::make_shared<Value>((uint32_t) 0));
|
push(std::make_shared<ValueInteger>(0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PushU8:
|
case PushU8:
|
||||||
push(std::make_shared<Value>(read_byte(pc)));
|
push(std::make_shared<ValueInteger>(read_byte(pc)));
|
||||||
pc++;
|
pc++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PushU16:
|
case PushU16:
|
||||||
push(std::make_shared<Value>(read_u16(pc)));
|
push(std::make_shared<ValueInteger>(read_u16(pc)));
|
||||||
pc += 2;
|
pc += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PushU24:
|
case PushU24:
|
||||||
push(std::make_shared<Value>(read_u24(pc)));
|
push(std::make_shared<ValueInteger>(read_u24(pc)));
|
||||||
pc += 3;
|
pc += 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PushU32:
|
case PushU32:
|
||||||
push(std::make_shared<Value>(read_u32(pc)));
|
push(std::make_shared<ValueInteger>(read_u32(pc)));
|
||||||
pc += 4;
|
pc += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PushEmptyString:
|
case PushEmptyString:
|
||||||
push(std::make_shared<Value>(new char[1] {0}, 1));
|
push(std::make_shared<ValueString>(new char[1] {0}, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Duplicate:
|
case Duplicate:
|
||||||
|
@ -114,7 +114,7 @@ void ASM::run() {
|
||||||
text[i] = read_byte(ptr + 1 + i);
|
text[i] = read_byte(ptr + 1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
push(std::make_shared<Value>(text, length + 1));
|
push(std::make_shared<ValueString>(text, length + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ void ASM::run() {
|
||||||
case Call: {
|
case Call: {
|
||||||
uint32_t next = pc;
|
uint32_t next = pc;
|
||||||
pc = pop_uint32();
|
pc = pop_uint32();
|
||||||
push(std::make_shared<Value>(next));
|
push(std::make_shared<ValueInteger>(next));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,23 +151,23 @@ void ASM::run() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetLabelText: {
|
case SetLabelText: {
|
||||||
auto str = pop(String);
|
auto str = pop<ValueString>(String);
|
||||||
auto obj = pop(LvglObject);
|
auto obj = pop<ValueLvglObject>(LvglObject);
|
||||||
|
|
||||||
lv_label_set_text(obj->data.lvobj, str->data.s);
|
lv_label_set_text(obj->obj, str->str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CreateLabel:
|
case CreateLabel:
|
||||||
push(std::make_shared<Value>(lv_label_create(lv_scr_act(), NULL)));
|
push(std::make_shared<ValueLvglObject>(lv_label_create(lv_scr_act(), NULL)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetObjectAlign: {
|
case SetObjectAlign: {
|
||||||
int16_t y = pop_uint32();
|
int16_t y = pop_uint32();
|
||||||
int16_t x = pop_uint32();
|
int16_t x = pop_uint32();
|
||||||
uint8_t align = pop_uint32();
|
uint8_t align = pop_uint32();
|
||||||
auto obj = pop(LvglObject);
|
auto obj = pop<ValueLvglObject>(LvglObject);
|
||||||
lv_obj_align(obj->data.lvobj, lv_scr_act(), align, x, y);
|
lv_obj_align(obj->obj, lv_scr_act(), align, x, y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,15 +177,15 @@ void ASM::run() {
|
||||||
uint32_t value = pop_uint32();
|
uint32_t value = pop_uint32();
|
||||||
uint32_t prop = pop_uint32();
|
uint32_t prop = pop_uint32();
|
||||||
uint32_t part = pop_uint32();
|
uint32_t part = pop_uint32();
|
||||||
auto obj = pop(LvglObject);
|
auto obj = pop<ValueLvglObject>(LvglObject);
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case SetStyleLocalInt:
|
case SetStyleLocalInt:
|
||||||
_lv_obj_set_style_local_int(obj->data.lvobj, part, prop, value);
|
_lv_obj_set_style_local_int(obj->obj, part, prop, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetStyleLocalColor:
|
case SetStyleLocalColor:
|
||||||
_lv_obj_set_style_local_color(obj->data.lvobj, part, prop, lv_color_hex(value));
|
_lv_obj_set_style_local_color(obj->obj, part, prop, lv_color_hex(value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetStyleLocalFont: {
|
case SetStyleLocalFont: {
|
||||||
|
@ -202,7 +202,7 @@ void ASM::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font)
|
if (font)
|
||||||
_lv_obj_set_style_local_ptr(obj->data.lvobj, part, prop, font);
|
_lv_obj_set_style_local_ptr(obj->obj, part, prop, font);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -214,33 +214,33 @@ void ASM::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case Add: {
|
case Add: {
|
||||||
push(std::make_shared<Value>(pop_uint32() + pop_uint32()));
|
push(std::make_shared<ValueInteger>(pop_uint32() + pop_uint32()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Subtract:
|
case Subtract:
|
||||||
push(std::make_shared<Value>(pop_uint32() - pop_uint32()));
|
push(std::make_shared<ValueInteger>(pop_uint32() - pop_uint32()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Multiply:
|
case Multiply:
|
||||||
push(std::make_shared<Value>(pop_uint32() * pop_uint32()));
|
push(std::make_shared<ValueInteger>(pop_uint32() * pop_uint32()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Divide:
|
case Divide:
|
||||||
push(std::make_shared<Value>(pop_uint32() / pop_uint32()));
|
push(std::make_shared<ValueInteger>(pop_uint32() / pop_uint32()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GrowString: {
|
case GrowString: {
|
||||||
auto len = pop(Integer);
|
auto len = pop_uint32();
|
||||||
auto str = pop(String);
|
auto str = pop<ValueString>(String);
|
||||||
|
|
||||||
size_t new_cap = len->data.i + str->data.cap;
|
size_t new_cap = len + str->capacity;
|
||||||
asm_assert(new_cap >= str->data.cap);
|
asm_assert(new_cap >= str->capacity);
|
||||||
|
|
||||||
char* new_str = new char[new_cap];
|
char* new_str = new char[new_cap];
|
||||||
memcpy(new_str, str->data.s, str->data.cap);
|
memcpy(new_str, str->str, str->capacity);
|
||||||
|
|
||||||
push(std::make_shared<Value>(new_str, new_cap));
|
push(std::make_shared<ValueString>(new_str, new_cap));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,29 +248,37 @@ void ASM::run() {
|
||||||
auto b = pop();
|
auto b = pop();
|
||||||
auto a = pop();
|
auto a = pop();
|
||||||
|
|
||||||
if (a->type == String && b->type == String) {
|
if (a->type() == String && b->type() == String) {
|
||||||
int len_a = strlen(a->data.s);
|
auto aString = static_cast<ValueString*>(a.get());
|
||||||
int len_b = strlen(b->data.s);
|
auto bString = static_cast<ValueString*>(b.get());
|
||||||
|
|
||||||
|
int len_a = strlen(aString->str);
|
||||||
|
int len_b = strlen(bString->str);
|
||||||
|
|
||||||
size_t new_len = len_a + len_b + 1;
|
size_t new_len = len_a + len_b + 1;
|
||||||
|
|
||||||
if (a->data.cap >= new_len) {
|
if (aString->capacity >= new_len) {
|
||||||
strcat(a->data.s, b->data.s);
|
strcat(aString->str, bString->str);
|
||||||
|
|
||||||
push(a);
|
push(a);
|
||||||
} else {
|
} else {
|
||||||
char* s = new char[new_len + 1];
|
char* s = new char[new_len + 1];
|
||||||
strcpy(s, a->data.s);
|
strcpy(s, aString->str);
|
||||||
strcat(s, b->data.s);
|
strcat(s, bString->str);
|
||||||
|
|
||||||
push(std::make_shared<Value>(s, new_len + 1));
|
push(std::make_shared<ValueString>(s, new_len + 1));
|
||||||
}
|
}
|
||||||
} else if (a->type == String && b->type == Integer) {
|
} else if (a->type() == String && b->type() == Integer) {
|
||||||
size_t cap = strlen(a->data.s) + 12 + 1;
|
auto aString = static_cast<ValueString*>(a.get());
|
||||||
char* s = new char[cap];
|
auto bInt = static_cast<ValueInteger*>(b.get());
|
||||||
snprintf(s, cap, "%s%lu", a->data.s, b->data.i);
|
|
||||||
|
|
||||||
push(std::make_shared<Value>(s, cap));
|
if (bInt) {
|
||||||
|
size_t cap = strlen(aString->str) + 12 + 1;
|
||||||
|
char* s = new char[cap];
|
||||||
|
snprintf(s, cap, "%s%lu", aString->str, bInt->i);
|
||||||
|
|
||||||
|
push(std::make_shared<ValueString>(s, cap));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
asm_assert(false);
|
asm_assert(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,51 +25,50 @@ namespace Pinetime {
|
||||||
|
|
||||||
enum DataType : uint8_t { Integer, String, LvglObject };
|
enum DataType : uint8_t { Integer, String, LvglObject };
|
||||||
|
|
||||||
|
// TODO: Use fancy C++ type stuff
|
||||||
struct Value {
|
struct Value {
|
||||||
const DataType type;
|
virtual DataType type() = 0;
|
||||||
|
|
||||||
union {
|
|
||||||
uint32_t i;
|
|
||||||
lv_obj_t* lvobj;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
char* s;
|
|
||||||
uint16_t cap;
|
|
||||||
};
|
};
|
||||||
} data;
|
|
||||||
|
|
||||||
Value() : type(Integer), data {0} {
|
struct ValueInteger : public Value {
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
ValueInteger(uint32_t i) : i(i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value(DataType t) : type(t), data {0} {
|
DataType type() override {
|
||||||
|
return Integer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ValueString : public Value {
|
||||||
|
char* str;
|
||||||
|
uint16_t capacity;
|
||||||
|
|
||||||
|
ValueString(char* str, uint16_t cap) : str(str), capacity(cap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value(uint32_t i) : type(Integer) {
|
~ValueString() {
|
||||||
data.i = i;
|
delete[] str;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value(lv_obj_t* obj) : type(LvglObject) {
|
DataType type() override {
|
||||||
data.lvobj = obj;
|
return String;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ValueLvglObject : public Value {
|
||||||
|
lv_obj_t* obj;
|
||||||
|
|
||||||
|
ValueLvglObject(lv_obj_t* obj) : obj(obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value(char* s, uint16_t cap) : type(String) {
|
~ValueLvglObject() {
|
||||||
data.s = s;
|
lv_obj_del(obj);
|
||||||
data.cap = cap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Value() {
|
DataType type() override {
|
||||||
switch (type) {
|
return LvglObject;
|
||||||
case String:
|
|
||||||
delete[] data.s;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LvglObject:
|
|
||||||
lv_obj_del(data.lvobj);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -140,15 +139,18 @@ namespace Pinetime {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Value> pop(DataType type) {
|
template <typename T>
|
||||||
|
std::shared_ptr<T> pop(DataType type)
|
||||||
|
requires(std::is_base_of_v<Value, T>)
|
||||||
|
{
|
||||||
auto v = pop();
|
auto v = pop();
|
||||||
asm_assert(v->type == type);
|
asm_assert(v->type() == type);
|
||||||
|
|
||||||
return v;
|
return std::static_pointer_cast<T>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pop_uint32() {
|
uint32_t pop_uint32() {
|
||||||
return pop(Integer)->data.i;
|
return pop<ValueInteger>(Integer)->i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(std::shared_ptr<Value> v) {
|
void push(std::shared_ptr<Value> v) {
|
||||||
|
|
Loading…
Reference in a new issue