Core generator distinguishes which fields need to be stored or not (via encoded flag).
diff --git a/dev/core_generator/lib/src/definition.dart b/dev/core_generator/lib/src/definition.dart
index 6951988..fdfbea2 100644
--- a/dev/core_generator/lib/src/definition.dart
+++ b/dev/core_generator/lib/src/definition.dart
@@ -165,10 +165,17 @@
code.writeln('static const uint16_t ${property.name}PropertyKey = '
'${property.key.intValue};');
}
- code.writeln('private:');
+ if (properties.any((prop) => !prop.isEncoded)) {
+ code.writeln('private:');
+ }
// Write fields.
for (final property in properties) {
+ if (property.isEncoded) {
+ // Encoded properties don't store data, it's up to the implementation
+ // to decode and store what it needs.
+ continue;
+ }
code.writeln('${property.type.cppName} m_${property.capitalizedName}');
var initialize = property.initialValueRuntime ??
@@ -186,19 +193,37 @@
// Write getter/setters.
code.writeln('public:');
for (final property in properties) {
- code.writeln((property.isVirtual ? 'virtual' : 'inline') +
- ' ${property.type.cppGetterName} ${property.name}() const ' +
- (property.isGetOverride ? 'override' : '') +
- '{ return m_${property.capitalizedName}; }');
+ if (property.isEncoded) {
+ // Encoded properties just have a pure virtual decoder that needs to
+ // be implemented. Also requires an implemention of copyPropertyName
+ // as that will no longer automatically be copied by the generated
+ // code.
+ code.writeln((property.isSetOverride ? '' : 'virtual ') +
+ 'void decode${property.capitalizedName}' +
+ '(${property.type.cppName} value) ' +
+ (property.isSetOverride ? 'override' : '') +
+ '= 0;');
+ code.writeln((property.isSetOverride ? '' : 'virtual ') +
+ 'void copy${property.capitalizedName}' +
+ '(const ${_name}Base& object) ' +
+ (property.isSetOverride ? 'override' : '') +
+ '= 0;');
+ } else {
+ code.writeln((property.isVirtual ? 'virtual' : 'inline') +
+ ' ${property.type.cppGetterName} ${property.name}() const ' +
+ (property.isGetOverride ? 'override' : '') +
+ '{ return m_${property.capitalizedName}; }');
- code.writeln('void ${property.name}(${property.type.cppName} value) ' +
- (property.isSetOverride ? 'override' : '') +
- '{'
- 'if(m_${property.capitalizedName} == value)'
- '{return;}'
- 'm_${property.capitalizedName} = value;'
- '${property.name}Changed();'
- '}');
+ code.writeln(
+ 'void ${property.name}(${property.type.cppName} value) ' +
+ (property.isSetOverride ? 'override' : '') +
+ '{'
+ 'if(m_${property.capitalizedName} == value)'
+ '{return;}'
+ 'm_${property.capitalizedName} = value;'
+ '${property.name}Changed();'
+ '}');
+ }
code.writeln();
}
@@ -211,8 +236,12 @@
if (properties.isNotEmpty || _extensionOf == null) {
code.writeln('void copy(const ${_name}Base& object) {');
for (final property in properties) {
- code.writeln('m_${property.capitalizedName} = '
- 'object.m_${property.capitalizedName};');
+ if (property.isEncoded) {
+ code.writeln('copy${property.capitalizedName}(object);');
+ } else {
+ code.writeln('m_${property.capitalizedName} = '
+ 'object.m_${property.capitalizedName};');
+ }
}
if (_extensionOf != null) {
code.writeln('${_extensionOf.name}::'
@@ -227,8 +256,13 @@
code.writeln('switch (propertyKey){');
for (final property in properties) {
code.writeln('case ${property.name}PropertyKey:');
- code.writeln('m_${property.capitalizedName} = '
- '${property.type.runtimeCoreType}::deserialize(reader);');
+ if (property.isEncoded) {
+ code.writeln('decode${property.capitalizedName}'
+ '(${property.type.runtimeCoreType}::deserialize(reader));');
+ } else {
+ code.writeln('m_${property.capitalizedName} = '
+ '${property.type.runtimeCoreType}::deserialize(reader);');
+ }
code.writeln('return true;');
}
code.writeln('}');
@@ -400,18 +434,23 @@
ctxCode.writeln('} return nullptr; }');
var usedFieldTypes = <FieldType, List<Property>>{};
+ var getSetFieldTypes = <FieldType, List<Property>>{};
for (final definition in runtimeDefinitions) {
for (final property in definition.properties) {
usedFieldTypes[property.type] ??= [];
usedFieldTypes[property.type].add(property);
+ if (!property.isEncoded) {
+ getSetFieldTypes[property.type] ??= [];
+ getSetFieldTypes[property.type].add(property);
+ }
}
}
- for (final fieldType in usedFieldTypes.keys) {
+ for (final fieldType in getSetFieldTypes.keys) {
ctxCode
.writeln('static void set${fieldType.capitalizedName}(Core* object, '
'int propertyKey, ${fieldType.cppName} value){');
ctxCode.writeln('switch (propertyKey) {');
- var properties = usedFieldTypes[fieldType];
+ var properties = getSetFieldTypes[fieldType];
for (final property in properties) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${property.name}PropertyKey:');
@@ -421,12 +460,12 @@
}
ctxCode.writeln('}}');
}
- for (final fieldType in usedFieldTypes.keys) {
+ for (final fieldType in getSetFieldTypes.keys) {
ctxCode.writeln(
'static ${fieldType.cppName} get${fieldType.capitalizedName}('
'Core* object, int propertyKey){');
ctxCode.writeln('switch (propertyKey) {');
- var properties = usedFieldTypes[fieldType];
+ var properties = getSetFieldTypes[fieldType];
for (final property in properties) {
ctxCode.writeln('case ${property.definition.name}Base'
'::${property.name}PropertyKey:');
@@ -451,25 +490,7 @@
}
ctxCode.writeln('default: return -1;}}');
- /*Core makeCoreInstance(int typeKey) {
- switch (typeKey) {
- case KeyedObjectBase.typeKey:
- return KeyedObject();
- case KeyedPropertyBase.typeKey:
- return KeyedProperty();*/
- // Put our fields in.
- // var usedFieldTypes = <FieldType>{};
- // for (final definition in definitions.values) {
- // for (final property in definition.properties) {
- // usedFieldTypes.add(property.type);
- // }
- // }
- // // Find fields we use.
- // for (final fieldType in usedFieldTypes) {
- // ctxCode.writeln('static ${fieldType.runtimeCoreType} '
- // '${fieldType.uncapitalizedName}Type;');
- // }
ctxCode.writeln('};}');
var output = generatedHppPath;
diff --git a/dev/core_generator/lib/src/property.dart b/dev/core_generator/lib/src/property.dart
index be707a4..76b3be8 100644
--- a/dev/core_generator/lib/src/property.dart
+++ b/dev/core_generator/lib/src/property.dart
@@ -1,5 +1,4 @@
import 'package:colorize/colorize.dart';
-import 'package:core_generator/src/comment.dart';
import 'package:core_generator/src/definition.dart';
import 'package:core_generator/src/field_type.dart';
import 'package:core_generator/src/key.dart';
@@ -20,6 +19,7 @@
bool isCoop = true;
bool isSetOverride = false;
bool isGetOverride = false;
+ bool isEncoded = false;
FieldType typeRuntime;
factory Property(Definition type, String name, Map<String, dynamic> data) {
@@ -28,7 +28,7 @@
}
var fieldType =
- FieldType.find(data["typeRuntime"]) ?? FieldType.find(data["type"]);
+ FieldType.find(data['typeRuntime']) ?? FieldType.find(data['type']);
if (fieldType == null) {
color('Invalid field type ${data['type']} for $name.', front: Styles.RED);
@@ -39,7 +39,11 @@
Property.make(
this.definition, this.name, this.type, Map<String, dynamic> data) {
- dynamic descriptionValue = data["description"];
+ dynamic encodedValue = data['encoded'];
+ if (encodedValue is bool) {
+ isEncoded = encodedValue;
+ }
+ dynamic descriptionValue = data['description'];
if (descriptionValue is String) {
description = descriptionValue;
}
@@ -89,153 +93,11 @@
if (rt is String) {
typeRuntime = FieldType.find(rt);
}
- key = Key.fromJSON(data["key"]) ?? Key.forProperty(this);
+ key = Key.fromJSON(data['key']) ?? Key.forProperty(this);
}
FieldType getExportType() => typeRuntime ?? type;
- String generateCode(bool forRuntime) {
- bool exportAnimates = false;
- var exportType = getExportType();
- String propertyKey = '${name}PropertyKey';
- var code = StringBuffer(' /// ${'-' * 74}\n');
- code.write(comment('${capitalize(name)} field with key ${key.intValue}.',
- indent: 1));
- if (initialValueRuntime != null || initialValue != null) {
- code.writeln(
- '${exportType.cppName} _$name = ${initialValueRuntime ?? initialValue};');
- } else {
- code.writeln('${exportType.cppName} _$name;');
- }
- if (exportAnimates) {
- code.writeln('${exportType.cppName} _${name}Animated;');
- code.writeln('KeyState _${name}KeyState = KeyState.none;');
- }
- code.writeln('static const int $propertyKey = ${key.intValue};');
-
- if (description != null) {
- code.write(comment(description, indent: 1));
- }
- if (exportAnimates) {
- code.write(comment(
- 'Get the [_$name] field value.'
- 'Note this may not match the core value '
- 'if animation mode is active.',
- indent: 1));
- code.writeln(
- '${exportType.cppName} get $name => _${name}Animated ?? _$name;');
- code.write(
- comment('Get the non-animation [_$name] field value.', indent: 1));
- code.writeln('${exportType.cppName} get ${name}Core => _$name;');
- } else {
- code.writeln('${exportType.cppName} get $name => _$name;');
- }
- code.write(comment('Change the [_$name] field value.', indent: 1));
- code.write(comment(
- '[${name}Changed] will be invoked only if the '
- 'field\'\s value has changed.',
- indent: 1));
- code.writeln(
- '''set $name${exportAnimates ? 'Core' : ''}(${exportType.cppName} value) {
- if(${exportType.equalityCheck('_$name', 'value')}) { return; }
- ${exportType.cppName} from = _$name;
- _$name = value;''');
- // Property change callbacks to the context don't propagate at runtime.
- if (!forRuntime) {
- code.writeln('onPropertyChanged($propertyKey, from, value);');
- if (!isCoop) {
- code.writeln(
- 'context?.editorPropertyChanged(this, $propertyKey, from, value);');
- }
- }
- // Change callbacks do as we use those to trigger dirty states.
- code.writeln('''
- ${name}Changed(from, value);
- }''');
- if (exportAnimates) {
- code.writeln('''set $name(${exportType.cppName} value) {
- if(context != null && context.isAnimating && $name != value) {
- _${name}Animate(value, true);
- return;
- }
- ${name}Core = value;
- }''');
-
- code.writeln(
- '''void _${name}Animate(${exportType.cppName} value, bool autoKey) {
- if (_${name}Animated == value) {
- return;
- }
- ${exportType.cppName} from = $name;
- _${name}Animated = value;
- ${exportType.cppName} to = $name;
- onAnimatedPropertyChanged($propertyKey, autoKey, from, to);
- ${name}Changed(from, to);
- }''');
-
- code.writeln(
- '${exportType.cppName} get ${name}Animated => _${name}Animated;');
- code.writeln('''set ${name}Animated(${exportType.cppName} value) =>
- _${name}Animate(value, false);''');
- code.writeln('KeyState get ${name}KeyState => _${name}KeyState;');
- code.writeln('''set ${name}KeyState(KeyState value) {
- if (_${name}KeyState == value) {
- return;
- }
- _${name}KeyState = value;
- // Force update anything listening on this property.
- onAnimatedPropertyChanged($propertyKey, false, _${name}Animated, _${name}Animated);
- }''');
- }
- code.writeln('void ${name}Changed('
- '${exportType.cppName} from, ${exportType.cppName} to);\n');
-
- return code.toString();
- }
-
- Map<String, dynamic> serialize() {
- Map<String, dynamic> data = <String, dynamic>{'type': type.name};
- if (typeRuntime != null) {
- data['typeRuntime'] = typeRuntime.name;
- }
-
- if (initialValue != null) {
- data['initialValue'] = initialValue;
- }
- if (initialValueRuntime != null) {
- data['initialValueRuntime'] = initialValueRuntime;
- }
- if (isGetOverride) {
- data['overrideGet'] = true;
- }
- if (isSetOverride) {
- data['overrideSet'] = true;
- }
- if (animates) {
- data['animates'] = true;
- }
- if (group != null) {
- data['group'] = group;
- }
- data['key'] = key.serialize();
- if (description != null) {
- data['description'] = description;
- }
- if (isNullable) {
- data['nullable'] = true;
- }
- if (!isRuntime) {
- data['runtime'] = false;
- }
- if (!isCoop) {
- data['coop'] = false;
- }
- if (isVirtual) {
- data['virtual'] = true;
- }
- return data;
- }
-
@override
String toString() {
return '$name(${key.intValue})';
diff --git a/dev/defs/shapes/mesh.json b/dev/defs/shapes/mesh.json
index e4986d5..857676b 100644
--- a/dev/defs/shapes/mesh.json
+++ b/dev/defs/shapes/mesh.json
@@ -29,6 +29,7 @@
},
"triangleIndexBytes": {
"type": "Bytes",
+ "encoded": true,
"key": {
"int": 223,
"string": "triangleindexbytes"
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp
index cef092c..d7d46a3 100644
--- a/include/rive/generated/core_registry.hpp
+++ b/include/rive/generated/core_registry.hpp
@@ -784,9 +784,6 @@
static void
setBytes(Core* object, int propertyKey, std::vector<uint8_t> value) {
switch (propertyKey) {
- case MeshBase::triangleIndexBytesPropertyKey:
- object->as<MeshBase>()->triangleIndexBytes(value);
- break;
case FileAssetContentsBase::bytesPropertyKey:
object->as<FileAssetContentsBase>()->bytes(value);
break;
@@ -1162,8 +1159,6 @@
}
static std::vector<uint8_t> getBytes(Core* object, int propertyKey) {
switch (propertyKey) {
- case MeshBase::triangleIndexBytesPropertyKey:
- return object->as<MeshBase>()->triangleIndexBytes();
case FileAssetContentsBase::bytesPropertyKey:
return object->as<FileAssetContentsBase>()->bytes();
}
diff --git a/include/rive/generated/shapes/mesh_base.hpp b/include/rive/generated/shapes/mesh_base.hpp
index 5a2aa1e..ff9b93d 100644
--- a/include/rive/generated/shapes/mesh_base.hpp
+++ b/include/rive/generated/shapes/mesh_base.hpp
@@ -28,31 +28,21 @@
static const uint16_t triangleIndexBytesPropertyKey = 223;
- private:
- std::vector<uint8_t> m_TriangleIndexBytes;
-
public:
- inline const std::vector<uint8_t>& triangleIndexBytes() const {
- return m_TriangleIndexBytes;
- }
- void triangleIndexBytes(std::vector<uint8_t> value) {
- if (m_TriangleIndexBytes == value) {
- return;
- }
- m_TriangleIndexBytes = value;
- triangleIndexBytesChanged();
- }
+ virtual void decodeTriangleIndexBytes(std::vector<uint8_t> value) = 0;
+ virtual void copyTriangleIndexBytes(const MeshBase& object) = 0;
Core* clone() const override;
void copy(const MeshBase& object) {
- m_TriangleIndexBytes = object.m_TriangleIndexBytes;
+ copyTriangleIndexBytes(object);
ContainerComponent::copy(object);
}
bool deserialize(uint16_t propertyKey, BinaryReader& reader) override {
switch (propertyKey) {
case triangleIndexBytesPropertyKey:
- m_TriangleIndexBytes = CoreBytesType::deserialize(reader);
+ decodeTriangleIndexBytes(
+ CoreBytesType::deserialize(reader));
return true;
}
return ContainerComponent::deserialize(propertyKey, reader);
diff --git a/include/rive/shapes/mesh.hpp b/include/rive/shapes/mesh.hpp
index ee3b0f2..1b531e5 100644
--- a/include/rive/shapes/mesh.hpp
+++ b/include/rive/shapes/mesh.hpp
@@ -12,7 +12,8 @@
StatusCode onAddedDirty(CoreContext* context) override;
void markDrawableDirty();
void addVertex(MeshVertex* vertex);
-
+ void decodeTriangleIndexBytes(std::vector<uint8_t> value) override;
+ void copyTriangleIndexBytes(const MeshBase& object) override;
#ifdef TESTING
std::vector<MeshVertex*>& vertices() { return m_Vertices; }
#endif
diff --git a/src/shapes/mesh.cpp b/src/shapes/mesh.cpp
index 207410c..e84b27e 100644
--- a/src/shapes/mesh.cpp
+++ b/src/shapes/mesh.cpp
@@ -21,4 +21,12 @@
parent()->as<Image>()->setMesh(this);
return StatusCode::Ok;
+}
+
+void Mesh::decodeTriangleIndexBytes(std::vector<uint8_t> value) {
+ // decode the triangle index bytes
+}
+
+void Mesh::copyTriangleIndexBytes(const MeshBase& object) {
+ // copy the triangle indices from object
}
\ No newline at end of file