skia2/tests/FlattenableCustomFactory.cpp
msarett a3b3b238f5 Enable flattening/unflattening with custom unflatten procs
Now flattenables are serialized using a string name, so that
flattenables do not necessarily need to be registered before
serialization.  They just need to override getTypeName().

Allows custom unflatten procs to be set on the SkReadBuffer.
This is optional if the flattenable is registered, but otherwise
must be called.

This was split off from:
https://codereview.chromium.org/1837913003/

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1858323002

Review URL: https://codereview.chromium.org/1858323002
2016-04-22 12:43:07 -07:00

96 lines
3.1 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkFlattenable.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "Test.h"
class IntFlattenable : public SkFlattenable {
public:
IntFlattenable(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
: fA(a)
, fB(b)
, fC(c)
, fD(d)
{}
void flatten(SkWriteBuffer& buffer) const override {
buffer.writeUInt(fA);
buffer.writeUInt(fB);
buffer.writeUInt(fC);
buffer.writeUInt(fD);
}
Factory getFactory() const override { return nullptr; }
uint32_t a() const { return fA; }
uint32_t b() const { return fB; }
uint32_t c() const { return fC; }
uint32_t d() const { return fD; }
const char* getTypeName() const override { return "IntFlattenable"; }
private:
uint32_t fA;
uint32_t fB;
uint32_t fC;
uint32_t fD;
};
static sk_sp<SkFlattenable> custom_create_proc(SkReadBuffer& buffer) {
uint32_t a = buffer.readUInt();
uint32_t b = buffer.readUInt();
uint32_t c = buffer.readUInt();
uint32_t d = buffer.readUInt();
return sk_sp<SkFlattenable>(new IntFlattenable(a + 1, b + 1, c + 1, d + 1));
}
DEF_TEST(UnflattenWithCustomFactory, r) {
// Create and flatten the test flattenable
SkWriteBuffer writeBuffer;
SkAutoTUnref<SkFlattenable> flattenable1(new IntFlattenable(1, 2, 3, 4));
writeBuffer.writeFlattenable(flattenable1);
SkAutoTUnref<SkFlattenable> flattenable2(new IntFlattenable(2, 3, 4, 5));
writeBuffer.writeFlattenable(flattenable2);
SkAutoTUnref<SkFlattenable> flattenable3(new IntFlattenable(3, 4, 5, 6));
writeBuffer.writeFlattenable(flattenable3);
// Copy the contents of the write buffer into a read buffer
sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
writeBuffer.writeToMemory(data->writable_data());
SkReadBuffer readBuffer(data->data(), data->size());
// Register a custom factory with the read buffer
readBuffer.setCustomFactory(SkString("IntFlattenable"), &custom_create_proc);
// Unflatten and verify the flattenables
SkAutoTUnref<IntFlattenable> out1((IntFlattenable*) readBuffer.readFlattenable(
SkFlattenable::kSkUnused_Type));
REPORTER_ASSERT(r, out1);
REPORTER_ASSERT(r, 2 == out1->a());
REPORTER_ASSERT(r, 3 == out1->b());
REPORTER_ASSERT(r, 4 == out1->c());
REPORTER_ASSERT(r, 5 == out1->d());
SkAutoTUnref<IntFlattenable> out2((IntFlattenable*) readBuffer.readFlattenable(
SkFlattenable::kSkUnused_Type));
REPORTER_ASSERT(r, out2);
REPORTER_ASSERT(r, 3 == out2->a());
REPORTER_ASSERT(r, 4 == out2->b());
REPORTER_ASSERT(r, 5 == out2->c());
REPORTER_ASSERT(r, 6 == out2->d());
SkAutoTUnref<IntFlattenable> out3((IntFlattenable*) readBuffer.readFlattenable(
SkFlattenable::kSkUnused_Type));
REPORTER_ASSERT(r, out3);
REPORTER_ASSERT(r, 4 == out3->a());
REPORTER_ASSERT(r, 5 == out3->b());
REPORTER_ASSERT(r, 6 == out3->c());
REPORTER_ASSERT(r, 7 == out3->d());
}