michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkMemberInfo_DEFINED michael@0: #define SkMemberInfo_DEFINED michael@0: michael@0: #if defined SK_BUILD_CONDENSED michael@0: #define SK_USE_CONDENSED_INFO 0 michael@0: #endif michael@0: michael@0: #include "SkDisplayType.h" michael@0: #include "SkScript.h" michael@0: #include "SkString.h" michael@0: #include "SkIntArray.h" michael@0: michael@0: class SkAnimateMaker; michael@0: class SkDisplayable; michael@0: class SkScriptEngine; michael@0: michael@0: // temporary hacks until name change is more complete michael@0: #define SkFloat SkScalar michael@0: #define SkInt SkS32 michael@0: michael@0: struct SkMemberInfo { michael@0: //!!! alternative: michael@0: // if fCount == 0, record is member property michael@0: // then fType can be type, so caller doesn't have to check michael@0: #if SK_USE_CONDENSED_INFO == 0 michael@0: const char* fName; // may be NULL for anonymous functions michael@0: size_t fOffset; // if negative, is index into member pointer table (for properties and functions) michael@0: SkDisplayTypes fType; michael@0: int fCount; // for properties, actual type (count is always assumed to be 1) michael@0: #else michael@0: unsigned char fName; michael@0: signed char fOffset; michael@0: unsigned char fType; michael@0: signed char fCount; michael@0: #endif michael@0: SkDisplayTypes arrayType() const { michael@0: SkASSERT(fType == SkType_Array); michael@0: return (SkDisplayTypes) fCount; // hack, but worth it? michael@0: } michael@0: int functionIndex() const { michael@0: SkASSERT(fType == SkType_MemberFunction); michael@0: return (signed) fOffset > 0 ? -1 + (int) fOffset : -1 - (int) fOffset; michael@0: } michael@0: bool getArrayValue(const SkDisplayable* displayable, int index, SkOperand* value) const; michael@0: int getCount() const { michael@0: return fType == SkType_MemberProperty || fType == SkType_Array || michael@0: fType == SkType_MemberFunction ? 1 : fCount; michael@0: } michael@0: const SkMemberInfo* getInherited() const; michael@0: size_t getSize(const SkDisplayable* ) const; michael@0: void getString(const SkDisplayable* , SkString** string) const; michael@0: SkDisplayTypes getType() const { michael@0: return fType == SkType_MemberProperty || fType == SkType_Array || michael@0: fType == SkType_MemberFunction ? (SkDisplayTypes) fCount : (SkDisplayTypes) fType; michael@0: } michael@0: void getValue(const SkDisplayable* , SkOperand values[], int count) const; michael@0: bool isEnum() const; michael@0: const char* mapEnums(const char* match, int* value) const; michael@0: void* memberData(const SkDisplayable* displayable) const { michael@0: SkASSERT(fType != SkType_MemberProperty && fType != SkType_MemberFunction); michael@0: return (void*) ((const char*) displayable + fOffset); michael@0: } michael@0: int propertyIndex() const { michael@0: SkASSERT(fType == SkType_MemberProperty); michael@0: return (signed) fOffset > 0 ? -1 + (int) fOffset : -1 - (int) fOffset; michael@0: } michael@0: SkDisplayTypes propertyType() const { michael@0: SkASSERT(fType == SkType_MemberProperty || fType == SkType_Array); michael@0: return (SkDisplayTypes) fCount; // hack, but worth it? michael@0: } michael@0: void setMemberData(SkDisplayable* displayable, const void* child, size_t size) const { michael@0: SkASSERT(fType != SkType_MemberProperty && fType != SkType_MemberFunction); michael@0: memcpy((char*) displayable + fOffset, child, size); michael@0: } michael@0: void setString(SkDisplayable* , SkString* ) const; michael@0: void setValue(SkDisplayable* , const SkOperand values[], int count) const; michael@0: bool setValue(SkAnimateMaker& , SkTDOperandArray* storage, michael@0: int storageOffset, int maxStorage, SkDisplayable* , michael@0: SkDisplayTypes outType, const char value[], size_t len) const; michael@0: bool setValue(SkAnimateMaker& , SkTDOperandArray* storage, michael@0: int storageOffset, int maxStorage, SkDisplayable* , michael@0: SkDisplayTypes outType, SkString& str) const; michael@0: // void setValue(SkDisplayable* , const char value[], const char name[]) const; michael@0: bool writeValue(SkDisplayable* displayable, SkTDOperandArray* arrayStorage, michael@0: int storageOffset, int maxStorage, void* untypedStorage, SkDisplayTypes outType, michael@0: SkScriptValue& scriptValue) const; michael@0: #if SK_USE_CONDENSED_INFO == 0 michael@0: static const SkMemberInfo* Find(const SkMemberInfo [], int count, int* index); michael@0: static const SkMemberInfo* Find(const SkMemberInfo [], int count, const char** name); michael@0: #else michael@0: static const SkMemberInfo* Find(SkDisplayTypes type, int* index); michael@0: static const SkMemberInfo* Find(SkDisplayTypes type, const char** name); michael@0: #endif michael@0: static size_t GetSize(SkDisplayTypes type); // size of simple types only michael@0: // static bool SetValue(void* value, const char* name, SkDisplayTypes , int count); michael@0: }; michael@0: michael@0: #define SK_MEMBER(_member, _type) \ michael@0: { #_member, SK_OFFSETOF(BASE_CLASS, _member), SkType_##_type, \ michael@0: sizeof(((BASE_CLASS*) 1)->_member) / sizeof(SkScalar) } michael@0: michael@0: #define SK_MEMBER_ALIAS(_member, _alias, _type) \ michael@0: { #_member, SK_OFFSETOF(BASE_CLASS, _alias), SkType_##_type, \ michael@0: sizeof(((BASE_CLASS*) 1)->_alias) / sizeof(SkScalar) } michael@0: michael@0: #define SK_MEMBER_ARRAY(_member, _type) \ michael@0: { #_member, SK_OFFSETOF(BASE_CLASS, _member), SkType_Array, \ michael@0: (int) SkType_##_type } michael@0: michael@0: #define SK_MEMBER_INHERITED \ michael@0: { (const char*) INHERITED::fInfo, 0, SkType_BaseClassInfo, INHERITED::fInfoCount } michael@0: michael@0: // #define SK_MEMBER_KEY_TYPE(_member, _type) michael@0: // {#_member, (size_t) -1, SkType_##_type, 0} michael@0: michael@0: #define SK_FUNCTION(_member) \ michael@0: k_##_member##Function michael@0: michael@0: #define SK_PROPERTY(_member) \ michael@0: k_##_member##Property michael@0: michael@0: #define SK_MEMBER_DYNAMIC_FUNCTION(_member, _type) \ michael@0: {#_member, (size_t) (+1 + SK_FUNCTION(_member)), SkType_MemberFunction, \ michael@0: (int) SkType_##_type } michael@0: michael@0: #define SK_MEMBER_DYNAMIC_PROPERTY(_member, _type) \ michael@0: {#_member, (size_t) (1 + SK_PROPERTY(_member)), SkType_MemberProperty, \ michael@0: (int) SkType_##_type } michael@0: michael@0: #define SK_MEMBER_FUNCTION(_member, _type) \ michael@0: {#_member, (size_t) (-1 - SK_FUNCTION(_member)), SkType_MemberFunction, \ michael@0: (int) SkType_##_type } michael@0: michael@0: #define SK_MEMBER_PROPERTY(_member, _type) \ michael@0: {#_member, (size_t) (-1 - SK_PROPERTY(_member)), SkType_MemberProperty, \ michael@0: (int) SkType_##_type } michael@0: michael@0: #if SK_USE_CONDENSED_INFO == 0 michael@0: michael@0: #define DECLARE_PRIVATE_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: static const SkMemberInfo fInfo[]; \ michael@0: static const int fInfoCount; \ michael@0: virtual const SkMemberInfo* getMember(int index); \ michael@0: virtual const SkMemberInfo* getMember(const char name[]); \ michael@0: typedef Sk##_type BASE_CLASS michael@0: michael@0: #define DECLARE_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: static const SkMemberInfo fInfo[]; \ michael@0: static const int fInfoCount; \ michael@0: virtual const SkMemberInfo* getMember(int index); \ michael@0: virtual const SkMemberInfo* getMember(const char name[]); \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } \ michael@0: typedef Sk##_type BASE_CLASS michael@0: michael@0: #define DECLARE_DRAW_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: static const SkMemberInfo fInfo[]; \ michael@0: static const int fInfoCount; \ michael@0: virtual const SkMemberInfo* getMember(int index); \ michael@0: virtual const SkMemberInfo* getMember(const char name[]); \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } \ michael@0: typedef SkDraw##_type BASE_CLASS michael@0: michael@0: #define DECLARE_DISPLAY_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: static const SkMemberInfo fInfo[]; \ michael@0: static const int fInfoCount; \ michael@0: virtual const SkMemberInfo* getMember(int index); \ michael@0: virtual const SkMemberInfo* getMember(const char name[]); \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } \ michael@0: typedef SkDisplay##_type BASE_CLASS michael@0: michael@0: #define DECLARE_EMPTY_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } michael@0: michael@0: #define DECLARE_EXTRAS_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: static const SkMemberInfo fInfo[]; \ michael@0: static const int fInfoCount; \ michael@0: virtual const SkMemberInfo* getMember(int index); \ michael@0: virtual const SkMemberInfo* getMember(const char name[]); \ michael@0: SkDisplayTypes fType; \ michael@0: virtual SkDisplayTypes getType() const { return fType; } \ michael@0: typedef _type BASE_CLASS michael@0: michael@0: #define DECLARE_NO_VIRTUALS_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: static const SkMemberInfo fInfo[]; \ michael@0: static const int fInfoCount; \ michael@0: typedef Sk##_type BASE_CLASS michael@0: michael@0: #define DEFINE_GET_MEMBER(_class) \ michael@0: const SkMemberInfo* _class::getMember(int index) { \ michael@0: const SkMemberInfo* result = SkMemberInfo::Find(fInfo, SK_ARRAY_COUNT(fInfo), &index); \ michael@0: return result; \ michael@0: } \ michael@0: const SkMemberInfo* _class::getMember(const char name[]) { \ michael@0: const SkMemberInfo* result = SkMemberInfo::Find(fInfo, SK_ARRAY_COUNT(fInfo), &name); \ michael@0: return result; \ michael@0: } \ michael@0: const int _class::fInfoCount = SK_ARRAY_COUNT(fInfo) michael@0: michael@0: #define DEFINE_NO_VIRTUALS_GET_MEMBER(_class) \ michael@0: const int _class::fInfoCount = SK_ARRAY_COUNT(fInfo) michael@0: michael@0: #else michael@0: michael@0: #define DECLARE_PRIVATE_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: typedef Sk##_type BASE_CLASS michael@0: michael@0: #define DECLARE_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: virtual const SkMemberInfo* getMember(int index) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \ michael@0: virtual const SkMemberInfo* getMember(const char name[]) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &name); } \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } \ michael@0: typedef Sk##_type BASE_CLASS michael@0: michael@0: #define DECLARE_DRAW_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: virtual const SkMemberInfo* getMember(int index) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \ michael@0: virtual const SkMemberInfo* getMember(const char name[]) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &name); } \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } \ michael@0: typedef SkDraw##_type BASE_CLASS michael@0: michael@0: #define DECLARE_DISPLAY_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: virtual const SkMemberInfo* getMember(int index) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \ michael@0: virtual const SkMemberInfo* getMember(const char name[]) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &name); } \ michael@0: virtual SkDisplayTypes getType() const { return SkType_##_type; } \ michael@0: typedef SkDisplay##_type BASE_CLASS michael@0: michael@0: #define DECLARE_EXTRAS_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: virtual const SkMemberInfo* getMember(int index) { \ michael@0: return SkDisplayType::GetMember(NULL, SkType_##_type, &index); } \ michael@0: virtual const SkMemberInfo* getMember(const char name[]) { \ michael@0: return SkDisplayType::GetMember(NULL, fType, &name); } \ michael@0: SkDisplayTypes fType; \ michael@0: virtual SkDisplayTypes getType() const { return fType; } \ michael@0: typedef _type BASE_CLASS michael@0: michael@0: #define DECLARE_NO_VIRTUALS_MEMBER_INFO(_type) \ michael@0: public: \ michael@0: typedef Sk##_type BASE_CLASS michael@0: michael@0: #define DEFINE_GET_MEMBER(_class) michael@0: #define DEFINE_NO_VIRTUALS_GET_MEMBER(_class) michael@0: michael@0: #endif michael@0: michael@0: #endif // SkMemberInfo_DEFINED