aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/animator/SkDisplayPost.cpp
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2008-12-17 15:59:43 +0000
commit8a1c16ff38322f0210116fa7293eb8817c7e477e (patch)
treefe40e07f6c8983318a2f79032b9a706ede1090c1 /src/animator/SkDisplayPost.cpp
parent2559c629078f738ac37095d896d580b681ac6a30 (diff)
grab from latest android
git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/animator/SkDisplayPost.cpp')
-rw-r--r--src/animator/SkDisplayPost.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/src/animator/SkDisplayPost.cpp b/src/animator/SkDisplayPost.cpp
new file mode 100644
index 0000000000..17e7c761e9
--- /dev/null
+++ b/src/animator/SkDisplayPost.cpp
@@ -0,0 +1,315 @@
+/* libs/graphics/animator/SkDisplayPost.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "SkDisplayPost.h"
+#include "SkAnimateMaker.h"
+#include "SkAnimator.h"
+#include "SkDisplayMovie.h"
+#include "SkPostParts.h"
+#include "SkScript.h"
+#ifdef SK_DEBUG
+#include "SkDump.h"
+#include "SkTime.h"
+#endif
+
+enum SkPost_Properties {
+ SK_PROPERTY(target),
+ SK_PROPERTY(type)
+};
+
+#if SK_USE_CONDENSED_INFO == 0
+
+const SkMemberInfo SkPost::fInfo[] = {
+ SK_MEMBER(delay, MSec),
+// SK_MEMBER(initialized, Boolean),
+ SK_MEMBER(mode, EventMode),
+ SK_MEMBER(sink, String),
+ SK_MEMBER_PROPERTY(target, String),
+ SK_MEMBER_PROPERTY(type, String)
+};
+
+#endif
+
+DEFINE_GET_MEMBER(SkPost);
+
+SkPost::SkPost() : delay(0), /*initialized(SkBool(-1)), */ mode(kImmediate), fMaker(NULL),
+ fSinkID(0), fTargetMaker(NULL), fChildHasID(false), fDirty(false) {
+}
+
+SkPost::~SkPost() {
+ for (SkData** part = fParts.begin(); part < fParts.end(); part++)
+ delete *part;
+}
+
+bool SkPost::add(SkAnimateMaker& , SkDisplayable* child) {
+ SkASSERT(child && child->isData());
+ SkData* part = (SkData*) child;
+ *fParts.append() = part;
+ return true;
+}
+
+bool SkPost::childrenNeedDisposing() const {
+ return false;
+}
+
+void SkPost::dirty() {
+ fDirty = true;
+}
+
+#ifdef SK_DUMP_ENABLED
+void SkPost::dump(SkAnimateMaker* maker) {
+ dumpBase(maker);
+ SkString* eventType = new SkString();
+ fEvent.getType(eventType);
+ if (eventType->equals("user")) {
+ const char* target = fEvent.findString("id");
+ SkDebugf("target=\"%s\" ", target);
+ }
+ else
+ SkDebugf("type=\"%s\" ", eventType->c_str());
+ delete eventType;
+
+ if (delay > 0) {
+#ifdef SK_CAN_USE_FLOAT
+ SkDebugf("delay=\"%g\" ", SkScalarToFloat(SkScalarDiv(delay, 1000)));
+#else
+ SkDebugf("delay=\"%x\" ", SkScalarDiv(delay, 1000));
+#endif
+ }
+// if (initialized == false)
+// SkDebugf("(uninitialized) ");
+ SkString string;
+ SkDump::GetEnumString(SkType_EventMode, mode, &string);
+ if (!string.equals("immediate"))
+ SkDebugf("mode=\"%s\" ", string.c_str());
+ // !!! could enhance this to search through make hierarchy to show name of sink
+ if (sink.size() > 0) {
+ SkDebugf("sink=\"%s\" sinkID=\"%d\" ", sink.c_str(), fSinkID);
+ } else if (fSinkID != maker->getAnimator()->getSinkID() && fSinkID != 0) {
+ SkDebugf("sinkID=\"%d\" ", fSinkID);
+ }
+ const SkMetaData& meta = fEvent.getMetaData();
+ SkMetaData::Iter iter(meta);
+ SkMetaData::Type type;
+ int number;
+ const char* name;
+ bool closedYet = false;
+ SkDisplayList::fIndent += 4;
+ //this seems to work, but kinda hacky
+ //for some reason the last part is id, which i don't want
+ //and the parts seem to be in the reverse order from the one in which we find the
+ //data itself
+ //SkData** ptr = fParts.end();
+ //SkData* data;
+ //const char* ID;
+ while ((name = iter.next(&type, &number)) != NULL) {
+ //ptr--;
+ if (strcmp(name, "id") == 0)
+ continue;
+ if (closedYet == false) {
+ SkDebugf(">\n");
+ closedYet = true;
+ }
+ //data = *ptr;
+ //if (data->id)
+ // ID = data->id;
+ //else
+ // ID = "";
+ SkDebugf("%*s<data name=\"%s\" ", SkDisplayList::fIndent, "", name);
+ switch (type) {
+ case SkMetaData::kS32_Type: {
+ int32_t s32;
+ meta.findS32(name, &s32);
+ SkDebugf("int=\"%d\" ", s32);
+ } break;
+ case SkMetaData::kScalar_Type: {
+ SkScalar scalar;
+ meta.findScalar(name, &scalar);
+#ifdef SK_CAN_USE_FLOAT
+ SkDebugf("float=\"%g\" ", SkScalarToFloat(scalar));
+#else
+ SkDebugf("float=\"%x\" ", scalar);
+#endif
+ } break;
+ case SkMetaData::kString_Type:
+ SkDebugf("string=\"%s\" ", meta.findString(name));
+ break;
+ case SkMetaData::kPtr_Type: {//when do we have a pointer
+ void* ptr;
+ meta.findPtr(name, &ptr);
+ SkDebugf("0x%08x ", ptr);
+ } break;
+ case SkMetaData::kBool_Type: {
+ bool boolean;
+ meta.findBool(name, &boolean);
+ SkDebugf("boolean=\"%s\" ", boolean ? "true " : "false ");
+ } break;
+ default:
+ break;
+ }
+ SkDebugf("/>\n");
+ //ptr++;
+/* perhaps this should only be done in the case of a pointer?
+ SkDisplayable* displayable;
+ if (maker->find(name, &displayable))
+ displayable->dump(maker);
+ else
+ SkDebugf("\n");*/
+ }
+ SkDisplayList::fIndent -= 4;
+ if (closedYet)
+ dumpEnd(maker);
+ else
+ SkDebugf("/>\n");
+
+}
+#endif
+
+bool SkPost::enable(SkAnimateMaker& maker ) {
+ if (maker.hasError())
+ return true;
+ if (fDirty) {
+ if (sink.size() > 0)
+ findSinkID();
+ if (fChildHasID) {
+ SkString preserveID(fEvent.findString("id"));
+ fEvent.getMetaData().reset();
+ if (preserveID.size() > 0)
+ fEvent.setString("id", preserveID);
+ for (SkData** part = fParts.begin(); part < fParts.end(); part++) {
+ if ((*part)->add())
+ maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingDataToPost);
+ }
+ }
+ fDirty = false;
+ }
+#ifdef SK_DUMP_ENABLED
+ if (maker.fDumpPosts) {
+ SkDebugf("post enable: ");
+ dump(&maker);
+ }
+#if defined SK_DEBUG_ANIMATION_TIMING
+ SkString debugOut;
+ SkMSec time = maker.getAppTime();
+ debugOut.appendS32(time - maker.fDebugTimeBase);
+ debugOut.append(" post id=");
+ debugOut.append(_id);
+ debugOut.append(" enable=");
+ debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
+ debugOut.append(" delay=");
+ debugOut.appendS32(delay);
+#endif
+#endif
+// SkMSec adjustedDelay = maker.adjustDelay(maker.fEnableTime, delay);
+ SkMSec futureTime = maker.fEnableTime + delay;
+ fEvent.setFast32(futureTime);
+#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
+ debugOut.append(" future=");
+ debugOut.appendS32(futureTime - maker.fDebugTimeBase);
+ SkDebugf("%s\n", debugOut.c_str());
+#endif
+ SkEventSinkID targetID = fSinkID;
+ bool isAnimatorEvent = true;
+ SkAnimator* anim = maker.getAnimator();
+ if (targetID == 0) {
+ isAnimatorEvent = fEvent.findString("id") != NULL;
+ if (isAnimatorEvent)
+ targetID = anim->getSinkID();
+ else if (maker.fHostEventSinkID)
+ targetID = maker.fHostEventSinkID;
+ else
+ return true;
+ } else
+ anim = fTargetMaker->getAnimator();
+ if (delay == 0) {
+ if (isAnimatorEvent && mode == kImmediate)
+ fTargetMaker->doEvent(fEvent);
+ else
+ anim->onEventPost(new SkEvent(fEvent), targetID);
+ } else
+ anim->onEventPostTime(new SkEvent(fEvent), targetID, futureTime);
+ return true;
+}
+
+void SkPost::findSinkID() {
+ // get the next delimiter '.' if any
+ fTargetMaker = fMaker;
+ const char* ch = sink.c_str();
+ do {
+ const char* end = strchr(ch, '.');
+ size_t len = end ? end - ch : strlen(ch);
+ SkDisplayable* displayable = NULL;
+ if (SK_LITERAL_STR_EQUAL("parent", ch, len)) {
+ if (fTargetMaker->fParentMaker)
+ fTargetMaker = fTargetMaker->fParentMaker;
+ else {
+ fTargetMaker->setErrorCode(SkDisplayXMLParserError::kNoParentAvailable);
+ return;
+ }
+ } else {
+ fTargetMaker->find(ch, len, &displayable);
+ if (displayable == NULL || displayable->getType() != SkType_Movie) {
+ fTargetMaker->setErrorCode(SkDisplayXMLParserError::kExpectedMovie);
+ return;
+ }
+ SkDisplayMovie* movie = (SkDisplayMovie*) displayable;
+ fTargetMaker = movie->fMovie.fMaker;
+ }
+ if (end == NULL)
+ break;
+ ch = ++end;
+ } while (true);
+ SkAnimator* anim = fTargetMaker->getAnimator();
+ fSinkID = anim->getSinkID();
+}
+
+bool SkPost::hasEnable() const {
+ return true;
+}
+
+void SkPost::onEndElement(SkAnimateMaker& maker) {
+ fTargetMaker = fMaker = &maker;
+ if (fChildHasID == false) {
+ for (SkData** part = fParts.begin(); part < fParts.end(); part++)
+ delete *part;
+ fParts.reset();
+ }
+}
+
+void SkPost::setChildHasID() {
+ fChildHasID = true;
+}
+
+bool SkPost::setProperty(int index, SkScriptValue& value) {
+ SkASSERT(value.fType == SkType_String);
+ SkString* string = value.fOperand.fString;
+ switch(index) {
+ case SK_PROPERTY(target): {
+ fEvent.setType("user");
+ fEvent.setString("id", *string);
+ mode = kImmediate;
+ } break;
+ case SK_PROPERTY(type):
+ fEvent.setType(*string);
+ break;
+ default:
+ SkASSERT(0);
+ return false;
+ }
+ return true;
+}
+