aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/record/SkRecord.h33
-rw-r--r--src/record/SkRecordDraw.cpp2
-rw-r--r--src/record/SkRecordOpts.cpp2
-rw-r--r--src/record/SkRecordPattern.h34
-rw-r--r--tests/RecordOptsTest.cpp17
-rw-r--r--tests/RecordTest.cpp19
-rw-r--r--tests/RecorderTest.cpp2
-rw-r--r--tools/dump_record.cpp2
8 files changed, 53 insertions, 58 deletions
diff --git a/src/record/SkRecord.h b/src/record/SkRecord.h
index 068155e47f..6c5177eefb 100644
--- a/src/record/SkRecord.h
+++ b/src/record/SkRecord.h
@@ -33,7 +33,7 @@ public:
~SkRecord() {
Destroyer destroyer;
for (unsigned i = 0; i < this->count(); i++) {
- this->mutate(i, destroyer);
+ this->mutate<void>(i, destroyer);
}
}
@@ -42,23 +42,24 @@ public:
// Visit the i-th canvas command with a functor matching this interface:
// template <typename T>
- // void operator()(const T& record) { ... }
+ // R operator()(const T& record) { ... }
// This operator() must be defined for at least all SkRecords::*.
- template <typename F>
- void visit(unsigned i, F& f) const {
+ template <typename R, typename F>
+ R visit(unsigned i, F& f) const {
SkASSERT(i < this->count());
- fRecords[i].visit(fTypes[i], f);
+ return fRecords[i].visit<R>(fTypes[i], f);
}
// Mutate the i-th canvas command with a functor matching this interface:
// template <typename T>
- // void operator()(T* record) { ... }
+ // R operator()(T* record) { ... }
// This operator() must be defined for at least all SkRecords::*.
- template <typename F>
- void mutate(unsigned i, F& f) {
+ template <typename R, typename F>
+ R mutate(unsigned i, F& f) {
SkASSERT(i < this->count());
- fRecords[i].mutate(fTypes[i], f);
+ return fRecords[i].mutate<R>(fTypes[i], f);
}
+ // TODO: It'd be nice to infer R from F for visit and mutate if we ever get std::result_of.
// Allocate contiguous space for count Ts, to be freed when the SkRecord is destroyed.
// Here T can be any class, not just those from SkRecords. Throws on failure.
@@ -89,7 +90,7 @@ public:
SkASSERT(i < this->count());
Destroyer destroyer;
- this->mutate(i, destroyer);
+ this->mutate<void>(i, destroyer);
fTypes[i] = T::kType;
return fRecords[i].set(this->allocCommand<T>());
@@ -191,20 +192,24 @@ private:
// Visit this record with functor F (see public API above) assuming the record we're
// pointing to has this type.
- template <typename F>
- void visit(Type8 type, F& f) const {
+ template <typename R, typename F>
+ R visit(Type8 type, F& f) const {
#define CASE(T) case SkRecords::T##_Type: return f(*this->ptr<SkRecords::T>());
switch(type) { SK_RECORD_TYPES(CASE) }
#undef CASE
+ SkDEBUGFAIL("Unreachable");
+ return R();
}
// Mutate this record with functor F (see public API above) assuming the record we're
// pointing to has this type.
- template <typename F>
- void mutate(Type8 type, F& f) {
+ template <typename R, typename F>
+ R mutate(Type8 type, F& f) {
#define CASE(T) case SkRecords::T##_Type: return f(this->ptr<SkRecords::T>());
switch(type) { SK_RECORD_TYPES(CASE) }
#undef CASE
+ SkDEBUGFAIL("Unreachable");
+ return R();
}
private:
diff --git a/src/record/SkRecordDraw.cpp b/src/record/SkRecordDraw.cpp
index 4878b3f4f6..666cfc9000 100644
--- a/src/record/SkRecordDraw.cpp
+++ b/src/record/SkRecordDraw.cpp
@@ -94,6 +94,6 @@ template <> void Draw::draw(const SkRecords::BoundedDrawPosTextH& r) { this->dra
void SkRecordDraw(const SkRecord& record, SkCanvas* canvas) {
for (Draw draw(canvas); draw.index() < record.count(); draw.next()) {
- record.visit(draw.index(), draw);
+ record.visit<void>(draw.index(), draw);
}
}
diff --git a/src/record/SkRecordOpts.cpp b/src/record/SkRecordOpts.cpp
index d855124917..c58a034fa7 100644
--- a/src/record/SkRecordOpts.cpp
+++ b/src/record/SkRecordOpts.cpp
@@ -264,7 +264,7 @@ public:
void apply(SkRecord* record) {
for (fRecord = record, fIndex = 0; fIndex < record->count(); fIndex++) {
- fRecord->mutate(fIndex, *this);
+ fRecord->mutate<void>(fIndex, *this);
}
}
diff --git a/src/record/SkRecordPattern.h b/src/record/SkRecordPattern.h
index c5d87f2a20..b1334a87c6 100644
--- a/src/record/SkRecordPattern.h
+++ b/src/record/SkRecordPattern.h
@@ -17,13 +17,13 @@ public:
typedef T type;
type* get() { return fPtr; }
- bool match(T* ptr) {
+ bool operator()(T* ptr) {
fPtr = ptr;
return true;
}
template <typename U>
- bool match(U*) {
+ bool operator()(U*) {
fPtr = NULL;
return false;
}
@@ -42,19 +42,19 @@ public:
type* get() { return fPaint; }
template <typename T>
- SK_WHEN(HasMember_paint<T>, bool) match(T* draw) {
+ SK_WHEN(HasMember_paint<T>, bool) operator()(T* draw) {
fPaint = AsPtr(draw->paint);
return true;
}
template <typename T>
- SK_WHEN(!HasMember_paint<T>, bool) match(T*) {
+ SK_WHEN(!HasMember_paint<T>, bool) operator()(T*) {
fPaint = NULL;
return false;
}
// SaveLayer has an SkPaint named paint, but it's not a draw.
- bool match(SaveLayer*) {
+ bool operator()(SaveLayer*) {
fPaint = NULL;
return false;
}
@@ -71,14 +71,14 @@ private:
template <typename Matcher>
struct Not {
template <typename T>
- bool match(T* ptr) { return !Matcher().match(ptr); }
+ bool operator()(T* ptr) { return !Matcher()(ptr); }
};
// Matches if either of A or B does. Stores nothing.
template <typename A, typename B>
struct Or {
template <typename T>
- bool match(T* ptr) { return A().match(ptr) || B().match(ptr); }
+ bool operator()(T* ptr) { return A()(ptr) || B()(ptr); }
};
// Matches if any of A, B or C does. Stores nothing.
@@ -96,7 +96,7 @@ public:
void reset() {}
template <typename T>
- bool match(T* ptr) { return Matcher().match(ptr); }
+ bool operator()(T* ptr) { return Matcher()(ptr); }
};
// This version stores a list of matches. It's enabled if Matcher stores something.
@@ -109,9 +109,9 @@ public:
void reset() { fMatches.rewind(); }
template <typename T>
- bool match(T* ptr) {
+ bool operator()(T* ptr) {
Matcher matcher;
- if (matcher.match(ptr)) {
+ if (matcher(ptr)) {
fMatches.push(matcher.get());
return true;
}
@@ -161,16 +161,11 @@ public:
template <typename T> T* third() { return fTail.fTail.fHead.get(); }
private:
- template <typename T>
- void operator()(T* r) { fHeadMatched = fHead.match(r); }
-
// If head isn't a Star, try to match at i once.
template <typename T>
unsigned matchHead(T*, SkRecord* record, unsigned i) {
if (i < record->count()) {
- fHeadMatched = false;
- record->mutate(i, *this);
- if (fHeadMatched) {
+ if (record->mutate<bool>(i, fHead)) {
return i+1;
}
}
@@ -182,9 +177,7 @@ private:
unsigned matchHead(Star<T>*, SkRecord* record, unsigned i) {
fHead.reset();
while (i < record->count()) {
- fHeadMatched = false;
- record->mutate(i, *this);
- if (!fHeadMatched) {
+ if (!record->mutate<bool>(i, fHead)) {
return i;
}
i++;
@@ -194,9 +187,6 @@ private:
Matcher fHead;
Pattern fTail;
- bool fHeadMatched;
-
- friend class ::SkRecord; // So operator() can otherwise stay private.
// All Cons are friends with each other. This lets first, second, and third work.
template <typename, typename> friend class Cons;
diff --git a/tests/RecordOptsTest.cpp b/tests/RecordOptsTest.cpp
index 33142c8a3d..c427c25119 100644
--- a/tests/RecordOptsTest.cpp
+++ b/tests/RecordOptsTest.cpp
@@ -19,26 +19,25 @@ static const int W = 1920, H = 1080;
// If the command we're reading is a U, set ptr to it, otherwise set it to NULL.
template <typename U>
struct ReadAs {
- explicit ReadAs(const U** ptr) : ptr(ptr), type(SkRecords::Type(~0)) {}
+ ReadAs() : ptr(NULL), type(SkRecords::Type(~0)) {}
- const U** ptr;
+ const U* ptr;
SkRecords::Type type;
- void operator()(const U& r) { *ptr = &r; type = U::kType; }
+ void operator()(const U& r) { ptr = &r; type = U::kType; }
template <typename T>
- void operator()(const T&) { *ptr = NULL; type = U::kType; }
+ void operator()(const T&) { type = U::kType; }
};
// Assert that the ith command in record is of type T, and return it.
template <typename T>
static const T* assert_type(skiatest::Reporter* r, const SkRecord& record, unsigned index) {
- const T* ptr = NULL;
- ReadAs<T> reader(&ptr);
- record.visit(index, reader);
+ ReadAs<T> reader;
+ record.visit<void>(index, reader);
REPORTER_ASSERT(r, T::kType == reader.type);
- REPORTER_ASSERT(r, ptr != NULL);
- return ptr;
+ REPORTER_ASSERT(r, NULL != reader.ptr);
+ return reader.ptr;
}
DEF_TEST(RecordOpts_Culling, r) {
diff --git a/tests/RecordTest.cpp b/tests/RecordTest.cpp
index e58ef10dda..9238d97aa7 100644
--- a/tests/RecordTest.cpp
+++ b/tests/RecordTest.cpp
@@ -17,35 +17,36 @@ public:
template <typename T> void operator()(const T&) { }
+ void operator()(const SkRecords::DrawRect& draw) {
+ fArea += (int)(draw.rect.width() * draw.rect.height());
+ }
+
int area() const { return fArea; }
void apply(const SkRecord& record) {
for (unsigned i = 0; i < record.count(); i++) {
- record.visit(i, *this);
+ record.visit<void>(i, *this);
}
}
private:
int fArea;
};
-template <> void AreaSummer::operator()(const SkRecords::DrawRect& record) {
- fArea += (int) (record.rect.width() * record.rect.height());
-}
// Scales out the bottom-right corner of any DrawRect command it sees by 2x.
struct Stretch {
template <typename T> void operator()(T*) {}
+ void operator()(SkRecords::DrawRect* draw) {
+ draw->rect.fRight *= 2;
+ draw->rect.fBottom *= 2;
+ }
void apply(SkRecord* record) {
for (unsigned i = 0; i < record->count(); i++) {
- record->mutate(i, *this);
+ record->mutate<void>(i, *this);
}
}
};
-template <> void Stretch::operator()(SkRecords::DrawRect* record) {
- record->rect.fRight *= 2;
- record->rect.fBottom *= 2;
-}
// Basic tests for the low-level SkRecord code.
DEF_TEST(Record, r) {
diff --git a/tests/RecorderTest.cpp b/tests/RecorderTest.cpp
index 407cf9add0..8fa198cd6d 100644
--- a/tests/RecorderTest.cpp
+++ b/tests/RecorderTest.cpp
@@ -30,7 +30,7 @@ public:
void apply(const SkRecord& record) {
for (unsigned i = 0; i < record.count(); i++) {
- record.visit(i, *this);
+ record.visit<void>(i, *this);
}
}
diff --git a/tools/dump_record.cpp b/tools/dump_record.cpp
index 8691155525..b427a81d61 100644
--- a/tools/dump_record.cpp
+++ b/tools/dump_record.cpp
@@ -84,7 +84,7 @@ static void dump(const char* name, const SkRecord& record) {
printf("%s %s\n", FLAGS_optimize ? "optimized" : "not-optimized", name);
for (unsigned i = 0; i < record.count(); i++) {
printf("%*d ", digits, i);
- record.visit(i, dumper);
+ record.visit<void>(i, dumper);
}
}