Skip to content

Commit

Permalink
ditch layers
Browse files Browse the repository at this point in the history
  • Loading branch information
renancaraujo committed Nov 16, 2024
1 parent 6c94d50 commit 17ef3fd
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 120 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import 'dart:convert';

import 'package:binarize/binarize.dart'
show ByteData, Bytes, Payload, PayloadType, binarize, uint8;
show ByteData, PayloadType, binarize;
import 'package:mesh/mesh.dart';
import 'package:mesh/src/hash/binary_payload/omesh_payload_type.dart';
import 'package:mesh/src/hash/binary_payload/omesh_rect_payload.dart';

typedef OMeshBinaryFormat = ({
int specVersion,
int layerCount,
List<(MeshType, OMeshRect)> layers,
OMeshRect mesh,
});

class OMeshBinaryFormatPayloadType extends PayloadType<OMeshBinaryFormat> {
Expand All @@ -22,92 +21,26 @@ class OMeshBinaryFormatPayloadType extends PayloadType<OMeshBinaryFormat> {
OMeshBinaryFormat get(ByteData data, int offset) {
final o = ByteOffset(offset);

final value = data.getUint8(o.displace(1));

/// first 3 bits are reserved for the spec version.
/// next 3 bits are reserved for the layer count.
final specVersion = value >> 5;
final layerCount = (value >> 2) & 0x7;

final layers = List.generate(
layerCount,
(_) => _LayerInfoPayloadType.instance.get(data, o),
);
final specVersion = data.getUint8(o.displace(1));

final mesh = OMeshRectPayloadType.instance.get(data, o);
return (
specVersion: specVersion,
layerCount: layerCount,
layers: layers,
mesh: mesh,
);
}



@override
int length(OMeshBinaryFormat value) {
const metadataLength = 1;
final layersLength = value.layers.fold<int>(
0,
(previousValue, element) =>
previousValue + _LayerInfoPayloadType.instance.length(element),
);

return metadataLength + layersLength;
final meshLength = OMeshRectPayloadType.instance.length(value.mesh);
return metadataLength + meshLength;
}

@override
void set(OMeshBinaryFormat value, ByteData data, int offset) {
final o = ByteOffset(offset);

/// first 3 bits are reserved for the spec version.
/// next 3 bits are reserved for the layer count.
var v = value.specVersion << 5;
v |= value.layerCount << 2;

data.setUint8(o.displace(1), v);

for (var i = 0; i < value.layers.length; i++) {
_LayerInfoPayloadType.instance.set(value.layers[i], data, o);
}
}
}

enum MeshType {
rect,
}

class _LayerInfoPayloadType extends OMeshPayloadType<(MeshType, OMeshRect)> {
const _LayerInfoPayloadType._();

static const _LayerInfoPayloadType instance = _LayerInfoPayloadType._();

@override
(MeshType, OMeshRect) get(ByteData data, ByteOffset o) {
final typeInfo = data.getUint8(o.displace(1));
final type = MeshType.values[typeInfo];

final mesh = type == MeshType.rect
? OMeshRectPayloadType.instance.get(data, o)
: throw UnimplementedError();

return (type, mesh);
}

@override
int length((MeshType, OMeshRect) value) {
const typeLength = 1;
final meshLength = OMeshRectPayloadType.instance.length(value.$2);
return typeLength + meshLength;
}

@override
void set((MeshType, OMeshRect) value, ByteData data, ByteOffset o) {
data.setUint8(o.displace(1), value.$1.index);
// ignore: unnecessary_type_check
if (value.$2 is OMeshRect) {
OMeshRectPayloadType.instance.set(value.$2, data, o);
} else {
throw UnimplementedError();
}
data.setUint8(o.displace(1), value.specVersion);
OMeshRectPayloadType.instance.set(value.mesh, data, o);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class OMeshRectPayloadType extends OMeshPayloadType<OMeshRect> {
previousValue + OVertexPayloadType.instance.length(element),
);
final colorsLength =
ColorListPayloadType(value.height * value.height).length(value.colors);
ColorListPayloadType(value.width * value.height).length(value.colors);

final metadataLength = _OMeshRectMetadataPayloadType.instance.length(
(
Expand Down
19 changes: 9 additions & 10 deletions flutter/mesh/lib/src/hash/omesh_codec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'package:mesh/src/hash/binary_payload/omesh_binary_format_payload.dart'
export 'package:mesh/src/hash/binary_payload/omesh_binary_format_payload.dart'
show MeshType, OMeshBinaryFormat, OMeshBinaryFormatPayloadType;

class OMeshBinaryFormatCodec extends Codec<List<OMeshRect>, Uint8List> {
class OMeshBinaryFormatCodec extends Codec<OMeshRect, Uint8List> {
const OMeshBinaryFormatCodec._({
required this.specVersion,
});
Expand All @@ -20,38 +20,37 @@ class OMeshBinaryFormatCodec extends Codec<List<OMeshRect>, Uint8List> {
final int specVersion;

@override
Converter<Uint8List, List<OMeshRect>> get decoder =>
Converter<Uint8List, OMeshRect> get decoder =>
_OMeshBinaryFormatDecoder();

@override
Converter<List<OMeshRect>, Uint8List> get encoder =>
Converter<OMeshRect, Uint8List> get encoder =>
_OMeshBinaryFormatEncoder(
specVersion: specVersion,
);
}

class _OMeshBinaryFormatDecoder extends Converter<Uint8List, List<OMeshRect>> {
class _OMeshBinaryFormatDecoder extends Converter<Uint8List, OMeshRect> {
@override
List<OMeshRect> convert(Uint8List input) {
OMeshRect convert(Uint8List input) {
final reader = Payload.read(input);
final format = reader.get(OMeshBinaryFormatPayloadType.instance);
return format.layers.map((e) => e.$2).toList();
return format.mesh;
}
}

class _OMeshBinaryFormatEncoder extends Converter<List<OMeshRect>, Uint8List> {
class _OMeshBinaryFormatEncoder extends Converter<OMeshRect, Uint8List> {
_OMeshBinaryFormatEncoder({
required this.specVersion,
});

final int specVersion;

@override
Uint8List convert(List<OMeshRect> input) {
Uint8List convert(OMeshRect input) {
final format = (
specVersion: specVersion,
layerCount: input.length,
layers: input.map((e) => (MeshType.rect, e)).toList(),
mesh: input,
);

final writer = Payload.write()
Expand Down
14 changes: 6 additions & 8 deletions flutter/mesh/lib/src/hash/omesh_hash.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,18 @@ import 'package:mesh/mesh.dart';
import 'package:mesh/src/hash/compression/zlib/zlib.dart' as zlib;
import 'package:mesh/src/hash/omesh_codec.dart';

const _kPrefix = 'OM';
const _kPrefix = 'O';

String getHashFromMesh(List<OMeshRect> mesh) {
String getHashFromMesh(OMeshRect mesh) {
final bytes = OMeshBinaryFormatCodec.v1.encoder.convert(mesh);
final compressed = zlib.zlibCompress(Uint8List.fromList(bytes));
final hash = base64Url.encode(compressed);
final unpaded = _removePadding(hash);
final unpaded = _removePadding(hash);
final prefixed = '$_kPrefix$unpaded';
return prefixed;
}


List<OMeshRect> getMeshFromHash(String hash) {
OMeshRect getMeshFromHash(String hash) {
final unprefixied = hash.substring(_kPrefix.length);
final paddedHash = _addPadding(unprefixied);
final compressed = base64Url.decode(paddedHash);
Expand All @@ -28,14 +27,13 @@ List<OMeshRect> getMeshFromHash(String hash) {
return layers;
}


String _removePadding(String base64String) {
// Remove trailing '=' characters
return base64String.replaceAll(RegExp(r'=+$'), '');
}

String _addPadding(String base64String) {
// Calculate the padding needed to make the length a multiple of 4
// Calculate the padding needed to make the length a multiple of 4
int paddingNeeded = (4 - base64String.length % 4) % 4;
return base64String + ('=' * paddingNeeded);
}
}
1 change: 1 addition & 0 deletions flutter/mesh/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ environment:

dependencies:
archive: ^3.6.1
base_x: ^2.0.1
binarize: ^1.5.0
cached_value: ^1.0.0
flutter:
Expand Down
65 changes: 40 additions & 25 deletions flutter/mesh/test/src/hash/omesh_hash_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ void main() {
],
);

final hash = getHashFromMesh([verySimpleOMesh]);
print('hash: $hash');

expect(
hash,
equals(
'''
eJxj8vdVYVBiQAf2HzCE0CRgDLgAI4Pb5JX_GRgZGJkZAA45CCg''',
),
);
final hash = getHashFromMesh(verySimpleOMesh);
print('hash: $hash ${hash.length}');

// expect(
// hash,
// equals(
// '''
// eJxj8vdVYVBiQAf2HzCE0CRgDLgAI4Pb5JX_GRgZGJkZAA45CCg''',
// ),
// );

final mesh = getMeshFromHash(hash);

expect(mesh, [verySimpleOMesh]);
expect(mesh, verySimpleOMesh);
});

test('encodes and decodes a simple mesh', () {
Expand Down Expand Up @@ -66,23 +66,23 @@ eJxj8vdVYVBiQAf2HzCE0CRgDLgAI4Pb5JX_GRgZGJkZAA45CCg''',
],
);

final hash = getHashFromMesh([simpleOMesh]);
print(hash);
final hash = getHashFromMesh(simpleOMesh);
print('hash: $hash ${hash.length}');

expect(
hash,
equals(
'''
eJxj8vdlZGRgZt6_bkfg61a5Hfu3VD10XydSzWD_qD9G4-uh_v0rZ4LALAb7r4dAIoftl0BV7J8CYdhfvs5lW7D4OoP9HZCGGE37JxCawf4jVMtNqBn7W6BaPsBUQBn2HxggwP4D2BlB9s_BtscwMHAyMCzVzvjPwOg2eeV_BiYwybxUe8F_BpYXt678Z2AFi7BNF135n4EdzOYAkcwMAM0AYso=''',
),
);
// expect(
// hash,
// equals(
// '''
// eJxj8vdlZGRgZt6_bkfg61a5Hfu3VD10XydSzWD_qD9G4-uh_v0rZ4LALAb7r4dAIoftl0BV7J8CYdhfvs5lW7D4OoP9HZCGGE37JxCawf4jVMtNqBn7W6BaPsBUQBn2HxggwP4D2BlB9s_BtscwMHAyMCzVzvjPwOg2eeV_BiYwybxUe8F_BpYXt678Z2AFi7BNF135n4EdzOYAkcwMAM0AYso=''',
// ),
// );

final mesh = getMeshFromHash(hash);

expect(mesh, [simpleOMesh]);
expect(mesh, simpleOMesh);
});

test('', () {
test('encodes and decodes a custom mesh', () {
final meshRect = OMeshRect(
width: 5,
height: 4,
Expand Down Expand Up @@ -130,6 +130,21 @@ eJxj8vdlZGRgZt6_bkfg61a5Hfu3VD10XydSzWD_qD9G4-uh_v0rZ4LALAb7r4dAIoftl0BV7J8CYdhf
Color(0xffde9a9a), Color(0xffde9a9a), // Row 4
],
);

final hash = getHashFromMesh(meshRect);
print('hash: $hash ${hash.length}');

// expect(
// hash,
// equals(
// '''
// eJxj8vdlZGRgZt6_bkfg61a5Hfu3VD10XydSzWD_qD9G4-uh_v0rZ4LALAb7r4dAIoftl0BV7J8CYdhfvs5lW7D4OoP9HZCGGE37JxCawf4jVMtNqBn7W6BaPsBUQBn2HxggwP4D2BlB9s_BtscwMHAyMCzVzvjPwOg2eeV_BiYwybxUe8F_BpYXt678Z2AFi7BNF135n4EdzOYAkcwMAM0AYso=''',
// ),
// );

final mesh = getMeshFromHash(hash);

expect(mesh, meshRect);
});

test('encodes and decodes a complex mesh', () {
Expand Down Expand Up @@ -219,8 +234,8 @@ eJxj8vdlZGRgZt6_bkfg61a5Hfu3VD10XydSzWD_qD9G4-uh_v0rZ4LALAb7r4dAIoftl0BV7J8CYdhf
],
);

final hash = getHashFromMesh([complexOMesh]);
print(hash.length);
final hash = getHashFromMesh(complexOMesh);
print('hash: $hash ${hash.length}');

// expect(
// hash,
Expand All @@ -232,6 +247,6 @@ eJxj8vdlZGRgZt6_bkfg61a5Hfu3VD10XydSzWD_qD9G4-uh_v0rZ4LALAb7r4dAIoftl0BV7J8CYdhf

final mesh = getMeshFromHash(hash);

expect(mesh, [complexOMesh]);
expect(mesh, complexOMesh);
});
}

0 comments on commit 17ef3fd

Please sign in to comment.