Explorar o código

Fixed drag and drop so that mouse capture change event doesn't incorrectly fire before the mouse up event, prematurely stopping the drop action

Marko Pintera %!s(int64=10) %!d(string=hai) anos
pai
achega
53ff33bd57

+ 3 - 0
BansheeCore/Source/Win32/BsWin32Platform.cpp

@@ -1083,12 +1083,15 @@ namespace BansheeEngine
 				break;
 			}
 		case WM_BS_SETCAPTURE:
+			LOGWRN("SET CAPTURE");
 			SetCapture(hWnd);
 			break;
 		case WM_BS_RELEASECAPTURE:
+			LOGWRN("RELEASE CAPTURE");
 			ReleaseCapture();
 			break;
 		case WM_CAPTURECHANGED:
+			LOGWRN("CAPTURE CHANGED");
 			if(!onMouseCaptureChanged.empty())
 				onMouseCaptureChanged();
 			return 0;

+ 1 - 0
BansheeEngine/Include/BsDragAndDropManager.h

@@ -127,5 +127,6 @@ namespace BansheeEngine
 
 		std::atomic<bool> mCaptureChanged;
 		std::atomic<int> mCaptureActive;
+		std::atomic<unsigned long> mCaptureChangeFrame;
 	};
 }

+ 5 - 1
BansheeEngine/Source/BsDragAndDropManager.cpp

@@ -1,6 +1,7 @@
 #include "BsDragAndDropManager.h"
 #include "BsPlatform.h"
 #include "BsCoreApplication.h"
+#include <BsTime.h>
 
 using namespace std::placeholders;
 
@@ -47,9 +48,11 @@ namespace BansheeEngine
 
 		// This generally happens when window loses focus and capture is lost (e.g. alt+tab)
 		int captureActive = mCaptureActive.load();
-		if(!captureActive && mCaptureChanged.load())
+		if (!captureActive && mCaptureChanged.load() && 
+			(gTime().getFrameNumber() > mCaptureChangeFrame.load())) // Wait one frame to insure input (like mouse up) gets a chance to be processed
 		{
 			endDrag(false);
+			mCaptureChanged.store(false);
 		}
 	}
 
@@ -68,6 +71,7 @@ namespace BansheeEngine
 	{
 		mCaptureActive.fetch_xor(1); // mCaptureActive = !mCaptureActive;
 		mCaptureChanged.store(true);
+		mCaptureChangeFrame.store(gTime().getFrameNumber());
 	}
 
 	void DragAndDropManager::cursorReleased(const PointerEvent& event)

+ 5 - 3
BansheeUtility/Include/BsTime.h

@@ -8,7 +8,7 @@ namespace BansheeEngine
 	/**
 	 * @brief	Manages all time related functionality.
 	 * 			
-	 * @note	Sim thread only 
+	 * @note	Sim thread only unless where specified otherwise.
 	 */
 	class BS_UTILITY_EXPORT Time : public Module<Time>
 	{
@@ -44,8 +44,10 @@ namespace BansheeEngine
 		 * @brief	Returns the number of the current frame. First frame is 0.
 		 *
 		 * @return	The current frame.
+		 *
+		 * @note	Thread safe, but only counts sim thread frames.
 		 */
-		unsigned long getFrameNumber() const { return mCurrentFrame; }
+		unsigned long getFrameNumber() const { return mCurrentFrame.load(); }
 
 		/**
 		 * @brief	Returns the precise time since application start, in microseconds.
@@ -84,7 +86,7 @@ namespace BansheeEngine
 
 		UINT64 mAppStartTime; /**< Time the application started, in microseconds */
 		unsigned long mLastFrameTime; /**< Time since last runOneFrame call, In microseconds */
-		unsigned long mCurrentFrame;
+		std::atomic<unsigned long> mCurrentFrame;
 
 		Timer* mTimer;
 	};

+ 2 - 2
BansheeUtility/Source/BsTime.cpp

@@ -6,7 +6,7 @@ namespace BansheeEngine
 	const double Time::MICROSEC_TO_SEC = 1.0/1000000.0;
 
 	Time::Time()
-		:mAppStartTime(0), mLastFrameTime(0), mFrameDelta(0.0f), mTimeSinceStart(0.0f), mCurrentFrame(0)
+		:mAppStartTime(0), mLastFrameTime(0), mFrameDelta(0.0f), mTimeSinceStart(0.0f), mCurrentFrame(0UL)
 	{
 		mTimer = bs_new<Timer>();
 		mAppStartTime = (UINT64)mTimer->getStartMs();
@@ -28,7 +28,7 @@ namespace BansheeEngine
 
 		mLastFrameTime = currentFrameTime;
 
-		mCurrentFrame++;
+		mCurrentFrame.fetch_add(1, std::memory_order_relaxed);
 	}
 
 	UINT64 Time::getTimePrecise() const

+ 0 - 3
TODO.txt

@@ -26,9 +26,6 @@ return them in checkForModifications?
 Project window
 
 Dropping doesn't work. endDrag in DragAndDropManager gets called before cursorReleased()
-Destroying Renderable objects doesn't seem to properly clear them from the renderer
-Add mesh scale to FBX importer (and default it to 0.01 or whatever makes the dragon look normal sized)
-There's still an issue with dragging a selection area in the scroll box
 
 Later:
  - Hook up ping effect so it triggers when I select a resource or sceneobject