http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/layout/layout.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/layout/layout.h b/weex_core/Source/core/layout/layout.h new file mode 100644 index 0000000..2b201e4 --- /dev/null +++ b/weex_core/Source/core/layout/layout.h @@ -0,0 +1,1073 @@ +#ifdef __cplusplus + +#ifndef WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H +#define WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H + +#include "style.h" +#include "flex_enum.h" +#include <vector> +#include <iostream> +#include <string> +#include <algorithm> + +namespace WeexCore { + + class WXCoreLayoutNode; + + class WXCoreFlexLine; + + enum FormattingContext { + kBFC, + kNonBFC, + } ; + + enum MeasureMode { + kUnspecified, + kExactly, + } ; + + struct WXCoreSize { + private: + float hypotheticalWidth; + float hypotheticalHeight; + public: + friend class WXCoreLayoutNode; + float width; + float height; + + WXCoreSize() : hypotheticalWidth(NAN), + hypotheticalHeight(NAN), + width(0), height(0) {} + + inline void reset() { + hypotheticalWidth = NAN ; + hypotheticalHeight = NAN; + width = 0; + height = 0; + } + + inline bool isNAN() { + return isnan(width) || isnan(height); + } + }; + + /** + * layout-resultï¼layout-heightãlayout-widthãpositionï¼leftãrightãtopãbottomï¼ + */ + struct WXCorelayoutResult { + WXCoreSize mLayoutSize; + WXCorePosition mLayoutPosition; + + inline bool isNAN() { + return mLayoutSize.isNAN() || mLayoutPosition.isNAN(); + } + + inline void reset() { + mLayoutSize.reset(); + mLayoutPosition.reset(); + } + }; + + typedef WXCoreSize(*WXCoreMeasureFunc)(WXCoreLayoutNode *node, float width, + MeasureMode widthMeasureMode, + float height, MeasureMode heightMeasureMode); + + using Index = std::vector<WXCoreLayoutNode *>::size_type; + + /** + * flie line + */ + class WXCoreFlexLine { + public: + float mMainSize; + + float mCrossSize; + + Index mItemCount; + + float mTotalFlexGrow; + + float mTotalFlexibleSize; + + /** + * Store the indices of the children views whose mAlignSelf property is stretch. + * The stored indices are the absolute indices including all children in the Flexbox, + * not the relative indices in this flex line. + */ + std::vector<Index> mIndicesAlignSelfStretch; + + WXCoreFlexLine() : mMainSize(0), + mCrossSize(0), + mItemCount(0), + mTotalFlexGrow(0), + mTotalFlexibleSize(0) { + } + + ~WXCoreFlexLine() { + mMainSize = 0; + mCrossSize = 0; + mItemCount = 0; + mTotalFlexGrow = 0; + mTotalFlexibleSize = 0; + mIndicesAlignSelfStretch.clear(); + } + }; + + /** + * Layout node + */ + class WXCoreLayoutNode { + + protected: + WXCoreLayoutNode() : + mParent(nullptr), + dirty(true), + widthDirty{false}, + heightDirty{false}, + mHasNewLayout(true), + mIsDestroy(false), + measureFunc(nullptr) { + mCssStyle = new WXCoreCSSStyle(); + mLayoutResult = new WXCorelayoutResult(); + } + + + ~WXCoreLayoutNode() { + mIsDestroy = true; + mHasNewLayout = true; + dirty = true; + measureFunc = nullptr; + mParent = nullptr; + mChildList.clear(); + BFCs.clear(); + NonBFCs.clear(); + mChildrenFrozen.clear(); + + for (WXCoreFlexLine *flexLine : mFlexLines) { + if (flexLine != nullptr) { + delete flexLine; + flexLine = nullptr; + } + } + mFlexLines.clear(); + + if (mCssStyle != nullptr) { + delete mCssStyle; + mCssStyle = nullptr; + } + + if (mLayoutResult != nullptr) { + delete mLayoutResult; + mLayoutResult = nullptr; + } + } + + private: + + /** + * Holds the 'frozen' state of children during measure. If a view is frozen it will no longer + * expand regardless of mFlexGrow. Items are indexed by the child's + * reordered index. + */ + std::vector<bool> mChildrenFrozen; + + std::vector<WXCoreFlexLine *> mFlexLines; + + std::vector<WXCoreLayoutNode *> mChildList; + + std::vector<WXCoreLayoutNode *> BFCs; + + std::vector<WXCoreLayoutNode *> NonBFCs; + + WXCoreLayoutNode *mParent = nullptr; + + WXCoreCSSStyle *mCssStyle = nullptr; + + MeasureMode widthMeasureMode = kUnspecified; + + MeasureMode heightMeasureMode = kUnspecified; + + WXCorelayoutResult *mLayoutResult = nullptr; + + WXCorePosition *absoultePositon = nullptr; + + bool mHasNewLayout; + + bool dirty, widthDirty, heightDirty; + + bool mIsDestroy = true; + + WXCoreMeasureFunc measureFunc = nullptr; + + void *context; + + /** ================================ Cacheï¼Last calculate result =================================== **/ + + public: + + + /** ================================ Engine Entry Function =================================== **/ + + void calculateLayout(const std::pair<float,float>&); + + /** ================================ measureFunc =================================== **/ + + inline void setMeasureFunc(WXCoreMeasureFunc measure) { + measureFunc = measure; + markDirty(); + } + + inline WXCoreMeasureFunc getMeasureFunc() const { + return measureFunc; + } + + inline bool haveMeasureFunc() const { + return measureFunc != nullptr; + } + + /** ================================ context =================================== **/ + + + inline void *getContext() const { + return context; + } + + inline void setContext(void * const context) { + this->context = context; + } + + inline void copyStyle(WXCoreLayoutNode *srcNode) { + if (memcmp(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle)) != 0) { + memcpy(mCssStyle, srcNode->mCssStyle, sizeof(WXCoreCSSStyle)); + markDirty(); + } + } + + inline void copyMeasureFunc(WXCoreLayoutNode *srcNode) { + if (memcmp(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc)) != 0) { + memcpy(&measureFunc, &srcNode->measureFunc, sizeof(WXCoreMeasureFunc)); + markDirty(); + } + } + + private: + + /** ================================ measure =================================== **/ + + inline void reset() { + if (isDirty()) { + mLayoutResult->reset(); + for (WXCoreFlexLine *flexLine : mFlexLines) { + if (flexLine != nullptr) { + delete flexLine; + flexLine = nullptr; + } + } + mFlexLines.clear(); + + mChildrenFrozen.assign(getChildCount(kNonBFC), false); + } + widthMeasureMode = isnan(mCssStyle->mStyleWidth) ? kUnspecified : kExactly; + heightMeasureMode = isnan(mCssStyle->mStyleHeight) ? kUnspecified : kExactly; + } + + inline void setLayoutWidth(const float width) { + if (mLayoutResult->mLayoutSize.width != width && + (!isnan(width) || !isnan(mLayoutResult->mLayoutSize.width))) { + mLayoutResult->mLayoutSize.width = width; + widthDirty = true; + markDirty(false); + } + } + + inline void setLayoutHeight(const float height) { + if (mLayoutResult->mLayoutSize.height != height && + (!isnan(height) || !isnan(mLayoutResult->mLayoutSize.height))) { + mLayoutResult->mLayoutSize.height = height; + heightDirty = true; + markDirty(false); + } + } + + inline void setWidthMeasureMode(const MeasureMode measureMode) { + if (widthMeasureMode != measureMode) { + widthMeasureMode = measureMode; + if (getChildCount(kNonBFC) > 0) { + widthDirty = true; + } + } + } + + inline void setHeightMeasureMode(const MeasureMode measureMode) { + if (heightMeasureMode != measureMode) { + heightMeasureMode = measureMode; + if (getChildCount(kNonBFC) > 0) { + heightDirty = true; + } + } + } + + inline float firstLineCrossSize() const { + float sum = sumPaddingBorderAlongAxis(this, !isMainAxisHorizontal(this)); + if (!mFlexLines.empty()) { + sum += mFlexLines[0]->mCrossSize; + } + return sum; + } + + inline float getSumOfCrossSize() const { + float sum = sumPaddingBorderAlongAxis(this, !isMainAxisHorizontal(this)); + for (WXCoreFlexLine *flexLine: mFlexLines) { + sum += flexLine->mCrossSize; + } + return sum; + } + + inline bool isMainAxisHorizontal(const WXCoreLayoutNode* const node) const { + return node->mCssStyle->mFlexDirection == kFlexDirectionRow || + node->mCssStyle->mFlexDirection == kFlexDirectionRowReverse; + } + + inline bool isCrossExactly() const { + return isMainAxisHorizontal(this) ? heightMeasureMode == kExactly + : widthMeasureMode == kExactly; + } + + inline float sumPaddingBorderAlongAxis(const WXCoreLayoutNode* const node, bool horizontal) const { + float paddingBorderAlongAxis; + if (horizontal) { + paddingBorderAlongAxis = + node->mCssStyle->mPadding.getPadding(kPaddingLeft) + + node->mCssStyle->mPadding.getPadding(kPaddingRight) + + node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthLeft) + + node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthRight); + } else { + paddingBorderAlongAxis = + node->mCssStyle->mPadding.getPadding(kPaddingTop) + + node->mCssStyle->mPadding.getPadding(kPaddingBottom) + + node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthTop) + + node->mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthBottom); + } + return paddingBorderAlongAxis; + } + + inline bool isWrapRequired(const float &width, const float &height, + const float ¤tLength, const float &childLength) const { + float freeMainSize = calcFreeSpaceAlongMainAxis(width, height, currentLength); + return !isSingleFlexLine(freeMainSize) && freeMainSize < childLength; + } + + //If width/height is NAN, ret is NAN, which property we use on purpose. + virtual float calcFreeSpaceAlongMainAxis(const float &width, const float &height, const float ¤tLength) const{ + float ret; + if(isMainAxisHorizontal(this)){ + ret = width - sumPaddingBorderAlongAxis(this, true) - currentLength; + } + else{ + ret = height - sumPaddingBorderAlongAxis(this, false) - currentLength; + } + return ret; + } + + inline bool isSingleFlexLine(const float &mainSize) const { + return mCssStyle->mFlexWrap == kNoWrap || isnan(mainSize); + } + + inline void sumFlexGrow(const WXCoreLayoutNode* const child, WXCoreFlexLine* const flexLine, Index i){ + if (child->mCssStyle->mFlexGrow > 0) { + flexLine->mTotalFlexGrow += child->mCssStyle->mFlexGrow; + mChildrenFrozen[i] = false; + if (isMainAxisHorizontal(this)) { + if (!isnan(child->mLayoutResult->mLayoutSize.hypotheticalWidth)) { + flexLine->mTotalFlexibleSize += child->mLayoutResult->mLayoutSize.hypotheticalWidth; + } + } else { + if (!isnan(child->mLayoutResult->mLayoutSize.hypotheticalHeight)) { + flexLine->mTotalFlexibleSize += child->mLayoutResult->mLayoutSize.hypotheticalHeight; + } + } + } else { + mChildrenFrozen[i] = true; + } + } + + inline void setMeasuredDimensionForFlex( + const float width, const MeasureMode widthMeasureMode, + const float height, const MeasureMode heightMeasureMode){ + float actualWidth, actualHeight; + if (isMainAxisHorizontal(this)) { + actualWidth = widthMeasureMode == kExactly ? width : getLargestMainSize(); + actualHeight = heightMeasureMode == kExactly ? height : getSumOfCrossSize(); + } else { + actualHeight = heightMeasureMode == kExactly ? height : getLargestMainSize(); + actualWidth = widthMeasureMode == kExactly ? width : firstLineCrossSize(); + } + setMeasuredDimension(actualWidth, actualHeight); + } + + inline float calcItemSizeAlongAxis(const WXCoreLayoutNode* const node, const bool horizontal, const bool useHypotheticalSize = false) const { + float ret; + if (horizontal) { + ret = node->mCssStyle->mMargin.getMargin(kMarginLeft) + + node->mCssStyle->mMargin.getMargin(kMarginRight); + ret += useHypotheticalSize ? node->mLayoutResult->mLayoutSize.hypotheticalWidth + : node->mLayoutResult->mLayoutSize.width; + } else { + ret = node->mCssStyle->mMargin.getMargin(kMarginTop) + + node->mCssStyle->mMargin.getMargin(kMarginBottom); + ret += useHypotheticalSize ? node->mLayoutResult->mLayoutSize.hypotheticalHeight + : node->mLayoutResult->mLayoutSize.height; + } + return ret; + } + + inline void limitMainSizeForFlexGrow(WXCoreFlexLine* const flexLine, const Index childIndex, + const float flexGrow) { + mChildrenFrozen[childIndex] = true; + flexLine->mTotalFlexGrow -= flexGrow; + } + + inline void setMeasuredDimension(const float width, const float height) { + mLayoutResult->mLayoutSize.width = width; + mLayoutResult->mLayoutSize.height = height; + } + + inline std::pair<bool, float> limitChildMainSize(WXCoreFlexLine* const flexLine, const WXCoreLayoutNode* const child, + float childSizeAlongMainAxis, const Index childIndex){ + bool needsReexpand = false; + if (isMainAxisHorizontal(this)) { + if (!isnan(child->mCssStyle->mMaxWidth) && + childSizeAlongMainAxis > child->mCssStyle->mMaxWidth) { + needsReexpand = true; + childSizeAlongMainAxis = child->mCssStyle->mMaxWidth; + } else if (!isnan(child->mCssStyle->mMinWidth) && + childSizeAlongMainAxis < child->mCssStyle->mMinWidth) { + needsReexpand = true; + childSizeAlongMainAxis = child->mCssStyle->mMinWidth; + } + } else { + if (!isnan(child->mCssStyle->mMaxHeight) && + childSizeAlongMainAxis > child->mCssStyle->mMaxHeight) { + needsReexpand = true; + childSizeAlongMainAxis = child->mCssStyle->mMaxHeight; + } else if (!isnan(child->mCssStyle->mMinHeight) && + childSizeAlongMainAxis < child->mCssStyle->mMinHeight) { + needsReexpand = true; + childSizeAlongMainAxis = child->mCssStyle->mMinHeight; + } + } + limitMainSizeForFlexGrow(flexLine, childIndex, child->mCssStyle->mFlexGrow); + return std::make_pair(needsReexpand, childSizeAlongMainAxis); + } + + void updateLeftRightForAbsolute(float &left, float &right, + const WXCorePadding &parentPadding, + const WXCoreBorderWidth &parentBorder, + const WXCoreSize &parentSize) const { + if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft))) { + if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeRight))) { + ; + } else { + right += parentSize.width - + (parentBorder.getBorderWidth(kBorderWidthRight) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeRight) + + mLayoutResult->mLayoutSize.width); + left += parentSize.width - + (parentBorder.getBorderWidth(kBorderWidthRight) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeRight) + + mLayoutResult->mLayoutSize.width); + } + } else { + left += parentBorder.getBorderWidth(kBorderWidthLeft) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft); + right += parentBorder.getBorderWidth(kBorderWidthLeft) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft); + } + } + + void updateTopBottomForAbsolute(float &top, float &bottom, + const WXCorePadding &parentPadding, + const WXCoreBorderWidth &parentBorder, + const WXCoreSize &parentSize) const { + if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeTop))) { + if (isnan(mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom))) { + ; + } else { + top += parentSize.height - + (parentBorder.getBorderWidth(kBorderWidthBottom) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom) + + mLayoutResult->mLayoutSize.height); + bottom += parentSize.height - + (parentBorder.getBorderWidth(kBorderWidthBottom) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom) + + mLayoutResult->mLayoutSize.height); + } + } else { + top += parentBorder.getBorderWidth(kBorderWidthTop) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeTop); + bottom += parentBorder.getBorderWidth(kBorderWidthTop) + + mCssStyle->mStylePosition.getPosition(kPositionEdgeTop); + } + } + + /** ================================ other =================================== **/ + + inline void clearDirty() { + dirty = false; + widthDirty = false; + heightDirty = false; + } + + void + measure(float, float, bool); + + void hypotheticalMeasure(float, float, bool = false); + + void measureLeafNode(float, float, bool, bool); + + void measureInternalNode(float, float, bool, bool); + + void updateCurrentFlexline(Index, WXCoreFlexLine *, Index, const WXCoreLayoutNode *, bool); + + void measureChild(WXCoreLayoutNode* , float, float, float, bool, bool); + + void adjustChildSize(WXCoreLayoutNode *, float); + + void adjustChildSize(const WXCoreLayoutNode *child, + const float currentMainSize, + const float parentWidth, + const float parentHeight, + float &childWidth, + float &childHeight) const; + + void stretchViewCrossSize(); + + void stretchViewCrossSize(WXCoreLayoutNode *, float); + + Index expandItemsInFlexLine(WXCoreFlexLine *, float, Index); + + void checkSizeConstraints(WXCoreLayoutNode *, bool); + + void + determineMainSize(float width, float height); + + void + determineCrossSize(float, float, bool); + + void setFrame(float, float, float, float); + + void setFrame(WXCorePosition*,float, float, float, float); + + /** ================================ layout =================================== **/ + + void layout(float left, float top, float right, float bottom, bool, const std::pair<float,float>* = nullptr); + + void calcRelativeOffset(float &left, float &top, float &right, float &bottom) const ; + + void calcAbsoluteOffset(float &left, float &top, float &right, float &bottom, const std::pair<float,float>* = nullptr); + + void positionAbsoluteFlexItem(float &left, float &top, float &right, float &bottom); + + void onLayout(float left, float top, float right, float bottom, WXCoreLayoutNode* = nullptr, WXCoreFlexLine *const flexLine = nullptr); + + void layoutHorizontal(bool isRtl, float left, float top, float right, float bottom, + WXCoreLayoutNode*, WXCoreFlexLine *const flexLine); + + void layoutFlexlineHorizontal(const float width, + const WXCoreFlexLine *const flexLine, + float &childLeft, + float &childRight, + float &spaceBetweenItem) const; + + void layoutSingleChildHorizontal(WXCoreLayoutNode *node, WXCoreFlexLine *flexLine, + WXCoreFlexWrap flexWrap, WXCoreAlignItems alignItems, + float, float, float, float, bool); + + void layoutSingleChildHorizontal(const bool isRtl, + const bool, + float childBottom, float childTop, + WXCoreFlexLine *const flexLine, + WXCoreLayoutNode *const child, + float&, float&); + + void layoutVertical(bool isRtl, bool fromBottomToTop, float left, float top, float right, float bottom, + WXCoreLayoutNode*, WXCoreFlexLine *const flexLine); + + void layoutFlexlineVertical(const float height, + const WXCoreFlexLine *const flexLine, + float &childTop, + float &childBottom, + float &spaceBetweenItem) const; + void layoutSingleChildVertical(WXCoreLayoutNode *node, WXCoreFlexLine *flexLine, + bool isRtl, WXCoreAlignItems alignItems, + float, float, float, float, bool); + + void layoutSingleChildVertical(const bool isRtl, const bool fromBottomToTop, + const bool absoluteFlexItem, + const float childLeft, const float childRight, + WXCoreFlexLine *const flexLine, + WXCoreLayoutNode *const child, + float& ,float&); + + void updateFlexLineForAbsoluteItem(WXCoreLayoutNode *const absoluteFlexItem, WXCoreFlexLine *const flexLine); + + void initFormatingContext(std::vector<WXCoreLayoutNode *> &BFCs); + + std::pair<bool,float> calculateBFCWidth(float, float); + + std::pair<bool,float> calculateBFCHeight(float, float); + + std::tuple<bool, float, float> calculateBFCDimension(const std::pair<float,float>&); + + virtual void onLayoutBefore() { + + } + + virtual void onLayoutAfter(float width, float height) { + + } + + + public: + + /** ================================ tree =================================== **/ + + inline Index getChildCount(FormattingContext formattingContext) const { + switch (formattingContext) { + case kNonBFC: + return NonBFCs.size(); + case kBFC: + return BFCs.size(); + default: + return mChildList.size(); + } + } + + inline Index getChildCount() const { + return mChildList.size(); + } + + inline std::vector<WXCoreLayoutNode *>::const_iterator ChildListIterBegin() { + return mChildList.cbegin(); + } + + inline std::vector<WXCoreLayoutNode *>::const_iterator ChildListIterEnd() { + return mChildList.cend(); + } + + inline void removeChild(const WXCoreLayoutNode* const child) { + for (int index = 0; index < mChildList.size(); index++) { + if (child == mChildList[index]) { + mChildList.erase(mChildList.begin() + index); + break; + } + } + markDirty(); + } + + inline void addChildAt(WXCoreLayoutNode* const child, Index index) { + mChildList.insert(mChildList.begin() + index, child); + child->mParent = this; + markDirty(); + } + + inline WXCoreLayoutNode *getChildAt(const FormattingContext formattingContext, const Index index) const { + switch (formattingContext) { + case kNonBFC: + return NonBFCs[index]; + case kBFC: + return BFCs[index]; + default: + return mChildList[index]; + } + } + + inline WXCoreLayoutNode *getChildAt(const Index index) const { + return mChildList[index]; + } + + inline WXCoreLayoutNode *getParent() const { + return mParent; + } + + inline bool isBFC(WXCoreLayoutNode* const node) const { + return node->mCssStyle->mPositionType == kAbsolute || node->mCssStyle->mPositionType == kFixed; + } + + /** ================================ margin =================================== **/ + + inline float getMarginTop() const { + return mCssStyle->mMargin.getMargin(kMarginTop); + } + + inline float getMarginBottom() const { + return mCssStyle->mMargin.getMargin(kMarginBottom); + } + + inline float getMarginLeft() const { + return mCssStyle->mMargin.getMargin(kMarginLeft); + } + + inline float getMarginRight() const { + return mCssStyle->mMargin.getMargin(kMarginRight); + } + + inline void setMargin(const WXCoreMarginEdge &edge, const float margin) { + if (mCssStyle->mMargin.setMargin(edge, margin)) { + markDirty(); + } + } + + inline const WXCoreMargin &GetMargins() const { + return mCssStyle->mMargin; + } + + /** ================================ padding =================================== **/ + + inline float getPaddingLeft() const { + return mCssStyle->mPadding.getPadding(kPaddingLeft); + } + + inline float getPaddingRight() const { + return mCssStyle->mPadding.getPadding(kPaddingRight); + } + + inline float getPaddingTop() const { + return mCssStyle->mPadding.getPadding(kPaddingTop); + } + + inline float getPaddingBottom() const { + return mCssStyle->mPadding.getPadding(kPaddingBottom); + } + + inline void setPadding(const WXCorePaddingEdge edge, const float padding) { + if (mCssStyle->mPadding.setPadding(edge, padding)) { + markDirty(); + } + } + + inline const WXCorePadding &GetPaddings() const { + return mCssStyle->mPadding; + } + + /** ================================ border-width =================================== **/ + + inline float getBorderWidthLeft() const { + return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthLeft); + } + + inline float getBorderWidthRight() const { + return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthRight); + } + + inline float getBorderWidthTop() const { + return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthTop); + } + + inline float getBorderWidthBottom() const { + return mCssStyle->mBorderWidth.getBorderWidth(kBorderWidthBottom); + } + + inline void setBorderWidth(const WXCoreBorderWidthEdge edge, const float borderWidth) { + if (mCssStyle->mBorderWidth.setBorderWidth(edge, borderWidth)) { + markDirty(); + } + } + + inline const WXCoreBorderWidth &GetBorders() const { + return mCssStyle->mBorderWidth; + } + + /** ================================ position-type =================================== **/ + + inline void setStylePositionType(const WXCorePositionType positionType) { + if (mCssStyle->mPositionType != positionType) { + mCssStyle->mPositionType = positionType; + markDirty(); + } + } + + inline WXCorePositionType getStypePositionType() const { + return mCssStyle->mPositionType; + } + + + /** ================================ position =================================== **/ + + inline float getStylePositionTop() const { + return mCssStyle->mStylePosition.getPosition(kPositionEdgeTop); + } + + inline float getStylePositionBottom() const { + return mCssStyle->mStylePosition.getPosition(kPositionEdgeBottom); + } + + inline float getStylePositionLeft() const { + return mCssStyle->mStylePosition.getPosition(kPositionEdgeLeft); + } + + inline float getStylePositionRight() const { + return mCssStyle->mStylePosition.getPosition(kPositionEdgeRight); + } + + inline void setStylePosition(const WXCorePositionEdge edge, const float positionRight) { + if (mCssStyle->mStylePosition.setPosition(edge, positionRight)) + markDirty(); + } + + + /** ================================ dimension =================================== **/ + + inline void setStyleWidthLevel(const DimensionLevel level) const { + if (mCssStyle->mStyleWidthLevel != level) { + mCssStyle->mStyleWidthLevel = level; + } + } + + inline void setStyleHeightLevel(const DimensionLevel level) const { + if (mCssStyle->mStyleHeightLevel != level) { + mCssStyle->mStyleHeightLevel = level; + } + } + + inline DimensionLevel getStyleHeightLevel() const { + return mCssStyle->mStyleHeightLevel; + } + + inline DimensionLevel getStyleWidthLevel() const { + return mCssStyle->mStyleWidthLevel; + } + + inline void setStyleWidth(const float width, const bool updating) { + if (mCssStyle->mStyleWidth != width) { + mCssStyle->mStyleWidth = width; + markDirty(); + if(updating) { + markChildrenDirty(true); + } + } + } + + inline void setStyleWidthToNAN() { + if (!isnan(mCssStyle->mStyleWidth)) { + mCssStyle->mStyleWidth = NAN; + markDirty(); + markChildrenDirty(true); + } + } + + inline float getStyleWidth() const { + return mCssStyle->mStyleWidth; + } + + inline void setStyleHeight(const float height) { + if (mCssStyle->mStyleHeight != height) { + mCssStyle->mStyleHeight = height; + markDirty(); + } + } + + inline float getStyleHeight() const { + return mCssStyle->mStyleHeight; + } + + inline void setMinWidth(const float minWidth, const bool updating) { + if (mCssStyle->mMinWidth != minWidth) { + mCssStyle->mMinWidth = minWidth; + markDirty(); + if(updating) { + markChildrenDirty(true); + } + } + } + + inline float getMinWidth() const { + return mCssStyle->mMinWidth; + } + + inline void setMaxWidth(const float maxWidth, const bool updating) { + if (mCssStyle->mMaxWidth != maxWidth) { + mCssStyle->mMaxWidth = maxWidth; + markDirty(); + if(updating) { + markChildrenDirty(true); + } + } + } + + inline float getMaxWidth() const { + return mCssStyle->mMaxWidth; + } + + inline void setMinHeight(const float minHeight) { + if (mCssStyle->mMinHeight != minHeight) { + mCssStyle->mMinHeight = minHeight; + markDirty(); + } + } + + inline float getMinHeight() const { + return mCssStyle->mMinHeight; + } + + inline void setMaxHeight(const float maxHeight) { + if (mCssStyle->mMaxHeight != maxHeight) { + mCssStyle->mMaxHeight = maxHeight; + markDirty(); + } + } + + inline float getMaxHeight() const { + return mCssStyle->mMaxHeight; + } + + + /** ================================ flex-style =================================== **/ + + inline void setFlexDirection(const WXCoreFlexDirection flexDirection, const bool updating) { + if (mCssStyle->mFlexDirection != flexDirection) { + mCssStyle->mFlexDirection = flexDirection; + markDirty(); + if (updating) { + for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) { + (*it)->markDirty(false); + } + } + } + } + + inline WXCoreFlexDirection getFlexDirection() const { + return mCssStyle->mFlexDirection; + } + + inline void setFlexWrap(const WXCoreFlexWrap flexWrap) { + if (mCssStyle->mFlexWrap != flexWrap) { + mCssStyle->mFlexWrap = flexWrap; + markDirty(); + } + } + + inline WXCoreFlexWrap getFlexWrap() const { + return mCssStyle->mFlexWrap; + } + + inline void setJustifyContent(const WXCoreJustifyContent justifyContent) { + if (mCssStyle->mJustifyContent != justifyContent) { + mCssStyle->mJustifyContent = justifyContent; + } + } + + inline WXCoreJustifyContent getJustifyContent() const { + return mCssStyle->mJustifyContent; + } + + inline void setAlignItems(const WXCoreAlignItems alignItems) { + if (mCssStyle->mAlignItems != alignItems) { + mCssStyle->mAlignItems = alignItems; + markDirty(); + } + } + + inline WXCoreAlignItems getAlignItems() const { + return mCssStyle->mAlignItems; + } + + inline void setAlignSelf(const WXCoreAlignSelf alignSelf) { + if (mCssStyle->mAlignSelf != alignSelf) { + mCssStyle->mAlignSelf = alignSelf; + markDirty(); + } + } + + inline WXCoreAlignSelf getAlignSelf() const { + return mCssStyle->mAlignSelf; + } + + virtual void setFlex(const float flex) { + if (mCssStyle->mFlexGrow != flex) { + mCssStyle->mFlexGrow = flex; + markDirty(); + } + } + + inline float getFlex() const { + return mCssStyle->mFlexGrow; + } + + /** ================================ layout-result =================================== **/ + + inline float getLayoutWidth() const { + return mLayoutResult->mLayoutSize.width; + } + + inline float getLayoutHeight() const { + return mLayoutResult->mLayoutSize.height; + } + + inline float getLayoutPositionTop() const { + return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeTop); + } + + inline float getLayoutPositionBottom() const { + return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeBottom); + } + + inline float getLayoutPositionLeft() const { + return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeLeft); + } + + inline float getLayoutPositionRight() const { + return mLayoutResult->mLayoutPosition.getPosition(kPositionEdgeRight); + } + + inline bool hasNewLayout() const { + return mHasNewLayout; + } + + inline bool isDirty() const { + return dirty; + } + + inline void markDirty(const bool recursion = true) { + if (!isDirty()) { + dirty = true; + if (getParent() != nullptr && recursion) { + getParent()->markDirty(); + } + } + } + + bool markChildrenDirty(const bool updatedNode = false) { + bool ret = false; + if(getChildCount() == 0){ + if(measureFunc!= nullptr){ + ret = true; + } + } + else { + //isnan(mCssStyle->mStyleWidth) XOR updatedNode + if(isnan(mCssStyle->mStyleWidth) != updatedNode){ + for (auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) { + ret = ((*it)->markChildrenDirty() || ret) ; + } + } + } + dirty = ret || dirty; + return ret; + } + + inline void setHasNewLayout(const bool hasNewLayout) { + this->mHasNewLayout = hasNewLayout; + } + + inline float getLargestMainSize() const { + float largestSize = 0; + for (WXCoreFlexLine *flexLine : mFlexLines) { + largestSize = std::max(largestSize, flexLine->mMainSize); + } + return largestSize + sumPaddingBorderAlongAxis(this, isMainAxisHorizontal(this)); + } + }; +} +#endif //WEEXCORE_FLEXLAYOUT_WXCORELAYOUTNODE_H +#endif \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/layout/style.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/layout/style.cpp b/weex_core/Source/core/layout/style.cpp new file mode 100644 index 0000000..60c6e18 --- /dev/null +++ b/weex_core/Source/core/layout/style.cpp @@ -0,0 +1,247 @@ +#include "style.h" + +namespace WeexCore { + + bool WXCoreMargin::setMargin(const WXCoreMarginEdge &edge, float margin) { + bool dirty = false; + switch (edge) { + case kMarginALL: + if (mMarginLeft != margin + || mMarginTop != margin + || mMarginRight != margin + || mMarginBottom != margin) { + mMarginLeft = margin; + mMarginTop = margin; + mMarginRight = margin; + mMarginBottom = margin; + dirty = true; + } + break; + case kMarginLeft: + if (mMarginLeft != margin) { + mMarginLeft = margin; + dirty = true; + } + break; + case kMarginTop: + if (mMarginTop != margin) { + mMarginTop = margin; + dirty = true; + } + break; + case kMarginRight: + if (mMarginRight != margin) { + mMarginRight = margin; + dirty = true; + } + break; + case kMarginBottom: + if (mMarginBottom != margin) { + mMarginBottom = margin; + dirty = true; + } + break; + } + return dirty; + } + + float WXCoreMargin::getMargin(const WXCoreMarginEdge &edge)const { + float margin = 0; + switch (edge) { + case kMarginLeft: + margin = mMarginLeft; + break; + case kMarginTop: + margin = mMarginTop; + break; + case kMarginRight: + margin = mMarginRight; + break; + case kMarginBottom: + margin = mMarginBottom; + break; + default: + break; + } + return margin; + } + + bool WXCorePadding::setPadding(const WXCorePaddingEdge &edge, float padding) { + bool dirty = false; + switch (edge) { + case kPaddingALL: + if (mPaddingLeft != padding + || mPaddingTop != padding + || mPaddingRight != padding + || mPaddingBottom != padding) { + mPaddingLeft = padding; + mPaddingTop = padding; + mPaddingRight = padding; + mPaddingBottom = padding; + dirty = true; + } + break; + case kPaddingLeft: + if (mPaddingLeft != padding) { + mPaddingLeft = padding; + dirty = true; + } + break; + case kPaddingTop: + if (mPaddingTop != padding) { + mPaddingTop = padding; + dirty = true; + } + break; + case kPaddingRight: + if (mPaddingRight != padding) { + mPaddingRight = padding; + dirty = true; + } + break; + case kPaddingBottom: + if (mPaddingBottom != padding) { + mPaddingBottom = padding; + dirty = true; + } + break; + } + return dirty; + } + + float WXCorePadding::getPadding(const WXCorePaddingEdge &edge)const { + float padding = 0; + switch (edge) { + case kPaddingLeft: + padding = mPaddingLeft; + break; + case kPaddingTop: + padding = mPaddingTop; + break; + case kPaddingRight: + padding = mPaddingRight; + break; + case kPaddingBottom: + padding = mPaddingBottom; + break; + default: + break; + } + return padding; + } + + bool WXCoreBorderWidth::setBorderWidth(const WXCoreBorderWidthEdge &edge, float borderWidth) { + bool dirty = false; + switch (edge) { + case kBorderWidthALL: + if (mBorderWidthLeft != borderWidth + || mBorderWidthTop != borderWidth + || mBorderWidthRight != borderWidth + || mBorderWidthBottom != borderWidth) { + mBorderWidthLeft = borderWidth; + mBorderWidthTop = borderWidth; + mBorderWidthRight = borderWidth; + mBorderWidthBottom = borderWidth; + dirty = true; + } + break; + case kBorderWidthLeft: + if (mBorderWidthLeft != borderWidth) { + mBorderWidthLeft = borderWidth; + dirty = true; + } + break; + case kBorderWidthTop: + if (mBorderWidthTop != borderWidth) { + mBorderWidthTop = borderWidth; + dirty = true; + } + break; + case kBorderWidthRight: + if (mBorderWidthRight != borderWidth) { + mBorderWidthRight = borderWidth; + dirty = true; + } + break; + case kBorderWidthBottom: + if (mBorderWidthBottom != borderWidth) { + mBorderWidthBottom = borderWidth; + dirty = true; + } + break; + } + return dirty; + } + + float WXCoreBorderWidth::getBorderWidth(const WXCoreBorderWidthEdge &edge)const { + float borderWidth = 0; + switch (edge) { + case kBorderWidthLeft: + borderWidth = mBorderWidthLeft; + break; + case kBorderWidthTop: + borderWidth = mBorderWidthTop; + break; + case kBorderWidthRight: + borderWidth = mBorderWidthRight; + break; + case kBorderWidthBottom: + borderWidth = mBorderWidthBottom; + break; + default: + break; + } + return borderWidth; + } + + bool WXCorePosition::setPosition(const WXCorePositionEdge &edge, float position) { + bool dirty = false; + switch (edge) { + case kPositionEdgeLeft: + if (mLeft != position) { + mLeft = position; + dirty = true; + } + break; + case kPositionEdgeTop: + if (mTop != position) { + mTop = position; + dirty = true; + } + break; + case kPositionEdgeRight: + if (mRight != position) { + mRight = position; + dirty = true; + } + break; + case kPositionEdgeBottom: + if (mBottom != position) { + mBottom = position; + dirty = true; + } + break; + } + return dirty; + } + + float WXCorePosition::getPosition(const WXCorePositionEdge &edge) { + float position = 0; + switch (edge) { + case kPositionEdgeLeft: + position = mLeft; + break; + case kPositionEdgeTop: + position = mTop; + break; + case kPositionEdgeRight: + position = mRight; + break; + case kPositionEdgeBottom: + position = mBottom; + break; + } + return position; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/layout/style.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/layout/style.h b/weex_core/Source/core/layout/style.h new file mode 100644 index 0000000..86a853f --- /dev/null +++ b/weex_core/Source/core/layout/style.h @@ -0,0 +1,285 @@ +#ifdef __cplusplus + +#ifndef WEEXCORE_FLEXLAYOUT_WXCOREFLEXENUMS_H +#define WEEXCORE_FLEXLAYOUT_WXCOREFLEXENUMS_H + + +#include "flex_enum.h" +#include <cmath> + +namespace WeexCore { + + /** + * Margin: margin-leftãmargin-rightãmargin-topãmargin-bottom + */ + class WXCoreMargin { + private: + float mMarginTop; + float mMarginBottom; + float mMarginLeft; + float mMarginRight; + + public: + WXCoreMargin() : mMarginTop(0), + mMarginBottom(0), + mMarginLeft(0), + mMarginRight(0) {} + + ~WXCoreMargin() { + mMarginTop = 0; + mMarginBottom = 0; + mMarginLeft = 0; + mMarginRight = 0; + } + + bool setMargin(const WXCoreMarginEdge &edge, float margin); + + float getMargin(const WXCoreMarginEdge &edge)const; + }; + + + /** + * Paddingï¼padding-leftãpadding-rightãpadding-topãpadding-bottom + */ + class WXCorePadding { + private: + float mPaddingTop; + float mPaddingBottom; + float mPaddingLeft; + float mPaddingRight; + + public: + WXCorePadding() : mPaddingTop(0), + mPaddingBottom(0), + mPaddingLeft(0), + mPaddingRight(0) {} + + ~WXCorePadding() { + mPaddingTop = 0; + mPaddingBottom = 0; + mPaddingLeft = 0; + mPaddingRight = 0; + } + + bool setPadding(const WXCorePaddingEdge &edge, float padding); + + float getPadding(const WXCorePaddingEdge &edge)const; + }; + + + /** + * BorderWidthï¼borderwidth-leftãborderwidth-rightãborderwidth-topãborderwidth-bottom + */ + class WXCoreBorderWidth { + private: + float mBorderWidthTop; + float mBorderWidthBottom; + float mBorderWidthLeft; + float mBorderWidthRight; + + public: + WXCoreBorderWidth() : mBorderWidthTop(0), + mBorderWidthBottom(0), + mBorderWidthLeft(0), + mBorderWidthRight(0) {} + + ~WXCoreBorderWidth() { + mBorderWidthTop = 0; + mBorderWidthBottom = 0; + mBorderWidthLeft = 0; + mBorderWidthRight = 0; + } + + bool setBorderWidth(const WXCoreBorderWidthEdge &edge, float borderWidth); + + float getBorderWidth(const WXCoreBorderWidthEdge &edge)const; + }; + + + /** + * positionï¼leftãrightãtopãbottom + */ + class WXCorePosition { + private: + float mTop; + float mBottom; + float mLeft; + float mRight; + + public: + WXCorePosition() : mTop(NAN), + mBottom(NAN), + mLeft(NAN), + mRight(NAN) {} + + ~WXCorePosition() { + reset(); + } + + inline bool isNAN() { + return isnan(mTop) || isnan(mBottom) || isnan(mLeft) || isnan(mRight); + } + + inline void reset() { + mTop = 0; + mBottom = 0; + mLeft = 0; + mRight = 0; + } + + bool setPosition(const WXCorePositionEdge &edge, float position); + + float getPosition(const WXCorePositionEdge &edge); + }; + + enum DimensionLevel{ + CSS_STYLE = 1, + INSTANCE_STYLE = 2, + FALLBACK_STYLE = 3 + }; + + /** + * css-style + */ + class WXCoreCSSStyle { + public: + /** + * The direction children items are placed inside the Flexbox layout, it determines the + * direction of the main axis (and the cross axis, perpendicular to the main axis). + * The default value is {@link WXCoreFlexDirection #WXCore_Flex_Direction_Row}. + */ + WXCoreFlexDirection mFlexDirection; + + /** + * This attribute controls whether the flex container is single-line or multi-line, and the + * direction of the cross axis. + * <ul> + * <li>{@link WXCoreFlexWrap}: The flex container is single-line.</li> + * <li>{@link WXCoreFlexWrap}: The flex container is multi-line.</li> + * <li>{@link WXCoreFlexWrap}: The flex container is multi-line. The direction of the + * cross axis is opposed to the direction as the {@link WXCoreFlexWrap}</li> + * </ul> + * The default value is {@link WXCoreFlexWrap #WXCore_Wrap_NoWrap}. + */ + WXCoreFlexWrap mFlexWrap; + + /** + * This attribute controls the alignment along the main axis. + * The default value is {@link WXCoreJustifyContent #WXCore_Justify_Flex_Start}. + */ + WXCoreJustifyContent mJustifyContent; + + /** + * This attribute controls the alignment along the cross axis. + * The default value is {@link WXCoreAlignItems #WXCore_AlignItems_Stretch}. + */ + WXCoreAlignItems mAlignItems; + + /** + * This attribute controls the alignment along the cross axis. + * The default value is {@link WXCoreAlignSelf #WXCore_AlignSelf_Auto}. + */ + WXCoreAlignSelf mAlignSelf; + + WXCorePositionType mPositionType; + + float mFlexGrow; + + float mMinWidth; + + float mMinHeight; + + float mMaxWidth; + + float mMaxHeight; + + float mStyleWidth; + + float mStyleHeight; + + DimensionLevel mStyleWidthLevel; + + DimensionLevel mStyleHeightLevel; + + WXCoreMargin mMargin; + + WXCorePadding mPadding; + + WXCoreBorderWidth mBorderWidth; + + WXCorePosition mStylePosition; + + constexpr static float kFlexGrowDefault = 0; + + constexpr static WXCoreFlexDirection kFlexDirectionDefault= kFlexDirectionColumn; + + constexpr static WXCoreFlexWrap kFlexWrapDefault = kNoWrap; + + constexpr static WXCoreJustifyContent kFlexJustifyContentDefault = kJustifyFlexStart; + + constexpr static WXCoreAlignItems kFlexAlignItemsDefault = kAlignItemsStretch; + + constexpr static WXCoreAlignSelf kFlexAlignSelfDefault = kAlignSelfAuto; + + constexpr static WXCorePositionType kWXCorePositionTypeDefault = kRelative; + + WXCoreCSSStyle() : mFlexDirection(kFlexDirectionDefault), + mFlexWrap(kFlexWrapDefault), + mJustifyContent(kFlexJustifyContentDefault), + mAlignItems(kFlexAlignItemsDefault), + mAlignSelf(kFlexAlignSelfDefault), + mFlexGrow(kFlexGrowDefault), + mPositionType(kWXCorePositionTypeDefault), + mStyleWidth(NAN), mStyleHeight(NAN), + mStyleHeightLevel(FALLBACK_STYLE), mStyleWidthLevel(FALLBACK_STYLE), + mMaxWidth(NAN), mMaxHeight(NAN), + mMinWidth(NAN), mMinHeight(NAN) { + + } + + ~WXCoreCSSStyle() { + mFlexDirection = kFlexDirectionDefault; + mFlexWrap = kFlexWrapDefault; + mJustifyContent = kFlexJustifyContentDefault; + mAlignItems = kFlexAlignItemsDefault; + mAlignSelf = kFlexAlignSelfDefault; + mFlexGrow = kFlexGrowDefault; + mStyleWidth = NAN; + mStyleHeight = NAN; + mStyleWidthLevel = FALLBACK_STYLE; + mStyleHeightLevel = FALLBACK_STYLE; + mMaxWidth = NAN; + mMaxHeight = NAN; + mMinWidth = NAN; + mMinHeight = NAN; + } + + inline float sumPaddingBorderOfEdge(const WXCoreEdge edge){ + switch (edge) { + case kTop: + return mPadding.getPadding(kPaddingTop) + + mBorderWidth.getBorderWidth(kBorderWidthTop); + case kRight: + return mPadding.getPadding(kPaddingRight) + + mBorderWidth.getBorderWidth(kBorderWidthRight); + case kBottom: + return mPadding.getPadding(kPaddingBottom) + + mBorderWidth.getBorderWidth(kBorderWidthBottom); + case kLeft: + return mPadding.getPadding(kPaddingLeft) + + mBorderWidth.getBorderWidth(kBorderWidthLeft); + } + } + + float sumMarginOfDirection(bool horizontal){ + if(horizontal){ + return mMargin.getMargin(kMarginLeft) + mMargin.getMargin(kMarginRight); + } + else{ + return mMargin.getMargin(kMarginTop) + mMargin.getMargin(kMarginBottom); + } + } + }; +} +#endif //WEEXCORE_FLEXLAYOUT_WXCOREFLEXENUMS_H +#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/moniter/render_performance.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/moniter/render_performance.cpp b/weex_core/Source/core/moniter/render_performance.cpp new file mode 100644 index 0000000..0e1b6f2 --- /dev/null +++ b/weex_core/Source/core/moniter/render_performance.cpp @@ -0,0 +1,32 @@ +#include "render_performance.h" +#include <android/base/log_utils.h> + +namespace WeexCore { + + int + RenderPerformance::PrintPerformanceLogImplAndroid(const PerformanceStage &performanceStage) { + +#if PERFORMANCE_LOG + + if (performanceStage == onFirstScreen) { + LOGD("[WeexCore render time]onFirstScreen"); + } else { + LOGD("[WeexCore render time]onRenderSuccess"); + } + LOGD("[WeexCore render time] jniCallTime: %lld", jniCallTime); + LOGD("[WeexCore render time] -addElementActionJNITime: %lld", addElementActionJNITime); + LOGD("[WeexCore render time] layoutActionJNITime: %lld", layoutActionJniTime); + LOGD("[WeexCore render time] -jniCallBridgeTime: %lld", jniCallBridgeTime); + LOGD("[WeexCore render time] createJMapJNITime: %lld", createJMapJNITime); + LOGD("[WeexCore render time] cssLayoutTime: %lld", cssLayoutTime); + LOGD("[WeexCore render time] parseJsonTime: %lld", parseJsonTime); + LOGD("[WeexCore render time] buildRenderObjectTime: %lld", buildRenderObjectTime); +#endif + + return cssLayoutTime; + } + + int RenderPerformance::PrintPerformanceLogImplIOS(const PerformanceStage &performanceStage) { + return 0; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/moniter/render_performance.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/moniter/render_performance.h b/weex_core/Source/core/moniter/render_performance.h new file mode 100644 index 0000000..b382fe5 --- /dev/null +++ b/weex_core/Source/core/moniter/render_performance.h @@ -0,0 +1,51 @@ +#ifndef WEEX_PROJECT_WXPERFORMANCE_H +#define WEEX_PROJECT_WXPERFORMANCE_H + +namespace WeexCore { + + typedef enum PerformanceStage { + onFirstScreen, onRenderSuccess, + } PerformanceStage; + + class RenderPerformance { + + public: + + long long jniCallTime; + + long long jniCallBridgeTime; + + long long cssLayoutTime; + + long long addElementActionJNITime; + + long long addEventActionJNITime; + + long long removeEventActionJNITime; + + long long layoutActionJniTime; + + long long parseJsonTime; + + long long buildRenderObjectTime; + + long long createJMapJNITime; + + RenderPerformance() : jniCallTime(0), jniCallBridgeTime(0), cssLayoutTime(0), + addElementActionJNITime(0), + layoutActionJniTime(0), parseJsonTime(0), buildRenderObjectTime(0), + createJMapJNITime(0) {} + + inline int PrintPerformanceLog(PerformanceStage performanceStage) { + return PrintPerformanceLogImplAndroid(performanceStage); + } + + private: + + int PrintPerformanceLogImplAndroid(const PerformanceStage &performanceStage); + + int PrintPerformanceLogImplIOS(const PerformanceStage &performanceStage); + }; +} + +#endif //WEEX_PROJECT_WXPERFORMANCE_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/parser/dom_parser.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/parser/dom_parser.cpp b/weex_core/Source/core/parser/dom_parser.cpp new file mode 100644 index 0000000..cf51297 --- /dev/null +++ b/weex_core/Source/core/parser/dom_parser.cpp @@ -0,0 +1,564 @@ + +#include "dom_parser.h" +#include <base/fpconv.h> +#include <core/render/node/render_object.h> +#include <core/render/page/render_page.h> +#include <core/render/node/factory/render_creator.h> +#include <android/base/log_utils.h> + +using namespace std; +using namespace rapidjson; + +namespace WeexCore { + + static inline int matchNum(std::string temp, std::string key, int startIndex, int endIndex) { + int num = 0; + while (startIndex < endIndex) { + int index = temp.find(key, startIndex); + if (index >= 0 && index < endIndex) { + num++; + startIndex = index + 1; + } else { + break; + } + } + return num; + } + + bool JsonParserHandler::Null() { + st_ = kHasNull; + v_.SetNull(); + return true; + } + + bool JsonParserHandler::Bool(bool b) { + st_ = kHasBool; + v_.SetBool(b); + return true; + } + + bool JsonParserHandler::Int(int i) { + st_ = kHasNumber; + v_.SetInt(i); + return true; + } + + bool JsonParserHandler::Uint(unsigned u) { + st_ = kHasNumber; + v_.SetUint(u); + return true; + } + + bool JsonParserHandler::Int64(int64_t i) { + st_ = kHasNumber; + v_.SetInt64(i); + return true; + } + + bool JsonParserHandler::Uint64(uint64_t u) { + st_ = kHasNumber; + v_.SetUint64(u); + return true; + } + + bool JsonParserHandler::Double(double d) { + st_ = kHasNumber; + v_.SetDouble(d); + return true; + } + + bool JsonParserHandler::RawNumber(const char *, SizeType, bool) { return false; } + + bool JsonParserHandler::String(const char *str, SizeType length, bool) { + st_ = kHasString; + v_.SetString(str, length); + return true; + } + + bool JsonParserHandler::StartObject() { + st_ = kEnteringObject; + return true; + } + + bool JsonParserHandler::Key(const char *str, SizeType length, bool) { + st_ = kHasKey; + v_.SetString(str, length); + return true; + } + + bool JsonParserHandler::EndObject(SizeType) { + st_ = kExitingObject; + return true; + } + + bool JsonParserHandler::StartArray() { + st_ = kEnteringArray; + return true; + } + + bool JsonParserHandler::EndArray(SizeType) { + st_ = kExitingArray; + return true; + } + + JsonParserHandler::JsonParserHandler(char *str) : v_(), st_(kInit), r_(), ss_(str) { + r_.IterativeParseInit(); + ParseNext(); + } + + void JsonParserHandler::ParseNext() { + if (r_.HasParseError()) { + st_ = kError; + return; + } + + r_.IterativeParseNext<parseFlags>(ss_, *this); + } + + bool JsonParser::EnterObject() { + if (st_ != kEnteringObject) { + st_ = kError; + return false; + } + + ParseNext(); + return true; + } + + bool JsonParser::EnterArray() { + if (st_ != kEnteringArray) { + st_ = kError; + return false; + } + + ParseNext(); + return true; + } + + const char *JsonParser::NextObjectKey() { + if (st_ == kHasKey) { + const char *result = v_.GetString(); + ParseNext(); + return result; + } + + if (st_ != kExitingObject) { + st_ = kError; + return 0; + } + + ParseNext(); + return 0; + } + + bool JsonParser::NextArrayValue() { + if (st_ == kExitingArray) { + ParseNext(); + return false; + } + + if (st_ == kError || st_ == kExitingObject || st_ == kHasKey) { + st_ = kError; + return false; + } + + return true; + } + + int JsonParser::GetInt() { + if (st_ != kHasNumber || !v_.IsInt()) { + st_ = kError; + return 0; + } + + int result = v_.GetInt(); + ParseNext(); + return result; + } + + double JsonParser::GetDouble() { + if (st_ != kHasNumber) { + st_ = kError; + return 0.; + } + + double result = v_.GetDouble(); + ParseNext(); + return result; + } + + bool JsonParser::GetBool() { + if (st_ != kHasBool) { + st_ = kError; + return false; + } + + bool result = v_.GetBool(); + ParseNext(); + return result; + } + + void JsonParser::GetNull() { + if (st_ != kHasNull) { + st_ = kError; + return; + } + + ParseNext(); + } + + const char *JsonParser::GetString() { + if (st_ != kHasString) { + st_ = kError; + return 0; + } + + const char *temp = v_.GetString(); + int len = v_.GetStringLength(); + char *result = new char[len + 1]; + strcpy(result, temp); + result[len] = '\0'; + ParseNext(); + return result; + } + + const char *JsonParser::Stringify() { + return ss_.src_; + } + + void JsonParser::SkipOut(int depth) { + do { + if (st_ == kEnteringArray || st_ == kEnteringObject) { + ++depth; + } else if (st_ == kExitingArray || st_ == kExitingObject) { + --depth; + } else if (st_ == kError) { + return; + } + + ParseNext(); + } while (depth > 0); + } + + void JsonParser::SkipValue() { + SkipOut(0); + } + + void JsonParser::SkipArray() { + SkipOut(1); + } + + void JsonParser::SkipObject() { + SkipOut(1); + } + + Value *JsonParser::PeekValue() { + if (st_ >= kHasNull && st_ <= kHasKey) { + return &v_; + } + + return 0; + } + + int JsonParser::PeekType() { + if (st_ >= kHasNull && st_ <= kHasKey) { + return v_.GetType(); + } + + if (st_ == kEnteringArray) { + return kArrayType; + } + + if (st_ == kEnteringObject) { + return kObjectType; + } + + return -1; + } + + RenderObject * + ParseJsonObject(JsonParser &r, RenderObject *parent, int index, const std::string &pageId) { + + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + r.EnterObject(); + + RenderObject *render; + std::string ref; + + while (const char *key = r.NextObjectKey()) { + + if (0 == strcmp(key, "ref")) { + RAPIDJSON_ASSERT(r.PeekType() == kStringType); + const char *temp_ref = r.GetString(); + ref = temp_ref; + if (temp_ref != nullptr) { + delete[]temp_ref; + temp_ref = nullptr; + } + } else if (0 == strcmp(key, "type")) { + RAPIDJSON_ASSERT(r.PeekType() == kStringType); + const char *temp_type = r.GetString(); + render = (RenderObject *) RenderCreator::GetInstance()->CreateRender(temp_type, ref); + render->SetPageId(pageId); + if (parent != nullptr) + parent->AddRenderObject(index, render); + if (temp_type != nullptr) { + delete[]temp_type; + temp_type = nullptr; + } + } else if (0 == strcmp(key, "attr") || 0 == strcmp(key, "style")) { + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + r.EnterObject(); + while (const char *key2 = r.NextObjectKey()) { + if (r.PeekType() == kNumberType) { + RAPIDJSON_ASSERT(r.PeekType() == kNumberType); + char *temp = new char[65]; + if (0 == strcmp(key, "attr")) { + int len = fpconv_dtoa(r.GetDouble(), temp); + temp[len] = '\0'; + char value[len + 1]; + strcpy(value, temp); + render->AddAttr(key2, value); + } else if (0 == strcmp(key, "style")) { + int len = fpconv_dtoa(r.GetDouble(), temp); + temp[len] = '\0'; + char value[len + 1]; + strcpy(value, temp); + render->AddStyle(key2, value); + } + if (temp != nullptr) { + delete[]temp; + temp = nullptr; + } + } else if (r.PeekType() == kStringType) { + RAPIDJSON_ASSERT(r.PeekType() == kStringType); + const char *temp_str = r.GetString(); + if (0 == strcmp(key, "attr")) { + render->AddAttr(key2, temp_str); + } else if (0 == strcmp(key, "style")) { + render->AddStyle(key2, temp_str); + } + if (temp_str != nullptr) { + delete[]temp_str; + temp_str = nullptr; + } + } else if (r.PeekType() == kArrayType) { + RAPIDJSON_ASSERT(r.PeekType() == kArrayType); + std::string temp = "["; + temp.append(r.Stringify()); + int endIndex = temp.find(']'); + if(endIndex > 0) { + // has found! + int startIndex = 0; + int leftMatchSize = matchNum(temp, "[", startIndex, endIndex) - 1; + while (leftMatchSize > 0 && startIndex < endIndex) { + startIndex = endIndex + 1; + int markIndex = temp.find(']', startIndex); + if(markIndex > 0) { + endIndex = markIndex; + leftMatchSize--; + } + leftMatchSize += matchNum(temp, "[", startIndex, endIndex); + } + } + std::string value = temp.substr(0, endIndex + 1); + if (0 == strcmp(key, "attr")) { + render->AddAttr(key2, value); + } else if (0 == strcmp(key, "style")) { + render->AddStyle(key2, value); + } + r.SkipValue(); + } else if (r.PeekType() == kTrueType) { + RAPIDJSON_ASSERT(r.PeekType() == kTrueType); + if (0 == strcmp(key, "attr")) { + render->AddAttr(key2, "true"); + } else if (0 == strcmp(key, "style")) { + render->AddStyle(key2, "true"); + } + r.SkipValue(); + } else if (r.PeekType() == kFalseType) { + RAPIDJSON_ASSERT(r.PeekType() == kFalseType); + if (0 == strcmp(key, "attr")) { + render->AddAttr(key2, "false"); + } else if (0 == strcmp(key, "style")) { + render->AddStyle(key2, "false"); + } + r.SkipValue(); + } else if (r.PeekType() == kObjectType) { + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + std::string temp = "{"; + temp.append(r.Stringify()); + int endIndex = temp.find('}'); + if(endIndex > 0) { + // has found! + int startIndex = 0; + int leftMatchSize = matchNum(temp, "{", startIndex, endIndex) - 1; + while (leftMatchSize > 0 && startIndex < endIndex) { + startIndex = endIndex + 1; + int markIndex = temp.find('}', startIndex); + if(markIndex > 0) { + endIndex = markIndex; + leftMatchSize--; + } + leftMatchSize += matchNum(temp, "{", startIndex, endIndex); + } + } + std::string value = temp.substr(0, endIndex + 1); + + if (0 == strcmp(key, "attr")) { + render->AddAttr(key2, value); + } else if (0 == strcmp(key, "style")) { + render->AddStyle(key2, value); + } + r.SkipValue(); + } else { + r.SkipValue(); + } + } + } else if (0 == strcmp(key, "event")) { + RAPIDJSON_ASSERT(r.PeekType() == kArrayType); + r.EnterArray(); + while (r.NextArrayValue()) { + RAPIDJSON_ASSERT(r.PeekType() == kStringType); + const char *temp_event = r.GetString(); + render->AddEvent(temp_event); + if (temp_event != nullptr) { + delete[]temp_event; + temp_event = nullptr; + } + } + } else if (0 == strcmp(key, "children")) { + RAPIDJSON_ASSERT(r.PeekType() == kArrayType); + r.EnterArray(); + + int index = 0; + + while (r.NextArrayValue()) { + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + ParseJsonObject(r, render, index, pageId); + index++; + } + } else { + r.SkipValue(); + } + } + + if (render != nullptr) { + render->ApplyDefaultStyle(); + render->ApplyDefaultAttr(); + } + + return render; + } + +/** + * Parse json data to RenderObject + * @param data : json data (include ref/style/attr/event/children) + * @param page : {@link RenderPage} + * @return {@link RenderObject*} + */ + RenderObject *Json2RenderObject(char *data, const std::string &pageId) { + + JsonParser r(data); + return ParseJsonObject(r, nullptr, 0, pageId); + } + + std::vector<std::pair<std::string, std::string>> *Json2Pairs(char *data) { + std::vector<std::pair<std::string, std::string>> *pairs = nullptr; + JsonParser r(data); + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + r.EnterObject(); + pairs = new std::vector<std::pair<std::string, std::string>>(); + while (const char *key = r.NextObjectKey()) { + if (r.PeekType() == kNumberType) { + RAPIDJSON_ASSERT(r.PeekType() == kNumberType); + char *temp = new char[65]; + int len = fpconv_dtoa(r.GetDouble(), temp); + temp[len] = '\0'; + char value[len + 1]; + strcpy(value, temp); + std::pair<std::string, std::string> myPair(key, value); + pairs->insert(pairs->end(), myPair); + if (temp != nullptr) { + delete[]temp; + temp = nullptr; + } + } else if (r.PeekType() == kStringType) { + RAPIDJSON_ASSERT(r.PeekType() == kStringType); + const char *value = r.GetString(); + std::pair<std::string, std::string> myPair(key, value); + pairs->insert(pairs->end(), myPair); + if (value != nullptr) { + delete value; + value = nullptr; + } + } else if (r.PeekType() == kArrayType) { + RAPIDJSON_ASSERT(r.PeekType() == kArrayType); + std::string temp = "["; + temp.append(r.Stringify()); + int endIndex = temp.find(']'); + if(endIndex > 0) { + // has found! + int startIndex = 0; + int leftMatchSize = matchNum(temp, "[", startIndex, endIndex) - 1; + while (leftMatchSize > 0 && startIndex < endIndex) { + startIndex = endIndex + 1; + int markIndex = temp.find(']', startIndex); + if(markIndex > 0) { + endIndex = markIndex; + leftMatchSize--; + } + leftMatchSize += matchNum(temp, "[", startIndex, endIndex); + } + } + std::string value = temp.substr(0, endIndex + 1); + std::pair<std::string, std::string> myPair(key, value); + pairs->insert(pairs->end(), myPair); + r.SkipValue(); + } else if (r.PeekType() == kTrueType) { + RAPIDJSON_ASSERT(r.PeekType() == kTrueType); + std::pair<std::string, std::string> myPair(key, "true"); + pairs->insert(pairs->end(), myPair); + r.SkipValue(); + } else if (r.PeekType() == kFalseType) { + RAPIDJSON_ASSERT(r.PeekType() == kFalseType); + std::pair<std::string, std::string> myPair(key, "false"); + pairs->insert(pairs->end(), myPair); + r.SkipValue(); + } else if (r.PeekType() == kNullType) { + RAPIDJSON_ASSERT(r.PeekType() == kNullType); + std::pair<std::string, std::string> myPair(key, ""); + pairs->insert(pairs->end(), myPair); + r.SkipValue(); + } else if (r.PeekType() == kObjectType) { + RAPIDJSON_ASSERT(r.PeekType() == kObjectType); + std::string temp = "{"; + temp.append(r.Stringify()); + int endIndex = temp.find('}'); + if(endIndex > 0) { + // has found! + int startIndex = 0; + int leftMatchSize = matchNum(temp, "{", startIndex, endIndex) - 1; + while (leftMatchSize > 0 && startIndex < endIndex) { + startIndex = endIndex + 1; + int markIndex = temp.find('}', startIndex); + if(markIndex > 0) { + endIndex = markIndex; + leftMatchSize--; + } + leftMatchSize += matchNum(temp, "{", startIndex, endIndex); + } + } + std::string value = temp.substr(0, endIndex + 1); + + std::pair<std::string, std::string> myPair(key, value); + pairs->insert(pairs->end(), myPair); + r.SkipValue(); + } else { + r.SkipValue(); + } + } + return pairs; + } +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/parser/dom_parser.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/parser/dom_parser.h b/weex_core/Source/core/parser/dom_parser.h new file mode 100644 index 0000000..064de63 --- /dev/null +++ b/weex_core/Source/core/parser/dom_parser.h @@ -0,0 +1,129 @@ +#ifndef WEEX_JSON_TOOLS +#define WEEX_JSON_TOOLS + +#include "rapidjson/pointer.h" +#include <vector> +#include <string> + +namespace WeexCore { + + class RenderObject; + + class RenderPage; + +/** + * Use to handler json parser result + */ + class JsonParserHandler { + public: + bool Null(); + + bool Bool(bool b); + + bool Int(int i); + + bool Uint(unsigned u); + + bool Int64(int64_t i); + + bool Uint64(uint64_t u); + + bool Double(double d); + + bool RawNumber(const char *, rapidjson::SizeType, bool); + + bool String(const char *str, rapidjson::SizeType length, bool); + + bool StartObject(); + + bool Key(const char *str, rapidjson::SizeType length, bool); + + bool EndObject(rapidjson::SizeType); + + bool StartArray(); + + bool EndArray(rapidjson::SizeType); + + protected: + JsonParserHandler(char *str); + + void ParseNext(); + + protected: + enum JsonParsingState { + kInit, + kError, + kHasNull, + kHasBool, + kHasNumber, + kHasString, + kHasKey, + kEnteringObject, + kExitingObject, + kEnteringArray, + kExitingArray + }; + + rapidjson::Value v_; + JsonParsingState st_; + rapidjson::Reader r_; + rapidjson::InsituStringStream ss_; + + static const int parseFlags = rapidjson::kParseDefaultFlags | rapidjson::kParseInsituFlag; + }; + +/** + * Use to parse json data + */ + class JsonParser : public JsonParserHandler { + public: + JsonParser(char *str) : JsonParserHandler(str) {} + + bool EnterObject(); + + bool EnterArray(); + + const char *NextObjectKey(); + + bool NextArrayValue(); + + int GetInt(); + + double GetDouble(); + + const char *GetString(); + + const char *Stringify(); + + bool GetBool(); + + void GetNull(); + + void SkipObject(); + + void SkipArray(); + + void SkipValue(); + + rapidjson::Value *PeekValue(); + + int PeekType(); // returns a rapidjson::Type, or -1 for no value (at end of object/array) + + bool IsValid() { return st_ != kError; } + + protected: + void SkipOut(int depth); + }; + +/** + * Parse json data to RenderObject + * @param data : json data (include ref/style/attr/event/children) + * @param page : {@link RenderPage*} + * @return {@link RenderObject*} + */ + RenderObject *Json2RenderObject(char *data, const std::string &pageId); + + std::vector<std::pair<std::string, std::string>> *Json2Pairs(char *data); +} + +#endif //WEEX_JSON_TOOLS http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action.h b/weex_core/Source/core/render/action/render_action.h new file mode 100644 index 0000000..3172ab2 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action.h @@ -0,0 +1,20 @@ +#ifndef WEEXV8_RENDERACTION_H +#define WEEXV8_RENDERACTION_H + +#include <core/layout/layout.h> +#include <core/render/node/render_object.h> +#include <core/render/manager/render_manager.h> +#include <core/render/page/render_page.h> +#include <android/bridge/impl/bridge_impl_android.h> +#include <string> +#include <base/TimeUtils.h> + +namespace WeexCore { + + class render_action { + public: + virtual void ExecuteAction() = 0; + }; +} + +#endif //WEEXV8_RENDERACTION_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_add_element.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_add_element.cpp b/weex_core/Source/core/render/action/render_action_add_element.cpp new file mode 100644 index 0000000..047359c --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_add_element.cpp @@ -0,0 +1,33 @@ +#include "render_action_add_element.h" + +namespace WeexCore { + + RenderActionAddElement::RenderActionAddElement(const std::string &pageId, const RenderObject *render, + const RenderObject *parent, int index) { + this->mAttributes = render->Attributes(); + this->mStyles = render->Styles(); + this->mEvents = render->Events(); + this->mMargins = render->GetMargins(); + this->mPaddings = render->GetPaddings(); + this->mBorders = render->GetBorders(); + this->mPageId = pageId; + this->mComponentType = render->Type(); + this->mRef = render->Ref(); + this->mParentRef = parent->Ref(); + this->mIndex = index; + } + + void RenderActionAddElement::ExecuteAction() { + RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId); + if (page == nullptr) + return; + + long long startTime = getCurrentTime(); + Bridge_Impl_Android::getInstance()->callAddElement(mPageId.c_str(), mComponentType.c_str(), mRef.c_str(), + mIndex, mParentRef.c_str(), mStyles, mAttributes, + mEvents, mMargins, mPaddings, mBorders); + page->JniCallTime(getCurrentTime() - startTime); + page->AddElementActionJNITime(getCurrentTime() - startTime); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_add_element.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_add_element.h b/weex_core/Source/core/render/action/render_action_add_element.h new file mode 100644 index 0000000..c87b943 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_add_element.h @@ -0,0 +1,31 @@ +#ifndef WEEX_PROJECT_ADDELEMENTACTION_H +#define WEEX_PROJECT_ADDELEMENTACTION_H + +#include "render_action.h" + +namespace WeexCore { + + class RenderActionAddElement : public render_action { + + public: + RenderActionAddElement(const std::string &pageId, const RenderObject *render, const RenderObject *parent, + int index); + + void ExecuteAction(); + + public: + StylesMap *mStyles; + AttributesMap *mAttributes; + EventsSet *mEvents; + WXCoreMargin mMargins; + WXCorePadding mPaddings; + WXCoreBorderWidth mBorders; + std::string mPageId; + std::string mComponentType; + std::string mParentRef; + std::string mRef; + int mIndex; + }; +} + +#endif //WEEX_PROJECT_ADDELEMENTACTION_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_add_event.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_add_event.cpp b/weex_core/Source/core/render/action/render_action_add_event.cpp new file mode 100644 index 0000000..66d8910 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_add_event.cpp @@ -0,0 +1,24 @@ +#include "render_action_add_event.h" + +namespace WeexCore { + + RenderActionAddEvent::RenderActionAddEvent(const std::string &pageId, const std::string &ref, const std::string &event) { + this->mPageId = pageId; + this->mRef = ref; + this->mEvent = event; + } + + void RenderActionAddEvent::ExecuteAction() { + RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId); + if (page == nullptr) + return; + + long long startTime = getCurrentTime(); + + Bridge_Impl_Android::getInstance()->callAddEvent(mPageId.c_str(), mRef.c_str(), mEvent.c_str()); + + page->JniCallTime(getCurrentTime() - startTime); + page->AddEventActionJNITime(getCurrentTime() - startTime); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_add_event.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_add_event.h b/weex_core/Source/core/render/action/render_action_add_event.h new file mode 100644 index 0000000..d6da682 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_add_event.h @@ -0,0 +1,22 @@ +#ifndef WEEX_PROJECT_ADDEVENTACTION_H +#define WEEX_PROJECT_ADDEVENTACTION_H + +#include "render_action.h" + +namespace WeexCore { + + class RenderActionAddEvent : public render_action { + + public: + RenderActionAddEvent(const std::string &pageId, const std::string &ref, const std::string &event); + + void ExecuteAction(); + + public: + std::string mPageId; + std::string mRef; + std::string mEvent; + }; +} + +#endif //WEEX_PROJECT_ADDEVENTACTION_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_createbody.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_createbody.cpp b/weex_core/Source/core/render/action/render_action_createbody.cpp new file mode 100644 index 0000000..7a97ec2 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_createbody.cpp @@ -0,0 +1,29 @@ +#include "render_action_createbody.h" + +namespace WeexCore { + + RenderActionCreateBody::RenderActionCreateBody(const std::string &pageId, const RenderObject *render) { + this->mAttributes = render->Attributes(); + this->mStyles = render->Styles(); + this->mEvents = render->Events(); + this->mMargins = render->GetMargins(); + this->mPaddings = render->GetPaddings(); + this->mBorders = render->GetBorders(); + this->mPageId = pageId; + this->mComponentType = render->Type(); + this->mRef = render->Ref(); + } + + void RenderActionCreateBody::ExecuteAction() { + RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId); + if (page == nullptr) + return; + + long long startTime = getCurrentTime(); + Bridge_Impl_Android::getInstance()->callCreateBody(mPageId.c_str(), mComponentType.c_str(), mRef.c_str(), + mStyles, mAttributes, mEvents, + mMargins, mPaddings, mBorders); + page->JniCallTime(getCurrentTime() - startTime); + page->AddElementActionJNITime(getCurrentTime() - startTime); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_createbody.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_createbody.h b/weex_core/Source/core/render/action/render_action_createbody.h new file mode 100644 index 0000000..f8dcd8a --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_createbody.h @@ -0,0 +1,27 @@ +#ifndef WEEX_PROJECT_CREATEBODYACTION_H +#define WEEX_PROJECT_CREATEBODYACTION_H + +#include "render_action.h" + +namespace WeexCore { + class RenderActionCreateBody : public render_action { + + public: + RenderActionCreateBody(const std::string &pageId, const RenderObject *render); + + void ExecuteAction(); + + public: + StylesMap *mStyles; + AttributesMap *mAttributes; + EventsSet *mEvents; + WXCoreMargin mMargins; + WXCorePadding mPaddings; + WXCoreBorderWidth mBorders; + std::string mPageId; + std::string mComponentType; + std::string mRef; + }; +} + +#endif //WEEX_PROJECT_CREATEBODYACTION_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_createfinish.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_createfinish.cpp b/weex_core/Source/core/render/action/render_action_createfinish.cpp new file mode 100644 index 0000000..0e72b03 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_createfinish.cpp @@ -0,0 +1,19 @@ +#include "render_action_createfinish.h" + +namespace WeexCore { + + RenderActionCreateFinish::RenderActionCreateFinish(const std::string &pageId) { + this->mPageId = pageId; + } + + void RenderActionCreateFinish::ExecuteAction() { + RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId); + if (page == nullptr) + return; + + long long startTime = getCurrentTime(); + Bridge_Impl_Android::getInstance()->callCreateFinish(mPageId.c_str()); + + page->JniCallTime(getCurrentTime() - startTime); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_createfinish.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_createfinish.h b/weex_core/Source/core/render/action/render_action_createfinish.h new file mode 100644 index 0000000..513ab45 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_createfinish.h @@ -0,0 +1,20 @@ +#ifndef WEEX_PROJECT_CREATEFINISHACTION_H +#define WEEX_PROJECT_CREATEFINISHACTION_H + +#include "render_action.h" + +namespace WeexCore { + + class RenderActionCreateFinish : public render_action { + + public: + RenderActionCreateFinish(const std::string &pageId); + + void ExecuteAction(); + + public: + std::string mPageId; + }; +} + +#endif //WEEX_PROJECT_CREATEFINISHACTION_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_layout.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_layout.cpp b/weex_core/Source/core/render/action/render_action_layout.cpp new file mode 100644 index 0000000..4417b5c --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_layout.cpp @@ -0,0 +1,33 @@ +#include "render_action_layout.h" + +namespace WeexCore { + + RenderActionLayout::RenderActionLayout(const std::string &pageId, const RenderObject *render,int index) { + this->mPageId = pageId; + this->mRef = render->Ref(); + this->index = index; + GetLayoutInfo(render); + } + + void RenderActionLayout::ExecuteAction() { + RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId); + if (page == nullptr) + return; + + long long startTime = getCurrentTime(); + Bridge_Impl_Android::getInstance()->callLayout(mPageId.c_str(), mRef.c_str(), + mTop, mBottom, mLeft, mRight, + mHeight, mWidth, index); + page->JniCallTime(getCurrentTime() - startTime); + page->LayoutActionJniTime(getCurrentTime() - startTime); + } + + void RenderActionLayout::GetLayoutInfo(const WXCoreLayoutNode *node) { + mTop = node->getLayoutPositionTop(); + mBottom = node->getLayoutPositionBottom(); + mRight = node->getLayoutPositionRight(); + mLeft = node->getLayoutPositionLeft(); + mHeight = node->getLayoutHeight(); + mWidth = node->getLayoutWidth(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_layout.h ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_layout.h b/weex_core/Source/core/render/action/render_action_layout.h new file mode 100644 index 0000000..0344e54 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_layout.h @@ -0,0 +1,31 @@ +#ifndef WEEX_PROJECT_RELAYOUTRENDERACTION_H +#define WEEX_PROJECT_RELAYOUTRENDERACTION_H + +#include "render_action.h" + +namespace WeexCore { + + class RenderActionLayout : public render_action { + + public: + RenderActionLayout(const std::string &pageId, const RenderObject *render, const int index); + + void ExecuteAction(); + + void GetLayoutInfo(const WXCoreLayoutNode *node); + + public: + EventsSet *mEvents; + std::string mPageId; + std::string mRef; + float mWidth; + float mHeight; + float mTop; + float mLeft; + float mBottom; + float mRight; + int index; + }; +} + +#endif //WEEX_PROJECT_RELAYOUTRENDERACTION_H http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_move_element.cpp ---------------------------------------------------------------------- diff --git a/weex_core/Source/core/render/action/render_action_move_element.cpp b/weex_core/Source/core/render/action/render_action_move_element.cpp new file mode 100644 index 0000000..98bb9b1 --- /dev/null +++ b/weex_core/Source/core/render/action/render_action_move_element.cpp @@ -0,0 +1,22 @@ +#include "render_action_move_element.h" + +namespace WeexCore { + + RenderActionMoveElement::RenderActionMoveElement(const std::string &pageId, const std::string &ref, + const std::string &parentRef, int index) { + this->mPageId = pageId; + this->mRef = ref; + this->mParentRef = parentRef; + this->mIndex = index; + } + + void RenderActionMoveElement::ExecuteAction() { + RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId); + if (page == nullptr) + return; + + long long startTime = getCurrentTime(); + Bridge_Impl_Android::getInstance()->callMoveElement(mPageId.c_str(), mRef.c_str(), mParentRef.c_str(), mIndex); + page->JniCallTime(getCurrentTime() - startTime); + } +} \ No newline at end of file
