Index: include/core/SkFlattenable.h |
diff --git a/include/core/SkFlattenable.h b/include/core/SkFlattenable.h |
index 58e69fd416cb049b56d881942f6f77ebb676e93d..ec0242eb403cd88e187a5dfaac3e416ec5dfbe5e 100644 |
--- a/include/core/SkFlattenable.h |
+++ b/include/core/SkFlattenable.h |
@@ -16,7 +16,7 @@ class SkFlattenableReadBuffer; |
class SkFlattenableWriteBuffer; |
#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ |
- SkFlattenable::Registrar(#flattenable, flattenable::CreateProc); |
+ SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, flattenable::IsA); |
#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); |
@@ -29,11 +29,34 @@ class SkFlattenableWriteBuffer; |
#define SK_DECLARE_UNFLATTENABLE_OBJECT() \ |
virtual Factory getFactory() SK_OVERRIDE { return NULL; } |
-#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
+/** For SkFlattenable derived objects with a valid type |
+ This macros would typically be used by virtual classes, which need a type, but can't |
+ be constructed or serialized directly without going through a derived class |
+ */ |
+#define SK_DEFINE_FLATTENABLE_TYPE_CHECKING_PROCS(flattenable) \ |
+ static const char* GetTypeName() { \ |
+ return #flattenable; \ |
+ } \ |
+ static bool IsA(const char* name) { \ |
+ return (strcmp(flattenable::GetTypeName(), name) == 0) || INHERITED::IsA(name); \ |
+ } \ |
+ virtual const char* getTypeName() SK_OVERRIDE { \ |
+ return flattenable::GetTypeName(); \ |
+ } |
+ |
+/** For SkFlattenable derived classes defined within the skia library |
+ */ |
+#define SK_DEFINE_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } \ |
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \ |
return SkNEW_ARGS(flattenable, (buffer)); \ |
- } |
+ } \ |
+ SK_DEFINE_FLATTENABLE_TYPE_CHECKING_PROCS(flattenable) |
+ |
+/** Deprecated, remove once noone is using it anymore |
+ */ |
+#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ |
+ SK_DEFINE_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) |
/** \class SkFlattenable |
@@ -43,9 +66,11 @@ class SkFlattenableWriteBuffer; |
*/ |
class SK_API SkFlattenable : public SkRefCnt { |
public: |
+ |
SK_DECLARE_INST_COUNT(SkFlattenable) |
typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&); |
+ typedef bool (*TypeCheck)(const char*); |
SkFlattenable() {} |
@@ -57,12 +82,44 @@ public: |
static Factory NameToFactory(const char name[]); |
static const char* FactoryToName(Factory); |
- static void Register(const char name[], Factory); |
+ |
+ static void Register(const char name[], Factory, TypeCheck); |
+ |
+ /** Returns the class id |
+ GetTypeName() methods on classes descending from SkFlattenable will return |
+ the name associated with that class, which is a stringified version of |
+ the class' name. Typically, SK_DEFINE_FLATTENABLE_TYPE_CHECKING_PROCS() |
+ will define GetTypeName(), getFlattenableType() and IsA() in the derived class. |
+ * Note that SK_DEFINE_FLATTENABLE_TYPE_CHECKING_PROCS() is included in |
+ SK_DEFINE_FLATTENABLE_DESERIALIZATION_PROCS(), so most classes will have |
+ these declared by default. |
+ */ |
+ static const char* GetTypeName() { return "SkFlattenable"; } |
+ |
+ /** Returns the name of the object's class |
+ */ |
+ virtual const char* getTypeName() = 0; |
+ |
+ /** Returns whether this class is itself or inherits from a class with this type name. |
+ * (SkFlattenable is the root of this type checking system.) |
+ */ |
+ static bool IsA(const char* name) { |
+ return strcmp(GetTypeName(), name) == 0; |
+ } |
+ |
+ /** Checks if typeA is a typeB |
+ * For example, if typeA is "SkImageFilter" and typeB is "SkFlattenable", this would return true |
+ * Inversely, if typeA is "SkFlattenable" and typeB is "SkImageFilter", this would return false |
+ */ |
+ static bool TypeIsA(const char* nameA, const char* nameB) { |
+ TypeCheck typeCheck = NameToTypeCheck(nameA); |
+ return typeCheck ? (*typeCheck)(nameB) : false; |
+ } |
class Registrar { |
public: |
- Registrar(const char name[], Factory factory) { |
- SkFlattenable::Register(name, factory); |
+ Registrar(const char name[], Factory factory, TypeCheck typeCheck) { |
+ SkFlattenable::Register(name, factory, typeCheck); |
} |
}; |
@@ -75,7 +132,8 @@ protected: |
virtual void flatten(SkFlattenableWriteBuffer&) const; |
private: |
- static void InitializeFlattenables(); |
+ static void InitializeFlattenablesIfNeeded(); |
+ static TypeCheck NameToTypeCheck(const char name[]); |
friend class SkGraphics; |
friend class SkFlattenableWriteBuffer; |