| Index: src/record/SkRecord.h
|
| diff --git a/src/record/SkRecord.h b/src/record/SkRecord.h
|
| index ddf1b3d95fabaf927c45bd7152263699f67a7097..b1e4ae24f8da69b5e60aecad189573dbd448c9fd 100644
|
| --- a/src/record/SkRecord.h
|
| +++ b/src/record/SkRecord.h
|
| @@ -82,20 +82,31 @@ public:
|
|
|
| // Replace the i-th command with a new command of type T.
|
| // You are expected to placement new an object of type T onto this pointer.
|
| - // References to the old command remain valid for the life of the SkRecord, but
|
| - // you must destroy the old command. (It's okay to destroy it first before calling replace.)
|
| + // References to the original command are invalidated.
|
| template <typename T>
|
| T* replace(unsigned i) {
|
| SkASSERT(i < this->count());
|
| +
|
| + Destroyer destroyer;
|
| + this->mutate(i, destroyer);
|
| +
|
| fTypes[i] = T::kType;
|
| return fRecords[i].set(this->alloc<T>());
|
| }
|
|
|
| - // A mutator that can be used with replace to destroy canvas commands.
|
| - struct Destroyer {
|
| - template <typename T>
|
| - void operator()(T* record) { record->~T(); }
|
| - };
|
| + // Replace the i-th command with a new command of type T.
|
| + // You are expected to placement new an object of type T onto this pointer.
|
| + // You must show proof that you've already adopted the existing command.
|
| + template <typename T, typename Existing>
|
| + T* replace(unsigned i, const SkRecords::Adopted<Existing>& proofOfAdoption) {
|
| + SkASSERT(i < this->count());
|
| +
|
| + SkASSERT(Existing::kType == fTypes[i]);
|
| + SkASSERT(proofOfAdoption == fRecords[i].ptr<Existing>());
|
| +
|
| + fTypes[i] = T::kType;
|
| + return fRecords[i].set(this->alloc<T>());
|
| + }
|
|
|
| private:
|
| // Implementation notes!
|
| @@ -134,6 +145,11 @@ private:
|
| //
|
| // The cost to append a T into this structure is 1 + sizeof(void*) + sizeof(T).
|
|
|
| + // A mutator that can be used with replace to destroy canvas commands.
|
| + struct Destroyer {
|
| + template <typename T>
|
| + void operator()(T* record) { record->~T(); }
|
| + };
|
|
|
| // Logically the same as SkRecords::Type, but packed into 8 bits.
|
| struct Type8 {
|
| @@ -157,6 +173,10 @@ private:
|
| return ptr;
|
| }
|
|
|
| + // Get the data in fAlloc, assuming it's of type T.
|
| + template <typename T>
|
| + T* ptr() const { return (T*)fPtr; }
|
| +
|
| // Visit this record with functor F (see public API above) assuming the record we're
|
| // pointing to has this type.
|
| template <typename F>
|
| @@ -176,9 +196,6 @@ private:
|
| }
|
|
|
| private:
|
| - template <typename T>
|
| - T* ptr() const { return (T*)fPtr; }
|
| -
|
| void* fPtr;
|
| };
|
|
|
|
|