Browse Source

Getting rid of friend classes from GUIElement

Marko Pintera 12 years ago
parent
commit
9fe1924389

+ 23 - 24
BansheeEngine/Include/BsGUIElement.h

@@ -81,42 +81,43 @@ namespace BansheeEngine
 
 		static void destroy(GUIElement* element);
 
+		/************************************************************************/
+		/* 							INTERNAL METHODS                      		*/
+		/************************************************************************/
+
+		GUILayout* _getParentLayout() const { return mParentLayout; }
+		void _setParentLayout(GUILayout* layout) { mParentLayout = layout; }
+
+		void _setDepth(INT32 depth) { mDepth = depth; }
+		void _setOffset(const CM::Int2& offset) { mOffset = offset; }
+		void _setWidth(UINT32 width) { mWidth = width; }
+		void _setHeight(UINT32 height) { mHeight = height; }
+		void _setClipRect(const CM::Rect& clipRect) { mClipRect = clipRect; }
+
+		UINT32 _getWidth() const { return mWidth; }
+		UINT32 _getHeight() const { return mHeight; }
+		virtual UINT32 _getOptimalWidth() const = 0;
+		virtual UINT32 _getOptimalHeight() const = 0;
+
+		const GUI_LAYOUT_OPTIONS& _getLayoutOptions() const { return mLayoutOptions; }
+
+		static void _destroyInternal(GUIElement* element);
+
 		//  onMouseMove
 		//	onMousePress
 		//	onMouseReleased
 		//	onKeyPressed
 		//	onKeyReleased
 	protected:
-		friend class GUIWidget;
-		friend class GUILayout;
-		friend class GUILayoutX;
-		friend class GUILayoutY;
-
 		virtual ~GUIElement();
 
 		virtual void updateRenderElementsInternal() = 0;
 
-		GUILayout* getParentLayout() const { return mParentLayout; }
-		void setParentLayout(GUILayout* layout) { mParentLayout = layout; }
-
-		void setDepth(INT32 depth) { mDepth = depth; }
-		void setOffset(const CM::Int2& offset) { mOffset = offset; }
-		void setWidth(UINT32 width) { mWidth = width; }
-		void setHeight(UINT32 height) { mHeight = height; }
-		void setClipRect(const CM::Rect& clipRect) { mClipRect = clipRect; }
-
-		UINT32 getWidth() const { return mWidth; }
-		UINT32 getHeight() const { return mHeight; }
-
 		void setLayoutOptions(const GUI_LAYOUT_OPTIONS& layoutOptions);
-		const GUI_LAYOUT_OPTIONS& getLayoutOptions() const { return mLayoutOptions; }
-
+		
 		void markAsClean() { mIsDirty = false; }
 		void markAsDirty() { mIsDirty = true; }
 
-		virtual UINT32 getOptimalWidth() const = 0;
-		virtual UINT32 getOptimalHeight() const = 0;
-
 		GUIWidget& mParent;
 		GUILayout* mParentLayout;
 		GUI_LAYOUT_OPTIONS mLayoutOptions;
@@ -128,7 +129,5 @@ namespace BansheeEngine
 		UINT32 mWidth, mHeight;
 		CM::Rect mClipRect;
 		const GUIElementStyle* mStyle;
-
-		static void destroyInternal(GUIElement* element);
 	};
 }

+ 2 - 2
BansheeEngine/Include/BsGUILabel.h

@@ -50,8 +50,8 @@ namespace BansheeEngine
 		 */
 		virtual void updateRenderElementsInternal();
 
-		virtual UINT32 getOptimalWidth() const;
-		virtual UINT32 getOptimalHeight() const;
+		virtual UINT32 _getOptimalWidth() const;
+		virtual UINT32 _getOptimalHeight() const;
 
 		static const GUI_LAYOUT_OPTIONS& getDefaultLayoutOptions();
 	private:

+ 2 - 2
BansheeEngine/Include/BsGUIWindowFrame.h

@@ -42,8 +42,8 @@ namespace BansheeEngine
 		 */
 		virtual void updateRenderElementsInternal();
 
-		virtual UINT32 getOptimalWidth() const;
-		virtual UINT32 getOptimalHeight() const;
+		virtual UINT32 _getOptimalWidth() const;
+		virtual UINT32 _getOptimalHeight() const;
 
 		static const GUI_LAYOUT_OPTIONS& getDefaultLayoutOptions();
 	private:

+ 1 - 1
BansheeEngine/Source/BsGUIElement.cpp

@@ -49,7 +49,7 @@ namespace BansheeEngine
 		return false;
 	}
 
-	void GUIElement::destroyInternal(GUIElement* element)
+	void GUIElement::_destroyInternal(GUIElement* element)
 	{
 		CM_DELETE(element, GUIElement, PoolAlloc);
 	}

+ 8 - 8
BansheeEngine/Source/BsGUILabel.cpp

@@ -59,16 +59,16 @@ namespace BansheeEngine
 		mBounds = mTextSprite->getBounds();
 	}
 
-	UINT32 GUILabel::getOptimalWidth() const
+	UINT32 GUILabel::_getOptimalWidth() const
 	{
 		UINT32 wordWrapWidth = 0;
 
 		if(mDesc.wordWrap)
 		{
-			if(getLayoutOptions().fixedWidth)
-				wordWrapWidth = getLayoutOptions().width;
+			if(_getLayoutOptions().fixedWidth)
+				wordWrapWidth = _getLayoutOptions().width;
 			else
-				wordWrapWidth = getLayoutOptions().maxWidth;
+				wordWrapWidth = _getLayoutOptions().maxWidth;
 		}
 
 		std::shared_ptr<TextUtility::TextData> textData = TextUtility::getTextData(mDesc.text, mDesc.font, mDesc.fontSize, wordWrapWidth, 0, mDesc.wordWrap);
@@ -78,16 +78,16 @@ namespace BansheeEngine
 		return textData->getWidth();
 	}
 
-	UINT32 GUILabel::getOptimalHeight() const
+	UINT32 GUILabel::_getOptimalHeight() const
 	{
 		UINT32 wordWrapWidth = 0;
 
 		if(mDesc.wordWrap)
 		{
-			if(getLayoutOptions().fixedWidth)
-				wordWrapWidth = getLayoutOptions().width;
+			if(_getLayoutOptions().fixedWidth)
+				wordWrapWidth = _getLayoutOptions().width;
 			else
-				wordWrapWidth = getLayoutOptions().maxWidth;
+				wordWrapWidth = _getLayoutOptions().maxWidth;
 		}
 
 		std::shared_ptr<TextUtility::TextData> textData = TextUtility::getTextData(mDesc.text, mDesc.font, mDesc.fontSize, wordWrapWidth, 0, mDesc.wordWrap);

+ 7 - 7
BansheeEngine/Source/BsGUILayout.cpp

@@ -33,20 +33,20 @@ namespace BansheeEngine
 			}
 			else
 			{
-				child.element->setParentLayout(nullptr);
+				child.element->_setParentLayout(nullptr);
 			}
 		}
 	}
 
 	void GUILayout::addElement(GUIElement* element)
 	{
-		if(element->getParentLayout() != nullptr)
-			element->getParentLayout()->removeElement(element);
+		if(element->_getParentLayout() != nullptr)
+			element->_getParentLayout()->removeElement(element);
 
 		GUILayoutEntry entry;
 		entry.setElement(element);
 
-		element->setParentLayout(this);
+		element->_setParentLayout(this);
 		mChildren.push_back(entry);
 	}
 
@@ -74,13 +74,13 @@ namespace BansheeEngine
 		if(idx < 0 || idx >= (UINT32)mChildren.size())
 			CM_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((UINT32)mChildren.size()));
 
-		if(element->getParentLayout() != nullptr)
-			element->getParentLayout()->removeElement(element);
+		if(element->_getParentLayout() != nullptr)
+			element->_getParentLayout()->removeElement(element);
 
 		GUILayoutEntry entry;
 		entry.setElement(element);
 
-		element->setParentLayout(this);
+		element->_setParentLayout(this);
 		mChildren.insert(mChildren.begin() + idx, entry);
 	}
 

+ 14 - 14
BansheeEngine/Source/BsGUILayoutX.cpp

@@ -30,7 +30,7 @@ namespace BansheeEngine
 		{
 			if(child.isElement())
 			{
-				const GUI_LAYOUT_OPTIONS& layoutOptions = child.element->getLayoutOptions();
+				const GUI_LAYOUT_OPTIONS& layoutOptions = child.element->_getLayoutOptions();
 
 				if(layoutOptions.fixedWidth)
 				{
@@ -64,7 +64,7 @@ namespace BansheeEngine
 		{
 			if(child.isElement())
 			{
-				const GUI_LAYOUT_OPTIONS& layoutOptions = child.element->getLayoutOptions();
+				const GUI_LAYOUT_OPTIONS& layoutOptions = child.element->_getLayoutOptions();
 
 				UINT32 elementWidth = 0;
 
@@ -97,13 +97,13 @@ namespace BansheeEngine
 					}
 				}
 
-				child.element->setWidth(elementWidth);
+				child.element->_setWidth(elementWidth);
 
 				if(layoutOptions.fixedHeight)
-					child.element->setHeight(layoutOptions.fixedHeight);
+					child.element->_setHeight(layoutOptions.fixedHeight);
 				else
 				{
-					UINT32 optimalHeight = child.element->getOptimalHeight();
+					UINT32 optimalHeight = child.element->_getOptimalHeight();
 					
 					if(layoutOptions.minHeight > 0)
 						optimalHeight = std::max(layoutOptions.minHeight, optimalHeight);
@@ -111,7 +111,7 @@ namespace BansheeEngine
 					if(layoutOptions.maxHeight > 0)
 						optimalHeight = std::min(layoutOptions.maxHeight, optimalHeight);
 
-					child.element->setHeight(optimalHeight);
+					child.element->_setHeight(optimalHeight);
 				}
 			}
 		}
@@ -126,20 +126,20 @@ namespace BansheeEngine
 		{
 			if(child.isElement())
 			{
-				const GUI_LAYOUT_OPTIONS& layoutOptions = child.element->getLayoutOptions();
+				const GUI_LAYOUT_OPTIONS& layoutOptions = child.element->_getLayoutOptions();
 
 				if(!layoutOptions.fixedWidth && layoutOptions.maxWidth == 0 && layoutOptions.minWidth == 0)
 				{
 					UINT32 elementWidth = std::min((UINT32)Math::CeilToInt(averageWidth), leftoverWidth);
 					leftoverWidth = (UINT32)std::max(0, (INT32)leftoverWidth - (INT32)elementWidth);
 
-					child.element->setWidth(elementWidth);
+					child.element->_setWidth(elementWidth);
 
 					if(layoutOptions.fixedHeight)
-						child.element->setHeight(layoutOptions.fixedHeight);
+						child.element->_setHeight(layoutOptions.fixedHeight);
 					else
 					{
-						UINT32 optimalHeight = child.element->getOptimalHeight();
+						UINT32 optimalHeight = child.element->_getOptimalHeight();
 
 						if(layoutOptions.minHeight > 0)
 							optimalHeight = std::max(layoutOptions.minHeight, optimalHeight);
@@ -147,16 +147,16 @@ namespace BansheeEngine
 						if(layoutOptions.maxHeight > 0)
 							optimalHeight = std::min(layoutOptions.maxHeight, optimalHeight);
 
-						child.element->setHeight(optimalHeight);
+						child.element->_setHeight(optimalHeight);
 					}
 				}
 
-				child.element->setOffset(Int2(x + xOffset, y));
-				child.element->setDepth(depth);
+				child.element->_setOffset(Int2(x + xOffset, y));
+				child.element->_setDepth(depth);
 
 				// TODO - Set clip rect
 
-				xOffset += child.element->getWidth();
+				xOffset += child.element->_getWidth();
 			}
 			else if(child.isLayout())
 			{

+ 1 - 1
BansheeEngine/Source/BsGUIWidget.cpp

@@ -33,7 +33,7 @@ namespace BansheeEngine
 
 		for(auto& elem : mElements)
 		{
-			GUIElement::destroyInternal(elem);
+			GUIElement::_destroyInternal(elem);
 		}
 
 		for(auto& area : mAreas)

+ 2 - 2
BansheeEngine/Source/BsGUIWindowFrame.cpp

@@ -79,7 +79,7 @@ namespace BansheeEngine
 		mBounds = mImageSprite->getBounds();
 	}
 
-	UINT32 GUIWindowFrame::getOptimalWidth() const
+	UINT32 GUIWindowFrame::_getOptimalWidth() const
 	{
 		if(mDesc.texture != nullptr)
 		{
@@ -89,7 +89,7 @@ namespace BansheeEngine
 		return 0;
 	}
 
-	UINT32 GUIWindowFrame::getOptimalHeight() const
+	UINT32 GUIWindowFrame::_getOptimalHeight() const
 	{
 		if(mDesc.texture != nullptr)
 		{

+ 11 - 16
TODO.txt

@@ -17,17 +17,19 @@ DebugDraw
 I still re-create GUIWidget mesh every frame instead of just updating it.
 
 MAJOR ISSUE: writeSubresource/readSubresoure doesn't require a shared ptr to GpuResourceData which means it could get destroyed while still in command queue. Right now it only works because I block right after I call those methods, which ensures nothing is destroyed.
+  - When fixed, make sure I remove blocking calls after writeSubresource where they're not needed (GUIManager for example)
+I call waitUntilLoaded too many times. Sometimes 5-6 times in a single function. Each of those calls will wait a single frame.
 GUIWidget::updateMeshes leaks. If I leave the game running I can see memory continously going up
 
-GUI element grouping is wrong as it doesn't account for transparency
- - Elements sharing same material cannot be batched unless they are at a nearby depth with no elements between them. I need an algorithm to handle that.
-
- On content change I need to notify parent layout
-Do layouts have isDirty flag? They probably should
-GUILabel::getOptimalWidth/Height
-Add clip rectangles on GUILayoutX
-Add flexible spaces (and fixed spaces)
-Implement GUILayoutY
+IMMEDIATE:
+ - I'm not setting worldTransform of GUI material in GUIManager::render
+   - I need to separate meshes per-widget and later implement some kind of smart batching using multiple transforms per mesh
+ - Widgets should probably have their own depth. Make widget and area depths UINT16, and element depth UINT32, a combination of those two.
+ - On content change I need to notify parent layout
+ - Do layouts have isDirty flag? They probably should
+   - GUIArea updates on every window resize event. I should instead just make it dirty and make the update during GUIManager::update
+ - Add clip rectangles on GUILayoutX
+ - Implement GUILayoutY
 
 Figure out how to deal with callbacks properly. I recently eliminated them from Input but I'll need them for my GUI elements...
  - How do I implement them? I really don't want to do Unitys approach to GUI
@@ -39,13 +41,6 @@ Figure out how to deal with callbacks properly. I recently eliminated them from
 
 Immediate TODO:
  - A way to handle onMouseOver, onMouseOut, onMouseDown, onMouseUp events
- - Viewports have a Z order as well. I should use that instead of GUIWidget depth
- - Make it so that widgets can be batched together. Probably means GUIWidget::updateMesh methods needs to move up to GUIManager or similar.
-   - However having widget transform update in shader means I have no way of merging multiple small GUIWidget elements into larger one (useful for batching when game UIs start using animation and stuff)
-     - However this might work with DX11 and newer OpenGL where we can fit in multiple transforms per pass.
-     - So refactor GUIWidget so it is capable of populating a vertex/index buffer, and then have 
-	   GUIManager be in charge of creating a mesh. And if possible we create as little meshes as possible, otherwise we just render them as we do now.
-     - Make sure to only batch widgets belonging to the same viewport
  - (optional) Implement DirectDraw for drawing the bounds so I know they're correct
  - A way to update mesh buffers without recreating vertex/index buffers (Setting data currently does exactly that)