Mercurial > LightClone
changeset 26:3a63df04f3c0
Several Gui enhancements; Drag and drop should work; Added resource caching
line wrap: on
line diff
--- a/LightClone/LightClone.vcproj Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/LightClone.vcproj Fri Sep 16 15:28:15 2011 -0700 @@ -241,38 +241,6 @@ > </File> <File - RelativePath=".\Source\GuiButton.cpp" - > - </File> - <File - RelativePath=".\Source\GuiCursor.cpp" - > - </File> - <File - RelativePath=".\Source\GuiElement.cpp" - > - </File> - <File - RelativePath=".\Source\GuiEvent.cpp" - > - </File> - <File - RelativePath=".\Source\GuiEventMap.cpp" - > - </File> - <File - RelativePath=".\Source\GuiImage.cpp" - > - </File> - <File - RelativePath=".\Source\GuiInterface.cpp" - > - </File> - <File - RelativePath=".\Source\GuiLabel.cpp" - > - </File> - <File RelativePath=".\Source\InputManager.cpp" > </File> @@ -320,6 +288,42 @@ RelativePath=".\Source\World.cpp" > </File> + <Filter + Name="Gui" + > + <File + RelativePath=".\Source\GuiButton.cpp" + > + </File> + <File + RelativePath=".\Source\GuiCursor.cpp" + > + </File> + <File + RelativePath=".\Source\GuiElement.cpp" + > + </File> + <File + RelativePath=".\Source\GuiEvent.cpp" + > + </File> + <File + RelativePath=".\Source\GuiEventMap.cpp" + > + </File> + <File + RelativePath=".\Source\GuiImage.cpp" + > + </File> + <File + RelativePath=".\Source\GuiInterface.cpp" + > + </File> + <File + RelativePath=".\Source\GuiLabel.cpp" + > + </File> + </Filter> </Filter> <Filter Name="Header Files" @@ -399,43 +403,11 @@ > </File> <File - RelativePath=".\Source\GuiButton.h" - > - </File> - <File - RelativePath=".\Source\GuiCursor.h" - > - </File> - <File - RelativePath=".\Source\GuiElement.h" - > - </File> - <File - RelativePath=".\Source\GuiEvent.h" + RelativePath=".\Source\HashMap.h" > </File> <File - RelativePath=".\Source\GuiEventMap.h" - > - </File> - <File - RelativePath=".\Source\GuiFunctor.h" - > - </File> - <File - RelativePath=".\Source\GuiImage.h" - > - </File> - <File - RelativePath=".\Source\GuiInterface.h" - > - </File> - <File - RelativePath=".\Source\GuiLabel.h" - > - </File> - <File - RelativePath=".\Source\HashMap.h" + RelativePath=".\Source\HashMapIterator.h" > </File> <File @@ -486,6 +458,46 @@ RelativePath=".\Source\World.h" > </File> + <Filter + Name="Gui" + > + <File + RelativePath=".\Source\GuiButton.h" + > + </File> + <File + RelativePath=".\Source\GuiCursor.h" + > + </File> + <File + RelativePath=".\Source\GuiElement.h" + > + </File> + <File + RelativePath=".\Source\GuiEvent.h" + > + </File> + <File + RelativePath=".\Source\GuiEventMap.h" + > + </File> + <File + RelativePath=".\Source\GuiFunctor.h" + > + </File> + <File + RelativePath=".\Source\GuiImage.h" + > + </File> + <File + RelativePath=".\Source\GuiInterface.h" + > + </File> + <File + RelativePath=".\Source\GuiLabel.h" + > + </File> + </Filter> </Filter> <Filter Name="Resource Files"
--- a/LightClone/Source/FixedString.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/FixedString.h Fri Sep 16 15:28:15 2011 -0700 @@ -21,6 +21,28 @@ */ static const uint32 MaximumLength = Size; + /* + * Hash + */ + struct Hash + { + /* + * operator() + */ + uint32 operator()(const FixedString& kString) + { + uint32 nHash = 5381; + + const char* pString = (const char*)kString; + while(*pString) + { + nHash = ((nHash << 5) + nHash) + *pString++; + } + + return nHash; + } + }; + private: /* @@ -112,28 +134,6 @@ }; /* - * FixedStringHash - */ -struct FixedStringHash -{ - /* - * operator() - */ - uint32 operator()(const FixedString<>& kString) - { - uint32 nHash = 5381; - - const char* pString = (const char*)kString; - while(*pString) - { - nHash = ((nHash << 5) + nHash) + *pString++; - } - - return nHash; - } -}; - -/* * operator == */ template<uint32 Size>
--- a/LightClone/Source/GuiButton.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiButton.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -3,6 +3,7 @@ */ #include "GuiButton.h" +#include "GuiInterface.h" #include "VertexTypes.h" /* @@ -85,7 +86,7 @@ */ void GuiButton::Render(RenderContext& kContext, Camera& kCamera) { - if(bVisible) + if(nFlags & GuiElementFlag_Visible) { if(pTexture[nState]) { @@ -200,15 +201,25 @@ } /* + * OnMouseEnter + */ +void GuiButton::OnMouseEnter() +{ +} + +/* + * OnMouseLeave + */ +void GuiButton::OnMouseLeave() +{ +} + +/* * OnMouseDown */ void GuiButton::OnMouseDown(uint32 nButton, float fX, float fY) { - //TODO: Proper states and click handling - GuiEventArguments kArguments; - kArguments.pSource = this; - - Fire(EventClick, kArguments); + pInterface->AcquireCursor(this); } /* @@ -216,6 +227,46 @@ */ void GuiButton::OnMouseUp(uint32 nButton, float fX, float fY) { + if(pInterface->IsCursorAcquiredBy(this)) + { + pInterface->ReleaseCursor(); + + if(Contains(fX, fY)) + { + nState = GuiButtonState_Hover; + + GuiEventArguments kArguments(this); + Fire(EventClick, kArguments); + } + else + { + nState = GuiButtonState_Normal; + } + } +} + +/* + * OnMouseMove + */ +void GuiButton::OnMouseMove(float fX, float fY) +{ + if(pInterface->IsCursorAcquiredBy(this)) + { + if(Contains(fX, fY)) + { + nState = GuiButtonState_Down; + } + else + { + nState = GuiButtonState_Hover; + } + } + else + { + //NOTE: If we're not capturing the mouse we only get mouse + // move events when the cursor is inside the button bounds + nState = GuiButtonState_Hover; + } } /*
--- a/LightClone/Source/GuiButton.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiButton.h Fri Sep 16 15:28:15 2011 -0700 @@ -112,6 +112,16 @@ void SetText(const char* pText); /* + * OnMouseEnter + */ + virtual void OnMouseEnter(); + + /* + * OnMouseLeave + */ + virtual void OnMouseLeave(); + + /* * OnMouseDown */ virtual void OnMouseDown(uint32 nButton, float fX, float fY); @@ -121,6 +131,11 @@ */ virtual void OnMouseUp(uint32 nButton, float fX, float fY); + /* + * OnMouseMove + */ + virtual void OnMouseMove(float fX, float fY); + private: /*
--- a/LightClone/Source/GuiElement.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiElement.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -7,7 +7,7 @@ /* * GuiElement */ -GuiElement::GuiElement() : pContainer(NULL), kPosition(0.0f, 0.0f), kDimensions(0.0f, 0.0f), kColor(0xFFFFFFFF), bVisible(true) +GuiElement::GuiElement() : pContainer(NULL), kPosition(0.0f, 0.0f), kDimensions(0.0f, 0.0f), kColor(0xFFFFFFFF), nFlags(GuiElementFlag_Visible) { } @@ -49,7 +49,7 @@ */ void GuiElement::Render(RenderContext& kContext, Camera& kCamera) { - if(bVisible) + if(nFlags & GuiElementFlag_Visible) { for(uint32 i = 0; i < kChildren.Size(); ++i) { @@ -157,11 +157,27 @@ } /* - * SetVisible + * SetFlag + */ +void GuiElement::SetFlag(uint32 nValue) +{ + nFlags |= nValue; +} + +/* + * ClearFlag */ -void GuiElement::SetVisible(bool bValue) +void GuiElement::ClearFlag(uint32 nValue) { - bVisible = bValue; + nFlags &= ~nValue; +} + +/* + * HasFlag + */ +bool GuiElement::HasFlag(uint32 nValue) const +{ + return (nFlags & nValue) == nValue; } /* @@ -169,7 +185,7 @@ */ bool GuiElement::IsVisible() const { - return bVisible; + return (nFlags & GuiElementFlag_Visible) != 0; } /* @@ -181,12 +197,9 @@ for(int32 i = (int32)kChildren.Size() - 1; i >= 0 && !pElement; --i) { - if(kChildren[i]->bVisible) + if(kChildren[i]->HasFlag(GuiElementFlag_Visible | GuiElementFlag_Pickable)) { - const D3DXVECTOR2& kLocation = kChildren[i]->GetPosition(); - const D3DXVECTOR2& kSize = kChildren[i]->GetDimensions(); - - if(Rectangle2(kLocation.x, kLocation.y, kSize.x, kSize.y).Contains(fX, fY)) + if(kChildren[i]->Contains(fX, fY)) { pElement = kChildren[i]->Pick(fX, fY); } @@ -195,12 +208,9 @@ if(!pElement) { - if(bVisible) + if(HasFlag(GuiElementFlag_Visible | GuiElementFlag_Pickable)) { - const D3DXVECTOR2& kLocation = GetPosition(); - const D3DXVECTOR2& kSize = GetDimensions(); - - if(Rectangle2(kLocation.x, kLocation.y, kSize.x, kSize.y).Contains(fX, fY)) + if(Contains(fX, fY)) { pElement = this; } @@ -250,6 +260,33 @@ } /* + * Contains + */ +bool GuiElement::Contains(float fX, float fY) +{ + const D3DXVECTOR2& kLocation = GetPosition(); + + const float fDeltaX = fX - kLocation.x; + const float fDeltaY = fY - kLocation.y; + + return (0.0f <= fDeltaX && fDeltaX < kDimensions.x) && (0.0f <= fDeltaY && fDeltaY < kDimensions.y); +} + +/* + * OnMouseEnter + */ +void GuiElement::OnMouseEnter() +{ +} + +/* + * OnMouseLeave + */ +void GuiElement::OnMouseLeave() +{ +} + +/* * OnMouseDown */ void GuiElement::OnMouseDown(uint32 nButton, float fX, float fY)
--- a/LightClone/Source/GuiElement.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiElement.h Fri Sep 16 15:28:15 2011 -0700 @@ -13,15 +13,24 @@ #include "GuiEventMap.h" /* - * GuiInterface + * GuiElementFlag */ -class GuiInterface; +enum +{ + GuiElementFlag_Visible = 1 << 0, + GuiElementFlag_Pickable = 1 << 1, +}; /* * GuiElement */ class GuiElement : private GuiEventMap { + /* + * GuiInterface + */ + friend class GuiInterface; + public: /* @@ -57,9 +66,9 @@ D3DCOLOR kColor; /* - * bVisible + * nFlags */ - bool bVisible; + uint32 nFlags; /* * kChildren @@ -159,9 +168,19 @@ float GetHeight() const; /* - * SetVisible + * SetFlag + */ + void SetFlag(uint32 nValue); + + /* + * ClearFlag */ - void SetVisible(bool bValue); + void ClearFlag(uint32 nValue); + + /* + * HasFlag + */ + bool HasFlag(uint32 nValue) const; /* * IsVisible @@ -184,6 +203,33 @@ ErrorCode Remove(GuiElement* pElement); /* + * Contains + */ + bool Contains(float fX, float fY); + + /* + * Subscribe + */ + using GuiEventMap::Subscribe; + + /* + * Fire + */ + using GuiEventMap::Fire; + +protected: + + /* + * OnMouseEnter + */ + virtual void OnMouseEnter(); + + /* + * OnMouseLeave + */ + virtual void OnMouseLeave(); + + /* * OnMouseDown */ virtual void OnMouseDown(uint32 nButton, float fX, float fY); @@ -202,16 +248,6 @@ * OnDrop */ virtual void OnDrop(GuiElement* pSource, float fX, float fY); - - /* - * Subscribe - */ - using GuiEventMap::Subscribe; - - /* - * Fire - */ - using GuiEventMap::Fire; }; #endif //__GUIELEMENT_H__
--- a/LightClone/Source/GuiEvent.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiEvent.h Fri Sep 16 15:28:15 2011 -0700 @@ -23,6 +23,13 @@ * pSource */ GuiElement* pSource; + + /* + * GuiEventArguments + */ + GuiEventArguments(GuiElement* pInstance) : pSource(pInstance) + { + } }; /*
--- a/LightClone/Source/GuiEventMap.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiEventMap.h Fri Sep 16 15:28:15 2011 -0700 @@ -17,7 +17,7 @@ /* * kMap */ - HashMap<FixedString<>, GuiEvent*, FixedStringHash> kMap; + HashMap<FixedString<>, GuiEvent*, FixedString<>::Hash> kMap; public:
--- a/LightClone/Source/GuiImage.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiImage.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -68,7 +68,7 @@ */ void GuiImage::Render(RenderContext& kContext, Camera& kCamera) { - if(bVisible) + if(nFlags & GuiElementFlag_Visible) { if(pTexture) {
--- a/LightClone/Source/GuiInterface.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiInterface.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -71,66 +71,94 @@ pCursor->Update(fElapsed); } - GuiElement* pElement = Pick(fMouseX, fMouseY); - - if(fMouseDeltaX != 0.0f || fMouseDeltaY != 0.0f) + if(pDragElement) { - //Mouse moved - if(pCaptureElement) + if(pInputManager->IsButtonReleased(nDragButton)) + { + EndDrag(Pick(fMouseX, fMouseY), fMouseX, fMouseY); + } + else { - + for(uint32 nButton = MouseButton_Left; nButton < MouseButton_Count; ++nButton) + { + if(pInputManager->IsButtonPressed(nButton) || pInputManager->IsButtonReleased(nButton)) + { + EndDrag(NULL, fMouseX, fMouseY); + } + } } } - - for(uint32 nButton = MouseButton_Left; nButton < MouseButton_Count; ++nButton) + else { - // button down - if(pInputManager->IsButtonDown(nButton) && !pInputManager->WasButtonDown(nButton)) + GuiElement* pElement = Pick(fMouseX, fMouseY); + + if(pFocusElement != pElement) { - if(pCaptureElement) + if(!pCaptureElement) { - //TODO: Does capture make sense for mouse down events? - pElement->OnMouseDown(nButton, fMouseX, fMouseY); + if(pFocusElement) + { + pFocusElement->OnMouseLeave(); + } + + if(pElement) + { + pElement->OnMouseEnter(); + } } - else + + pFocusElement = pElement; + } + + for(uint32 nButton = MouseButton_Left; nButton < MouseButton_Count; ++nButton) + { + // button down + if(pInputManager->IsButtonPressed(nButton)) { + if(pCaptureElement) + { + pElement->OnMouseDown(nButton, fMouseX, fMouseY); + } + else + if(pElement) { pElement->OnMouseDown(nButton, fMouseX, fMouseY); } } - } - else + else - // button up - if(!pInputManager->IsButtonDown(nButton) && pInputManager->WasButtonDown(nButton)) - { - if(pDragElement) - { - GuiElement* pElement = Pick(fMouseX, fMouseY); - if(pElement) - { - pElement->OnDrop(pDragElement, fMouseX, fMouseY); - } - - pDragElement = NULL; - } - else + // button up + if(pInputManager->IsButtonReleased(nButton)) { if(pCaptureElement) { pCaptureElement->OnMouseUp(nButton, fMouseX, fMouseY); } else + + if(pElement) { - GuiElement* pElement = Pick(fMouseX, fMouseY); - if(pElement) - { - pElement->OnMouseUp(nButton, fMouseX, fMouseY); - } + pElement->OnMouseUp(nButton, fMouseX, fMouseY); } } } + + // mouse moved + if(fDeltaX != 0.0f || fDeltaY != 0.0f) + //if(pInputManager->MouseMoved()) + { + if(pCaptureElement) + { + pCaptureElement->OnMouseMove(fMouseX, fMouseY); + } + else + + if(pElement) + { + pElement->OnMouseMove(fMouseX, fMouseY); + } + } } } @@ -142,7 +170,7 @@ //TODO: Begin batch //kContext.BeginBatch(); - if(bVisible) + if(nFlags & GuiElementFlag_Visible) { //TODO: Inside Render functions call kContext.AddToBatch(pTexture, kPosition, kDimensions, kColor) GuiElement::Render(kContext, kCamera); @@ -185,15 +213,33 @@ } /* + * IsCursorAcquiredBy + */ +bool GuiInterface::IsCursorAcquiredBy(GuiElement* pElement) const +{ + return pDragElement == pElement; +} + +/* * BeginDrag */ -void GuiInterface::BeginDrag(GuiElement* pSource) +void GuiInterface::BeginDrag(GuiElement* pSource, uint32 nButton) { + //ASSERT(pDragElement == NULL); + + pDragElement = pSource; + nDragButton = nButton; } /* * EndDrag */ -void GuiInterface::EndDrag() +void GuiInterface::EndDrag(GuiElement* pTarget, float fX, float fY) { + if(pTarget) + { + pTarget->OnDrop(pDragElement, fX, fY); + } + + pDragElement = NULL; }
--- a/LightClone/Source/GuiInterface.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiInterface.h Fri Sep 16 15:28:15 2011 -0700 @@ -31,6 +31,11 @@ GuiElement* pDragElement; /* + * nDragButton + */ + uint32 nDragButton; + + /* * pCaptureElement */ GuiElement* pCaptureElement; @@ -78,14 +83,19 @@ void ReleaseCursor(); /* + * IsCursorAcquiredBy + */ + bool IsCursorAcquiredBy(GuiElement* pElement) const; + + /* * BeginDrag */ - void BeginDrag(GuiElement* pSource); + void BeginDrag(GuiElement* pSource, uint32 nButton); /* * EndDrag */ - void EndDrag(); + void EndDrag(GuiElement* pTarget, float fX, float fY); private:
--- a/LightClone/Source/GuiLabel.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiLabel.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -7,9 +7,8 @@ /* * GuiLabel */ -GuiLabel::GuiLabel() : pResourceManager(NULL), pFont(NULL), nFlags(0), kColor(0xFFFFFFFF) +GuiLabel::GuiLabel() : pResourceManager(NULL), pFont(NULL), nLabelFlags(0) { - memset(kLabel, 0, sizeof(kLabel)); } /* @@ -44,7 +43,7 @@ */ void GuiLabel::Render(RenderContext& kContext, Camera& kCamera) { - if(bVisible) + if(nFlags & GuiElementFlag_Visible) { if(pFont) { @@ -56,21 +55,20 @@ kRectangle.right = (int32)kLocation.x; kRectangle.bottom = (int32)kLocation.y; - uint32 nLength = strlen(kLabel); uint32 nFormat = 0; - if(nFlags & GuiLabelFlag_CenterX) + if(nLabelFlags & GuiLabelFlag_CenterX) { nFormat |= DT_CENTER; } - if(nFlags & GuiLabelFlag_CenterY) + if(nLabelFlags & GuiLabelFlag_CenterY) { nFormat |= DT_VCENTER; } - pFont->DrawTextA(NULL, kLabel, nLength, &kRectangle, nFormat | DT_CALCRECT, kColor); - pFont->DrawTextA(NULL, kLabel, nLength, &kRectangle, nFormat, kColor); + pFont->DrawTextA(NULL, kLabel, kLabel.Length(), &kRectangle, nFormat | DT_CALCRECT, kColor); + pFont->DrawTextA(NULL, kLabel, kLabel.Length(), &kRectangle, nFormat, kColor); } GuiElement::Render(kContext, kCamera); @@ -96,30 +94,21 @@ */ ErrorCode GuiLabel::SetText(const char* pText) { - ErrorCode eCode = Error_Fail; - - uint32 nLength = strlen(pText); - if(nLength < MaximumLabelLength) - { - strncpy_s(kLabel, pText, nLength); - eCode = Error_Success; - } - - return eCode; + return kLabel = pText, Error_Success; } /* - * SetFlags + * SetLabelFlag */ -ErrorCode GuiLabel::SetFlags(uint32 nValue) +ErrorCode GuiLabel::SetLabelFlag(uint32 nValue) { - return nFlags |= nValue, Error_Success; + return nLabelFlags |= nValue, Error_Success; } /* - * ClearFlags + * ClearLabelFlag */ -ErrorCode GuiLabel::ClearFlags(uint32 nValue) +ErrorCode GuiLabel::ClearLabelFlag(uint32 nValue) { - return nFlags &= ~nValue, Error_Success; + return nLabelFlags &= ~nValue, Error_Success; } \ No newline at end of file
--- a/LightClone/Source/GuiLabel.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/GuiLabel.h Fri Sep 16 15:28:15 2011 -0700 @@ -7,6 +7,7 @@ #include "Core.h" #include "GuiElement.h" +#include "FixedString.h" /* * GuiLabelFlag @@ -23,11 +24,6 @@ class GuiLabel : public GuiElement { /* - * MaximumLabelLength - */ - static const uint32 MaximumLabelLength = 32; - - /* * pResourceManager */ ResourceManager* pResourceManager; @@ -40,17 +36,12 @@ /* * kLabel */ - char kLabel[MaximumLabelLength]; + FixedString<> kLabel; /* - * nFlags + * nLabelFlags */ - uint32 nFlags; - - /* - * kColor - */ - D3DCOLOR kColor; + uint32 nLabelFlags; public: @@ -90,14 +81,14 @@ ErrorCode SetText(const char* pText); /* - * SetFlags + * SetLabelFlag */ - ErrorCode SetFlags(uint32 nFlags); + ErrorCode SetLabelFlag(uint32 nFlag); /* - * ClearFlags + * ClearLabelFlag */ - ErrorCode ClearFlags(uint32 nFlags); + ErrorCode ClearLabelFlag(uint32 nFlag); }; #endif //__GUILABEL_H__
--- a/LightClone/Source/HashMap.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/HashMap.h Fri Sep 16 15:28:15 2011 -0700 @@ -6,6 +6,7 @@ #define __HASHMAP_H__ #include "Types.h" +#include "HashMapIterator.h" /* * DefaultHash @@ -56,6 +57,25 @@ } }; +public: + + /* + * KeyType + */ + typedef Key KeyType; + + /* + * ValueType + */ + typedef Value ValueType; + + /* + * Iterator + */ + typedef HashMapIterator<HashMap<Key, Value, HashFunction, Size>, Value> Iterator; + +private: + /* * pTable */ @@ -71,7 +91,7 @@ /* * HashMap */ - HashMap() //: kHash() + HashMap() { for(uint32 i = 0; i < Size; ++i) { @@ -121,6 +141,16 @@ return NULL; } + /* + * Begin + */ + Iterator Begin(); + + /* + * End + */ + Iterator End(); + private: /*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LightClone/Source/HashMapIterator.h Fri Sep 16 15:28:15 2011 -0700 @@ -0,0 +1,94 @@ +/* + * HashMapIterator + */ + +#ifndef __HASHMAPITERATOR_H__ +#define __HASHMAPITERATOR_H__ + +#include "Types.h" + +/* + * HashMapIterator + */ +template<typename Map, typename Value> +class HashMapIterator +{ + /* + * pMap + */ + Map* pMap; + + /* + * nSize + */ + uint32 nSize; + + /* + * pNode + */ + typename Map::Node* pNode; + + /* + * nSlot + */ + uint32 nSlot; + +public: + + /* + * HashMapIterator + */ + HashMapIterator(Map* pInstance, uint32 nInstanceSize) : pMap(pInstance), nSize(nInstanceSize), pNode(NULL), nSlot(0) + { + } + + /* + * HashMapIterator + */ + HashMapIterator(Map* pInstance, uint32 nInstanceSize, uint32 nStart) : pMap(pInstance), nSize(nInstanceSize), pNode(NULL), nSlot(nStart) + { + //pNode = pInstance->pTable[nSlot]; + } + + /* + * operator ++ + */ + HashMapIterator& operator ++() + { + return *this; + } + + /* + * operator ++ + */ + HashMapIterator& operator ++(int) + { + return *this; + } + + /* + * operator * + */ + Value operator *() + { + return pNode ? pNode->kValue : Value(); + } + + /* + * operator == + */ + bool operator ==(HashMapIterator& kOther) + { + return nSlot == kOther.nSlot && pNode == kOther.pNode; + } + + /* + * operator != + */ + bool operator !=(HashMapIterator& kOther) + { + return nSlot != kOther.nSlot || pNode != kOther.pNode; + } +}; + +#endif //__HASHMAPITERATOR_H__
--- a/LightClone/Source/InputManager.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/InputManager.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -270,6 +270,22 @@ } /* + * IsButtonPressed + */ +bool InputManager::IsButtonPressed(uint32 nButton) const +{ + return ((kCurrentMouseState.rgbButtons[nButton] & 0x80) != 0) && ((kPreviousMouseState.rgbButtons[nButton] & 0x80) == 0); +} + +/* + * IsButtonReleased + */ +bool InputManager::IsButtonReleased(uint32 nButton) const +{ + return ((kCurrentMouseState.rgbButtons[nButton] & 0x80) == 0) && ((kPreviousMouseState.rgbButtons[nButton] & 0x80) == 0); +} + +/* * GetMouseX */ float InputManager::GetMouseX() const @@ -283,4 +299,20 @@ float InputManager::GetMouseY() const { return fMouseY; +} + +/* + * GetMouseDeltaX + */ +float InputManager::GetMouseDeltaX() const +{ + return (float)kCurrentMouseState.lX; +} + +/* + * GetMouseDeltaY + */ +float InputManager::GetMouseDeltaY() const +{ + return (float)kCurrentMouseState.lY; } \ No newline at end of file
--- a/LightClone/Source/InputManager.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/InputManager.h Fri Sep 16 15:28:15 2011 -0700 @@ -35,6 +35,7 @@ MouseButton_Left, MouseButton_Right, MouseButton_Middle, + MouseButton_Count, }; /* @@ -193,6 +194,16 @@ bool WasButtonDown(uint32 nButton) const; /* + * IsButtonPressed + */ + bool IsButtonPressed(uint32 nButton) const; + + /* + * IsButtonReleased + */ + bool IsButtonReleased(uint32 nButton) const; + + /* * GetMouseX */ float GetMouseX() const; @@ -201,6 +212,16 @@ * GetMouseY */ float GetMouseY() const; + + /* + * GetMouseDeltaX + */ + float GetMouseDeltaX() const; + + /* + * GetMouseDeltaY + */ + float GetMouseDeltaY() const; }; #endif //__INPUTMANAGER_H__
--- a/LightClone/Source/ResourceManager.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/ResourceManager.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -5,6 +5,41 @@ #include "ResourceManager.h" /* + * CreateTextureHelper + */ +ErrorCode CreateTextureHelper(GraphicsDevice* pDevice, const char* pName, IDirect3DTexture9** pTexture) +{ + const uint32 nSizeX = D3DX_DEFAULT_NONPOW2; + const uint32 nSizeY = D3DX_DEFAULT_NONPOW2; + const uint32 nFilter = D3DX_DEFAULT; + const uint32 nFilterMip = D3DX_DEFAULT; + + return SUCCEEDED(D3DXCreateTextureFromFileExA(*pDevice, pName, nSizeX, nSizeY, 0, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, nFilter, nFilterMip, 0, NULL, NULL, pTexture)) ? Error_Success : Error_Fail; +} + +/* + * CreateEffectHelper + */ +ErrorCode CreateEffectHelper(GraphicsDevice* pDevice, const char* pName, ID3DXEffect** pEffect) +{ + ID3DXBuffer* pBuffer = NULL; + return SUCCEEDED(D3DXCreateEffectFromFileA(*pDevice, pName, NULL, NULL, 0, NULL, pEffect, &pBuffer)) ? Error_Success : Error_Fail; +} + +/* + * CreateFontHelper + */ +ErrorCode CreateFontHelper(GraphicsDevice* pDevice, const char* pName, uint32 nSize, uint32 nWeight, ID3DXFont** pFont) +{ + const uint32 nCharset = DEFAULT_CHARSET; + const uint32 nPrecision = OUT_DEFAULT_PRECIS; + const uint32 nQuality = DEFAULT_QUALITY; + const uint32 nPitch = DEFAULT_PITCH | FF_DONTCARE; + + return SUCCEEDED(D3DXCreateFontA(*pDevice, nSize, 0, nWeight, 1, FALSE, nCharset, nPrecision, nQuality, nPitch, pName, pFont)) ? Error_Success : Error_Fail; +} + +/* * ResourceManager */ ResourceManager::ResourceManager() @@ -24,6 +59,9 @@ */ void ResourceManager::Terminate() { + //TODO: Iterate over each cache and release resources + + pGraphicsDevice = NULL; } @@ -36,16 +74,25 @@ if(pGraphicsDevice) { - const uint32 nSizeX = D3DX_DEFAULT_NONPOW2; - const uint32 nSizeY = D3DX_DEFAULT_NONPOW2; - const uint32 nFilter = D3DX_DEFAULT; - const uint32 nFilterMip = D3DX_DEFAULT; - - HRESULT hResult = D3DXCreateTextureFromFileExA(*pGraphicsDevice, pName, nSizeX, nSizeY, 0, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, nFilter, nFilterMip, 0, NULL, NULL, pTexture); - if(SUCCEEDED(hResult)) + IDirect3DTexture9** pInstance = kTextureCache.Find(ResourcePath(pName)); + if(!pInstance) + { + pInstance = kTextureCache.Add(ResourcePath(pName)); + if(pInstance) + { + eCode = CreateTextureHelper(pGraphicsDevice, pName, pInstance); + } + } + else { eCode = Error_Success; } + + if(eCode == Error_Success) + { + if(pTexture) + *pTexture = *pInstance; + } } return eCode; @@ -60,13 +107,58 @@ if(pGraphicsDevice) { - ID3DXBuffer* pBuffer = NULL; - - HRESULT hResult = D3DXCreateEffectFromFileA(*pGraphicsDevice, pName, NULL, NULL, 0, NULL, pEffect, &pBuffer); - if(SUCCEEDED(hResult)) + ID3DXEffect** pInstance = kEffectCache.Find(ResourcePath(pName)); + if(!pInstance) + { + pInstance = kEffectCache.Add(ResourcePath(pName)); + if(pInstance) + { + eCode = CreateEffectHelper(pGraphicsDevice, pName, pInstance); + } + } + else { eCode = Error_Success; } + + if(eCode == Error_Success) + { + if(pEffect) + *pEffect = *pInstance; + } + } + + return eCode; +} + +/* + * CreateFontFromName + */ +ErrorCode ResourceManager::CreateFontFromName(const char* pName, uint32 nSize, uint32 nWeight, ID3DXFont** pFont) +{ + ErrorCode eCode = Error_Fail; + + if(pGraphicsDevice) + { + ID3DXFont** pInstance = kFontCache.Find(ResourcePath(pName)); + if(!pInstance) + { + pInstance = kFontCache.Add(ResourcePath(pName)); + if(pInstance) + { + eCode = CreateFontHelper(pGraphicsDevice, pName, nSize, nWeight, pInstance); + } + } + else + { + eCode = Error_Success; + } + + if(eCode == Error_Success) + { + if(pFont) + *pFont = *pInstance; + } } return eCode; @@ -81,8 +173,7 @@ if(pGraphicsDevice) { - //HRESULT hResult = ((IDirect3DDevice9*)*pGraphicsDevice)->CreateVertexBuffer(nSize, nUsage, 0, (D3DPOOL)nPool, pBuffer, NULL); - HRESULT hResult = static_cast<IDirect3DDevice9*>(*pGraphicsDevice)->CreateVertexBuffer(nSize, nUsage, 0, (D3DPOOL)nPool, pBuffer, NULL); + HRESULT hResult = ((IDirect3DDevice9*)*pGraphicsDevice)->CreateVertexBuffer(nSize, nUsage, 0, (D3DPOOL)nPool, pBuffer, NULL); if(SUCCEEDED(hResult)) { eCode = Error_Success; @@ -91,22 +182,3 @@ return eCode; } - -/* - * CreateFontFromName - */ -ErrorCode ResourceManager::CreateFontFromName(const char* pName, uint32 nSize, uint32 nWeight, ID3DXFont** pFont) -{ - ErrorCode eCode = Error_Fail; - - if(pGraphicsDevice) - { - HRESULT hResult = D3DXCreateFontA(*pGraphicsDevice, nSize, 0, nWeight, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, pName, pFont); - if(SUCCEEDED(hResult)) - { - eCode = Error_Success; - } - } - - return eCode; -}
--- a/LightClone/Source/ResourceManager.h Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/ResourceManager.h Fri Sep 16 15:28:15 2011 -0700 @@ -7,6 +7,26 @@ #include "Core.h" #include "GraphicsDevice.h" +#include "FixedString.h" +#include "HashMap.h" + +/* + * ResourceType + */ +enum +{ + ResourceType_Texture, + ResourceType_Effect, + ResourceType_Font, + ResourceType_VertexBuffer, + ResourceType_IndexBuffer, +}; + +/* + * ResourcePath + * TODO: Wasting memory + */ +typedef FixedString<> ResourcePath; /* * ResourceManager @@ -18,6 +38,21 @@ */ GraphicsDevice* pGraphicsDevice; + /* + * kTextureCache + */ + HashMap<ResourcePath, IDirect3DTexture9*, ResourcePath::Hash> kTextureCache; + + /* + * kEffectCache + */ + HashMap<ResourcePath, ID3DXEffect*, ResourcePath::Hash> kEffectCache; + + /* + * kFontCache + */ + HashMap<ResourcePath, ID3DXFont*, ResourcePath::Hash> kFontCache; + public: /* @@ -46,14 +81,14 @@ ErrorCode CreateEffectFromFile(const char* pName, ID3DXEffect** pEffect); /* + * CreateFontFromName + */ + ErrorCode CreateFontFromName(const char* pName, uint32 nSize, uint32 nWeight, ID3DXFont** pFont); + + /* * CreateVertexBuffer */ ErrorCode CreateVertexBuffer(uint32 nSize, uint32 nUsage, uint32 nPool, IDirect3DVertexBuffer9** pBuffer); - - /* - * CreateFontFromName - */ - ErrorCode CreateFontFromName(const char* pName, uint32 nSize, uint32 nWeight, ID3DXFont** pFont); }; #endif //__RESOURCEMANAGER_H__
--- a/LightClone/Source/World.cpp Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/Source/World.cpp Fri Sep 16 15:28:15 2011 -0700 @@ -322,7 +322,7 @@ pLevelDialog = new GuiImage(); pLevelDialog->Initialize(pResourceManager); - pLevelDialog->SetVisible(false); + pLevelDialog->ClearFlag(GuiElementFlag_Visible); pLevelDialog->SetTexture("Data\\Textures\\Dialog0.tga", true); pLevelDialog->SetPosition(0.5f * (ScreenSizeX - pLevelDialog->GetWidth()), 0.5f * (ScreenSizeY - pLevelDialog->GetHeight())); @@ -350,7 +350,7 @@ pGameDialog = new GuiImage(); pGameDialog->Initialize(pResourceManager); - pGameDialog->SetVisible(false); + pGameDialog->ClearFlag(GuiElementFlag_Visible); pGameDialog->SetTexture("Data\\Textures\\Dialog0.tga", true); pGameDialog->SetPosition(0.5f * (ScreenSizeX - pGameDialog->GetWidth()), 0.5f * (ScreenSizeY - pGameDialog->GetHeight())); //pGameDialog->Add(pGameDialogOk);
--- a/LightClone/ToDo.txt Fri Sep 16 13:11:35 2011 -0700 +++ b/LightClone/ToDo.txt Fri Sep 16 15:28:15 2011 -0700 @@ -5,12 +5,8 @@ 5. Pause menu 6. Robot model & texture 7. Implement confirm exit dialog -8. Help interface -9. Add button to clear code panes +8. Help interface +9. Add button to clear code panes 10. Implement drag and drop - a. Implement mouse capturing - b. Add drag and drop interface to GuiInterface and move handling into subclasses -11. Add flags to gui elements (picking, visibility) -12. Implement caching in the resource manager -13. Implement gui batching -14. Add GuiInterface reference to GuiElement \ No newline at end of file + a. Add drag and drop interface to GuiInterface and move handling into subclasses +11. Implement gui batching \ No newline at end of file