reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 1 | /* libs/graphics/animator/SkScript.h |
| 2 | ** |
| 3 | ** Copyright 2006, The Android Open Source Project |
| 4 | ** |
| 5 | ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | ** you may not use this file except in compliance with the License. |
| 7 | ** You may obtain a copy of the License at |
| 8 | ** |
| 9 | ** http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | ** |
| 11 | ** Unless required by applicable law or agreed to in writing, software |
| 12 | ** distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | ** See the License for the specific language governing permissions and |
| 15 | ** limitations under the License. |
| 16 | */ |
| 17 | |
| 18 | #ifndef SkScript_DEFINED |
| 19 | #define SkScript_DEFINED |
| 20 | |
| 21 | #include "SkOperand.h" |
| 22 | #include "SkIntArray.h" |
| 23 | #include "SkTDict.h" |
| 24 | #include "SkTDStack.h" |
| 25 | |
| 26 | class SkAnimateMaker; |
| 27 | |
| 28 | class SkScriptEngine { |
| 29 | public: |
| 30 | enum Error { |
| 31 | kNoError, |
| 32 | kArrayIndexOutOfBounds, |
| 33 | kCouldNotFindReferencedID, |
| 34 | kDotOperatorExpectsObject, |
| 35 | kErrorInArrrayIndex, |
| 36 | kErrorInFunctionParameters, |
| 37 | kExpectedArray, |
| 38 | kExpectedBooleanExpression, |
| 39 | kExpectedFieldName, |
| 40 | kExpectedHex, |
| 41 | kExpectedIntForConditionOperator, |
| 42 | kExpectedNumber, |
| 43 | kExpectedNumberForArrayIndex, |
| 44 | kExpectedOperator, |
| 45 | kExpectedToken, |
| 46 | kExpectedTokenBeforeDotOperator, |
| 47 | kExpectedValue, |
| 48 | kHandleMemberFailed, |
| 49 | kHandleMemberFunctionFailed, |
| 50 | kHandleUnboxFailed, |
| 51 | kIndexOutOfRange, |
| 52 | kMismatchedArrayBrace, |
| 53 | kMismatchedBrackets, |
| 54 | kNoFunctionHandlerFound, |
| 55 | kPrematureEnd, |
| 56 | kTooManyParameters, |
| 57 | kTypeConversionFailed, |
| 58 | kUnterminatedString |
| 59 | }; |
| 60 | |
| 61 | enum SkOpType { |
| 62 | kNoType, |
| 63 | kInt = 1, |
| 64 | kScalar = 2, |
| 65 | kString = 4, |
| 66 | kArray = 8, |
| 67 | kObject = 16 |
| 68 | // kStruct = 32 |
| 69 | }; |
| 70 | |
| 71 | typedef bool (*_boxCallBack)(void* userStorage, SkScriptValue* result); |
| 72 | typedef bool (*_functionCallBack)(const char* func, size_t len, SkTDArray<SkScriptValue>& params, |
| 73 | void* userStorage, SkScriptValue* result); |
| 74 | typedef bool (*_memberCallBack)(const char* member, size_t len, void* object, |
| 75 | void* userStorage, SkScriptValue* result); |
| 76 | typedef bool (*_memberFunctionCallBack)(const char* member, size_t len, void* object, |
| 77 | SkTDArray<SkScriptValue>& params, void* userStorage, SkScriptValue* result); |
| 78 | // typedef bool (*_objectToStringCallBack)(void* object, void* userStorage, SkScriptValue* result); |
| 79 | typedef bool (*_propertyCallBack)(const char* prop, size_t len, void* userStorage, SkScriptValue* result); |
| 80 | typedef bool (*_unboxCallBack)(void* userStorage, SkScriptValue* result); |
| 81 | SkScriptEngine(SkOpType returnType); |
| 82 | ~SkScriptEngine(); |
| 83 | void boxCallBack(_boxCallBack func, void* userStorage); |
| 84 | bool convertTo(SkDisplayTypes , SkScriptValue* ); |
| 85 | bool evaluateScript(const char** script, SkScriptValue* value); |
| 86 | void forget(SkTypedArray* array); |
| 87 | void functionCallBack(_functionCallBack func, void* userStorage); |
| 88 | Error getError() const { return fError; } |
| 89 | #ifdef SK_DEBUG |
| 90 | bool getErrorString(SkString* err) const; |
| 91 | #endif |
| 92 | void memberCallBack(_memberCallBack , void* userStorage); |
| 93 | void memberFunctionCallBack(_memberFunctionCallBack , void* userStorage); |
| 94 | // void objectToStringCallBack(_objectToStringCallBack , void* userStorage); |
| 95 | void propertyCallBack(_propertyCallBack prop, void* userStorage); |
| 96 | void track(SkTypedArray* array); |
| 97 | void track(SkString* string); |
| 98 | void unboxCallBack(_unboxCallBack func, void* userStorage); |
| 99 | static bool ConvertTo(SkScriptEngine* , SkDisplayTypes toType, SkScriptValue* value); |
| 100 | static SkScalar IntToScalar(int32_t ); |
| 101 | static SkDisplayTypes ToDisplayType(SkOpType type); |
| 102 | static SkOpType ToOpType(SkDisplayTypes type); |
| 103 | static bool ValueToString(SkScriptValue value, SkString* string); |
| 104 | |
| 105 | enum CallBackType { |
| 106 | kBox, |
| 107 | kFunction, |
| 108 | kMember, |
| 109 | kMemberFunction, |
| 110 | // kObjectToString, |
| 111 | kProperty, |
| 112 | kUnbox |
| 113 | }; |
| 114 | |
| 115 | struct UserCallBack { |
| 116 | CallBackType fCallBackType; |
| 117 | void* fUserStorage; |
| 118 | union { |
| 119 | _boxCallBack fBoxCallBack; |
| 120 | _functionCallBack fFunctionCallBack; |
| 121 | _memberCallBack fMemberCallBack; |
| 122 | _memberFunctionCallBack fMemberFunctionCallBack; |
| 123 | // _objectToStringCallBack fObjectToStringCallBack; |
| 124 | _propertyCallBack fPropertyCallBack; |
| 125 | _unboxCallBack fUnboxCallBack; |
| 126 | }; |
| 127 | }; |
| 128 | |
| 129 | enum SkOp { |
| 130 | kUnassigned, |
| 131 | kAdd, |
| 132 | kAddInt = kAdd, |
| 133 | kAddScalar, |
| 134 | kAddString, // string concat |
| 135 | kArrayOp, |
| 136 | kBitAnd, |
| 137 | kBitNot, |
| 138 | kBitOr, |
| 139 | kDivide, |
| 140 | kDivideInt = kDivide, |
| 141 | kDivideScalar, |
| 142 | kElse, |
| 143 | kEqual, |
| 144 | kEqualInt = kEqual, |
| 145 | kEqualScalar, |
| 146 | kEqualString, |
| 147 | kFlipOps, |
| 148 | kGreaterEqual, |
| 149 | kGreaterEqualInt = kGreaterEqual, |
| 150 | kGreaterEqualScalar, |
| 151 | kGreaterEqualString, |
| 152 | kIf, |
| 153 | kLogicalAnd, |
| 154 | kLogicalNot, |
| 155 | kLogicalOr, |
| 156 | kMinus, |
| 157 | kMinusInt = kMinus, |
| 158 | kMinusScalar, |
| 159 | kModulo, |
| 160 | kModuloInt = kModulo, |
| 161 | kModuloScalar, |
| 162 | kMultiply, |
| 163 | kMultiplyInt = kMultiply, |
| 164 | kMultiplyScalar, |
| 165 | kParen, |
| 166 | kShiftLeft, |
| 167 | kShiftRight, // signed |
| 168 | kSubtract, |
| 169 | kSubtractInt = kSubtract, |
| 170 | kSubtractScalar, |
| 171 | kXor, |
| 172 | kArtificialOp = 0x40 |
| 173 | }; |
| 174 | |
| 175 | enum SkOpBias { |
| 176 | kNoBias, |
| 177 | kTowardsNumber = 0, |
| 178 | kTowardsString |
| 179 | }; |
| 180 | |
| 181 | protected: |
| 182 | |
| 183 | struct SkOperatorAttributes { |
| 184 | unsigned int fLeftType : 3; // SkOpType, but only lower values |
| 185 | unsigned int fRightType : 3; // SkOpType, but only lower values |
| 186 | SkOpBias fBias : 1; |
| 187 | }; |
| 188 | |
| 189 | struct SkSuppress { // !!! could be compressed to a long |
| 190 | SkOp fOperator; // operand which enabled suppression |
| 191 | int fOpStackDepth; // depth when suppression operator was found |
| 192 | SkBool8 fSuppress; // set if suppression happens now, as opposed to later |
| 193 | SkBool8 fElse; // set on the : half of ? : |
| 194 | }; |
| 195 | |
| 196 | static const SkOperatorAttributes gOpAttributes[]; |
| 197 | static const signed char gPrecedence[]; |
| 198 | int arithmeticOp(char ch, char nextChar, bool lastPush); |
| 199 | void commonCallBack(CallBackType type, UserCallBack& callBack, void* userStorage); |
| 200 | bool convertParams(SkTDArray<SkScriptValue>&, const SkFunctionParamType* , |
| 201 | int paramTypeCount); |
| 202 | void convertToString(SkOperand& operand, SkDisplayTypes type) { |
| 203 | SkScriptValue scriptValue; |
| 204 | scriptValue.fOperand = operand; |
| 205 | scriptValue.fType = type; |
| 206 | convertTo(SkType_String, &scriptValue); |
| 207 | operand = scriptValue.fOperand; |
| 208 | } |
| 209 | bool evaluateDot(const char*& script, bool suppressed); |
| 210 | bool evaluateDotParam(const char*& script, bool suppressed, const char* field, size_t fieldLength); |
| 211 | bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue>& params); |
| 212 | bool handleArrayIndexer(const char** scriptPtr, bool suppressed); |
| 213 | bool handleBox(SkScriptValue* value); |
| 214 | bool handleFunction(const char** scriptPtr, bool suppressed); |
| 215 | bool handleMember(const char* field, size_t len, void* object); |
| 216 | bool handleMemberFunction(const char* field, size_t len, void* object, SkTDArray<SkScriptValue>& params); |
| 217 | // bool handleObjectToString(void* object); |
| 218 | bool handleProperty(bool suppressed); |
| 219 | bool handleUnbox(SkScriptValue* scriptValue); |
| 220 | bool innerScript(const char** scriptPtr, SkScriptValue* value); |
| 221 | int logicalOp(char ch, char nextChar); |
| 222 | Error opError(); |
| 223 | bool processOp(); |
| 224 | void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; } |
| 225 | bool setError(Error , const char* pos); |
| 226 | enum SkBraceStyle { |
| 227 | // kStructBrace, |
| 228 | kArrayBrace, |
| 229 | kFunctionBrace |
| 230 | }; |
| 231 | |
| 232 | #if 0 |
| 233 | SkIntArray(SkBraceStyle) fBraceStack; // curly, square, function paren |
| 234 | SkIntArray(SkOp) fOpStack; |
| 235 | SkIntArray(SkOpType) fTypeStack; |
| 236 | SkTDOperandArray fOperandStack; |
| 237 | SkTDArray<SkSuppress> fSuppressStack; |
| 238 | #else |
| 239 | SkTDStack<SkBraceStyle> fBraceStack; // curly, square, function paren |
| 240 | SkTDStack<SkOp> fOpStack; |
| 241 | SkTDStack<SkOpType> fTypeStack; |
| 242 | SkTDStack<SkOperand> fOperandStack; |
| 243 | SkTDStack<SkSuppress> fSuppressStack; |
| 244 | #endif |
| 245 | SkAnimateMaker* fMaker; |
| 246 | SkTDTypedArrayArray fTrackArray; |
| 247 | SkTDStringArray fTrackString; |
| 248 | const char* fToken; // one-deep stack |
| 249 | size_t fTokenLength; |
| 250 | SkTDArray<UserCallBack> fUserCallBacks; |
| 251 | SkOpType fReturnType; |
| 252 | Error fError; |
| 253 | int fErrorPosition; |
| 254 | private: |
| 255 | friend class SkTypedArray; |
| 256 | #ifdef SK_SUPPORT_UNITTEST |
| 257 | public: |
| 258 | static void UnitTest(); |
| 259 | #endif |
| 260 | }; |
| 261 | |
| 262 | #ifdef SK_SUPPORT_UNITTEST |
| 263 | |
| 264 | struct SkScriptNAnswer { |
| 265 | const char* fScript; |
| 266 | SkDisplayTypes fType; |
| 267 | int32_t fIntAnswer; |
| 268 | SkScalar fScalarAnswer; |
| 269 | const char* fStringAnswer; |
| 270 | }; |
| 271 | |
| 272 | #endif |
| 273 | |
| 274 | #endif // SkScript_DEFINED |