Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "prerelease",
"comment": "Use DispatcherQueue instead of CoreDispatcher for Mso::DispatchQueue",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch",
"date": "2020-05-12T18:18:15.956Z"
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ struct SampleModuleCppImpl {
void Initialize(ReactContext const &reactContext) noexcept {
const ReactPropertyId<int> myProp1{L"Prop1"};
const ReactPropertyId<winrt::hstring> myProp2{L"Prop2"};
DEBUG_OUTPUT("globalProps.Prop1:", *reactContext.Properties().Get(myProp1));
DEBUG_OUTPUT("instanceProps.Prop2:", winrt::to_string(*reactContext.Properties().Get(myProp2)));
DEBUG_OUTPUT("C++ Properties.Prop1:", *reactContext.Properties().Get(myProp1));
DEBUG_OUTPUT("C++ Properties.Prop2:", winrt::to_string(*reactContext.Properties().Get(myProp2)));

m_timer = winrt::Windows::System::Threading::ThreadPoolTimer::CreatePeriodicTimer(
[this](const winrt::Windows::System::Threading::ThreadPoolTimer) noexcept {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ internal sealed class SampleModuleCS
[ReactInitializer]
public void Initialize(ReactContext reactContext)
{
Debug.WriteLine($"C# globalProps.Prop1: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop1"))}");
Debug.WriteLine($"C# instanceProps.Prop2: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop2"))}");
Debug.WriteLine($"C# Properties.Prop1: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop1"))}");
Debug.WriteLine($"C# Properties.Prop2: {reactContext.Handle.Properties.Get(ReactPropertyBagHelper.GetName(null, "Prop2"))}");

_timer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler((timer) =>
{
Expand Down
3 changes: 3 additions & 0 deletions packages/playground/windows/playground-win32.sln
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\..\..\vnext\Co
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\..\..\vnext\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\..\..\vnext\ReactWindowsCore\ReactWindowsCore.vcxitems*{11c084a3-a57c-4296-a679-cac17b603144}*SharedItemsImports = 4
..\..\..\vnext\Chakra\Chakra.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4
..\..\..\vnext\Mso\Mso.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4
..\..\..\vnext\Shared\Shared.vcxitems*{2d5d43d9-cffc-4c40-b4cd-02efb4e2742b}*SharedItemsImports = 4
..\..\..\vnext\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{8b88ffae-4dbc-49a2-afa5-d2477d4ad189}*SharedItemsImports = 4
..\..\..\vnext\JSI\Shared\JSI.Shared.vcxitems*{a62d504a-16b8-41d2-9f19-e2e86019e5e4}*SharedItemsImports = 4
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
Expand Down
44 changes: 44 additions & 0 deletions vnext/Microsoft.ReactNative/IReactDispatcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "pch.h"
#include "IReactDispatcher.h"
#include "ReactDispatcherHelper.g.cpp"

using namespace winrt;
using namespace Windows::Foundation;

namespace winrt::Microsoft::ReactNative {
Copy link
Contributor

@JunielKatarn JunielKatarn May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why prefix these namespaces winrt::? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The winrt:: prefix is commonly used for the C++/WinRT components. It is used by default by the C++/WinRT code generator. It is much easier to author our own components in that namespace. Plus, we can use many winrt functions without prefixes.
Do you think it would be preferable not to use it?


In reply to: 424007290 [](ancestors = 424007290)


ReactDispatcher::ReactDispatcher(Mso::DispatchQueue &&queue) noexcept : m_queue{std::move(queue)} {}

bool ReactDispatcher::HasThreadAccess() noexcept {
return m_queue.HasThreadAccess();
}

void ReactDispatcher::Post(ReactDispatcherCallback const &callback) noexcept {
return m_queue.Post([callback]() noexcept { callback(); });
}

/*static*/ Mso::DispatchQueue ReactDispatcher::GetUIDispatchQueue(IReactPropertyBag const &properties) noexcept {
return GetUIDispatcher(properties).as<ReactDispatcher>()->m_queue;
}

/*static*/ IReactDispatcher ReactDispatcher::UIThreadDispatcher() noexcept {
return make<ReactDispatcher>(Mso::DispatchQueue::MakeCurrentThreadUIQueue());
}

/*static*/ ReactPropertyId<IReactDispatcher> ReactDispatcher::UIDispatcherProperty() noexcept {
static ReactPropertyId<IReactDispatcher> uiThreadDispatcherProperty{L"ReactNative.Dispatcher", L"UIDispatcher"};
return uiThreadDispatcherProperty;
}

/*static*/ IReactDispatcher ReactDispatcher::GetUIDispatcher(IReactPropertyBag const &properties) noexcept {
return ReactPropertyBag{properties}.Get(UIDispatcherProperty());
}

/*static*/ void ReactDispatcher::SetUIThreadDispatcher(IReactPropertyBag const &properties) noexcept {
ReactPropertyBag{properties}.Set(UIDispatcherProperty(), UIThreadDispatcher());
}

} // namespace winrt::Microsoft::ReactNative
52 changes: 52 additions & 0 deletions vnext/Microsoft.ReactNative/IReactDispatcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once
#include "ReactDispatcherHelper.g.h"
#include <ReactPropertyBag.h>
#include <dispatchQueue/dispatchQueue.h>
#include <winrt/Microsoft.ReactNative.h>

namespace winrt::Microsoft::ReactNative {

struct ReactDispatcher : implements<ReactDispatcher, IReactDispatcher> {
ReactDispatcher() = default;
ReactDispatcher(Mso::DispatchQueue &&queue) noexcept;
Copy link

@NikoAri NikoAri May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DispatchQueue [](start = 23, length = 13)

(nit) why not IDispatchQueue? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The open source implementation of the DispatchQueue is different. We do not use the interface directly anymore. Instead, the DispatchQueue is a wrapper of the interface similar to what we do with the Mso::Future or Mso::Promise.
The good thing about having a wrapper class like Mso::DispatchQueue is that we can have template methods there, static methods, and all the DispatchQueue APIs are grouped under one class that makes it IntelliSense friendly.


In reply to: 423963640 [](ancestors = 423963640)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the mechanism you describe above allow people to provide their own dispatcher implementations?


In reply to: 423982263 [](ancestors = 423982263,423963640)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the new Mso::DispatchQueue model we have only one Mso::DispatchQueue class that manages queue of tasks. Then we have IDispatchQueueScheduler interface that can run these tasks according to specific rules on the threads it wants. It is relatively small interface and developers can provide their own implementation of it. By implementing custom IDispatchQueueScheduler interface, developers can implement a 'custom queue' when they give it to the Mso::DispatchQueue constructor.


In reply to: 423983579 [](ancestors = 423983579,423982263,423963640)


bool HasThreadAccess() noexcept;
void Post(ReactDispatcherCallback const &callback) noexcept;
Copy link

@NikoAri NikoAri May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

& [](start = 42, length = 1)

Why not &&? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is C++/WinRT thing : they pass parameters by const&. I will check again if we can use && in places like this, but my previous tries were not successful.


In reply to: 423967144 [](ancestors = 423967144)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it. It does not compile. The C++/WinRT uses const&.


In reply to: 423983290 [](ancestors = 423983290,423967144)


static Mso::DispatchQueue GetUIDispatchQueue(IReactPropertyBag const &properties) noexcept;

static IReactDispatcher UIThreadDispatcher() noexcept;
Copy link

@NikoAri NikoAri May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UIThreadDispatcher [](start = 26, length = 18)

Should this match api on line 23? Eg: GetUIThreadDispatcher? or the other way around? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are tow different APIs:

  • UIThreadDispatcher returns IReactDispatcher associated with the current UI thread.
  • GetUIThreadDispatcher is an 'attached property' method that returns UIThreadDispatcher stored in the property bag.

In reply to: 423966470 [](ancestors = 423966470)

Copy link

@NikoAri NikoAri May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IReactDispatcher [](start = 9, length = 16)

(nit) shouldn't this be a pointer? Or winrt idl is smart for this type of object? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++/WinRT interface-looking types are actually smart pointers to a real ABI interface.


In reply to: 423966942 [](ancestors = 423966942)

static ReactPropertyId<IReactDispatcher> UIDispatcherProperty() noexcept;
static IReactDispatcher GetUIDispatcher(IReactPropertyBag const &properties) noexcept;
static void SetUIThreadDispatcher(IReactPropertyBag const &properties) noexcept;

private:
Mso::DispatchQueue m_queue;
};

} // namespace winrt::Microsoft::ReactNative

namespace winrt::Microsoft::ReactNative::implementation {

struct ReactDispatcherHelper {
ReactDispatcherHelper() = default;

static IReactDispatcher UIThreadDispatcher() noexcept {
return ReactDispatcher::UIThreadDispatcher();
}

static IReactPropertyName UIDispatcherProperty() noexcept {
return ReactDispatcher::UIDispatcherProperty().Handle();
}
};

} // namespace winrt::Microsoft::ReactNative::implementation

namespace winrt::Microsoft::ReactNative::factory_implementation {

struct ReactDispatcherHelper : ReactDispatcherHelperT<ReactDispatcherHelper, implementation::ReactDispatcherHelper> {};

} // namespace winrt::Microsoft::ReactNative::factory_implementation
32 changes: 32 additions & 0 deletions vnext/Microsoft.ReactNative/IReactDispatcher.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import "IReactPropertyBag.idl";

namespace Microsoft.ReactNative {

// The delegate is used to create property value on-demand.
[webhosthidden]
delegate void ReactDispatcherCallback();

[webhosthidden]
interface IReactDispatcher
Copy link
Contributor

@aeulitz aeulitz May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this replace the IMessageQueue interface (see Desktop/ABI/MessageQueue.idl)? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, yes. I was not aware about it.


In reply to: 423980262 [](ancestors = 423980262)

{
// True if dispatcher uses current thread.
Boolean HasThreadAccess { get; };

// Post task for the asynchronous execution.
void Post(ReactDispatcherCallback callback);
}

// Helper methods for the property bag implementation.
[webhosthidden]
static runtimeclass ReactDispatcherHelper
Copy link
Contributor

@aeulitz aeulitz May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static runtimeclass ReactDispatcherHelper [](start = 2, length = 41)

Nit: Should we keep it at one type per file? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we do not have such requirement. Seeing how slow the MIDL compiler is, I would say the opposite: less IDL files we have is better. I would rather use the IDL files as a group of definitions related to some functionality.


In reply to: 423987808 [](ancestors = 423987808)

{
// Get or create IReactDispatcher for the current UI thread.
static IReactDispatcher UIThreadDispatcher{ get; };
Copy link
Contributor

@NickGerleman NickGerleman May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this exposed to consumers? From what I understood we weren't sure yet how we wanted to treat the multi-UI-thread scenario. I worry that anything we do expose would be hard to walk back. #Resolved

Copy link
Contributor

@NickGerleman NickGerleman May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I think I misinterpreted the API. If this is just for getting the dispatcher of current thread that makes sense. Questions above still apply to UIThreadDispatcherProperty though. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property is per thread. It does not matter what we decide in future: this code will work in any case. There is no such thing as 'perfect API'. This design works today. Tomorrow if we have new requirements we will change it.


In reply to: 423970645 [](ancestors = 423970645)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is about getting dispatcher of the current thread. The UIThreadDispatcherProperty can be used to set the UIThreadDispatcher in the ReactPropertyBag.


In reply to: 423981509 [](ancestors = 423981509)

Copy link
Contributor

@NickGerleman NickGerleman May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vmoroz are external native modules expected to use this? "Tomorrow if we have new requirements we will change it." becomes painful if users start relying on this. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the current vision is that developers of native modules can access IReactDispatcher of current UI thread using this API. This is a new API. I cannot give you 100% guarantee that this is the final one. It must tested by real usage first. I do not believe we any new API where we can provide such guarantee. I am not sure what is your concern here. Did you ever create API that you never changed?


In reply to: 423993539 [](ancestors = 423993539)

Copy link
Contributor

@NickGerleman NickGerleman May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course we will sometimes need to make changes. It's just much more expensive to do this for the public API of a package where we don't control consumers.

For internal code, or if we're in a monorepo setup like Office, we can just fixup old code using an API we don't like. It's much more expensive to do this for RNW. We either make sudden breaks, which has been a big cause of customer frustration, or we need to do phased deprecation, which is a but less painful, but annoying to track and maintain.

In this instance, we know we have the potential to run into some issues with the current design. It feels like we could avoid pain if we can prevent these rapid changes. E.g. expose this internally for now.

Consumers can still manually inject a queue of their own property if they're okay with it being instance global. Directing people towards that would avoid needing to deal with breaks and user frustration if we decide we can do something better. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"In this instance, we know we have the potential to run into some issues with the current design." Could you please share what you see as an issue?
Previous design was not multi UI thread friendly. This one makes it more friendly, but we still must provide a dedicated UI thread per RNH. It is not a 'true' multi-UI concept, but we must do it today because many native components and RN itself needs it. So, as any other engineering solution we must implement some kind of 'transitional' design. But even if multi-UI will never happen this current design is still much better and more usable comparing to what we have today.

I would like to understand what type of design issue you see that makes you block this PR.


In reply to: 424009257 [](ancestors = 424009257)

Copy link
Contributor

@NickGerleman NickGerleman May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't sure how long-term multi-ui thread was. From the last discussion I was under the impression there was some active effort there, but now it sounds like it's further out. Just wanting to make sure we don't break this too quickly or box ourselves into a corner.

Signing off. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the sign off!
As we discussed offline before, the core issue with the multi-UI threads are the core native modules and the core RN that relies on the single UI thread.
This change allows us to bring the UI queue to the RNH as an external entity. The RNH does not create it anymore. This design change moves us closer to the multi-UI threads if we ever do it. Plus, it enables use of the RNH for the XAML islands.


In reply to: 424022761 [](ancestors = 424022761)

Copy link
Contributor

@aeulitz aeulitz May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get [](start = 48, length = 3)

For my understanding, who sets this? Does the API design represented here accommodate user who want to provide there own dispatcher implementations? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a shortcut to get a default implementation out of the current UI thread.
The current design has a gap that I do not understand yet how we can supply custom Office implementation. We must go back to solve it.
E.g. one of the solutions could be to make this property settable to enable such scenarios.


In reply to: 423982313 [](ancestors = 423982313)


// Get name of the UIDispatcher property for the IReactPropertyBag.
static IReactPropertyName UIDispatcherProperty();
}
} // namespace ReactNative
9 changes: 8 additions & 1 deletion vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" />
Expand Down Expand Up @@ -299,6 +299,9 @@
<DependentUpon>IJSValueWriter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="HResult.h" />
<ClInclude Include="IReactDispatcher.h">
<DependentUpon>IReactDispatcher.idl</DependentUpon>
</ClInclude>
<ClInclude Include="IReactModuleBuilder.h">
<DependentUpon>IReactModuleBuilder.idl</DependentUpon>
</ClInclude>
Expand Down Expand Up @@ -467,6 +470,9 @@
<ClCompile Include="DynamicWriter.cpp">
<DependentUpon>IJSValueWriter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="IReactDispatcher.cpp">
<DependentUpon>IReactDispatcher.idl</DependentUpon>
</ClCompile>
<ClCompile Include="IReactModuleBuilder.cpp">
<DependentUpon>IReactModuleBuilder.idl</DependentUpon>
</ClCompile>
Expand Down Expand Up @@ -547,6 +553,7 @@
<Midl Include="IJSValueReader.idl" />
<Midl Include="IJSValueWriter.idl" />
<Midl Include="ILifecycleEventListener.idl" />
<Midl Include="IReactDispatcher.idl" />
<Midl Include="IReactPropertyBag.idl" />
<Midl Include="IReactModuleBuilder.idl" />
<Midl Include="IReactPackageBuilder.idl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@
</ClCompile>
<ClCompile Include="ABICxxModule.cpp" />
<ClCompile Include="ABIViewManager.cpp" />
<ClCompile Include="IReactDispatcher.cpp" />
<ClCompile Include="Modules\AppStateData.cpp">
<Filter>Modules</Filter>
</ClCompile>
Expand Down Expand Up @@ -298,7 +299,6 @@
<ClCompile Include="ReactHost\UwpReactInstanceProxy.cpp">
<Filter>ReactHost</Filter>
</ClCompile>
<ClCompile Include="ReactPropertyBag.cpp" />
<ClCompile Include="ReactSupport.cpp" />
<ClCompile Include="RedBox.cpp" />
<ClCompile Include="TestHook.cpp" />
Expand Down Expand Up @@ -599,6 +599,7 @@
<Filter>Base</Filter>
</ClInclude>
<ClInclude Include="HResult.h" />
<ClInclude Include="IReactDispatcher.h" />
<ClInclude Include="LifecycleState.h" />
<ClInclude Include="Modules\AppStateData.h">
<Filter>Modules</Filter>
Expand Down Expand Up @@ -648,7 +649,6 @@
<ClInclude Include="ReactHost\UwpReactInstanceProxy.h">
<Filter>ReactHost</Filter>
</ClInclude>
<ClInclude Include="ReactPropertyBag.h" />
Copy link
Contributor

@NickGerleman NickGerleman May 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this removed? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was removed automatically by VS. We do not have such files. The implementation files are IReactPropertyBag.h and IReactPropertyBag.cpp. I never can understand what rules VS uses to change the .filters files.


In reply to: 423977037 [](ancestors = 423977037)

<ClInclude Include="ReactSupport.h" />
<ClInclude Include="RedBox.h" />
<ClInclude Include="TestHook.h" />
Expand Down Expand Up @@ -685,6 +685,7 @@
<Midl Include="IJSValueWriter.idl" />
<Midl Include="ILifecycleEventListener.idl" />
<Midl Include="IReactContext.idl" />
<Midl Include="IReactDispatcher.idl" />
<Midl Include="IReactModuleBuilder.idl" />
<Midl Include="IReactPackageBuilder.idl" />
<Midl Include="IReactPackageProvider.idl" />
Expand Down
8 changes: 4 additions & 4 deletions vnext/Microsoft.ReactNative/Modules/AppStateData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ using namespace xaml;

namespace react::uwp {

AppStateData::AppStateData(Mso::React::IReactContext &reactContext) noexcept
: Super(Mso::DispatchQueue::MainUIQueue()), m_lastState{"active"}, m_reactContext{&reactContext} {}
AppStateData::AppStateData(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept
: Super(uiQueue), m_lastState{"active"}, m_reactContext{&reactContext} {}

AppStateData::~AppStateData() = default;

Expand Down Expand Up @@ -59,8 +59,8 @@ void AppStateData::RaiseEvent(char const *newState) noexcept {
"RCTDeviceEventEmitter", "emit", folly::dynamic::array("appStateDidChange", std::move(parameters)));
}

AppState2::AppState2(Mso::React::IReactContext &reactContext) noexcept
: m_data{Mso::Make<AppStateData>(reactContext)} {}
AppState2::AppState2(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept
: m_data{Mso::Make<AppStateData>(reactContext, uiQueue)} {}

AppState2::~AppState2() = default;

Expand Down
4 changes: 2 additions & 2 deletions vnext/Microsoft.ReactNative/Modules/AppStateData.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace react::uwp {
struct AppStateData : Mso::ActiveObject<> {
using Super = ActiveObjectType;

AppStateData(Mso::React::IReactContext &reactContext) noexcept;
AppStateData(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept;
~AppStateData() override;
void Initialize() noexcept override;
void Finalize() noexcept override;
Expand All @@ -36,7 +36,7 @@ struct AppStateData : Mso::ActiveObject<> {
// It is a temporary class that we need to keep until we remove ReactUWP
class AppState2 : public facebook::react::AppState {
public:
AppState2(Mso::React::IReactContext &reactContext) noexcept;
AppState2(Mso::React::IReactContext &reactContext, Mso::DispatchQueue const &uiQueue) noexcept;

public: // facebook::react::AppState
~AppState2() override;
Expand Down
2 changes: 2 additions & 0 deletions vnext/Microsoft.ReactNative/ReactApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "ReactApplication.h"
#include "ReactApplication.g.cpp"

#include "IReactDispatcher.h"
#include "Modules/LinkingManagerModule.h"
#include "ReactNativeHost.h"

Expand Down Expand Up @@ -48,6 +49,7 @@ ReactApplication::ReactApplication(IInspectable const &outer) noexcept : ReactAp
ReactNative::ReactInstanceSettings ReactApplication::InstanceSettings() noexcept {
if (!m_instanceSettings) {
m_instanceSettings = make<ReactInstanceSettings>();
ReactDispatcher::SetUIThreadDispatcher(m_instanceSettings.Properties());
}

return m_instanceSettings;
Expand Down
15 changes: 9 additions & 6 deletions vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <ReactWindowsCore/ViewManager.h>
#include <dispatchQueue/dispatchQueue.h>
#include "IReactDispatcher.h"
#include "Modules/AppStateData.h"
#include "Modules/ClipboardModule.h"
#include "Modules/DevSettingsModule.h"
Expand Down Expand Up @@ -153,7 +154,7 @@ void ReactInstanceWin::Initialize() noexcept {
InitUIManager();

Mso::PostFuture(
Mso::DispatchQueue::MainUIQueue(),
m_uiQueue,
[weakThis = Mso::WeakPtr{this}]() noexcept {
// Objects that must be created on the UI thread
if (auto strongThis = weakThis.GetStrongPtr()) {
Expand All @@ -162,7 +163,8 @@ void ReactInstanceWin::Initialize() noexcept {
strongThis->m_appTheme =
std::make_shared<react::uwp::AppTheme>(legacyInstance, strongThis->m_uiMessageThread.LoadWithLock());
react::uwp::I18nHelper().Instance().setInfo(react::uwp::I18nModule::GetI18nInfo());
strongThis->m_appearanceListener = Mso::Make<react::uwp::AppearanceChangeListener>(legacyInstance);
strongThis->m_appearanceListener =
Mso::Make<react::uwp::AppearanceChangeListener>(legacyInstance, strongThis->m_uiQueue);
}
})
.Then(Queue(), [ this, weakThis = Mso::WeakPtr{this} ]() noexcept {
Expand Down Expand Up @@ -198,7 +200,7 @@ void ReactInstanceWin::Initialize() noexcept {
devSettings->debuggerConsoleRedirection =
false; // JSHost::ChangeGate::ChakraCoreDebuggerConsoleRedirection();

m_appState = std::make_shared<react::uwp::AppState2>(*m_reactContext);
m_appState = std::make_shared<react::uwp::AppState2>(*m_reactContext, m_uiQueue);

// Acquire default modules and then populate with custom modules
std::vector<facebook::react::NativeModuleDescription> cxxModules = react::uwp::GetCoreModules(
Expand Down Expand Up @@ -454,8 +456,9 @@ void ReactInstanceWin::InitNativeMessageThread() noexcept {

void ReactInstanceWin::InitUIMessageThread() noexcept {
// Native queue was already given us in constructor.
m_uiMessageThread.Exchange(std::make_shared<MessageDispatchQueue>(
Mso::DispatchQueue::MainUIQueue(), Mso::MakeWeakMemberFunctor(this, &ReactInstanceWin::OnError)));
m_uiQueue = winrt::Microsoft::ReactNative::ReactDispatcher::GetUIDispatchQueue(m_options.Properties);
m_uiMessageThread.Exchange(
std::make_shared<MessageDispatchQueue>(m_uiQueue, Mso::MakeWeakMemberFunctor(this, &ReactInstanceWin::OnError)));

m_batchingUIThread = react::uwp::MakeBatchingQueueThread(m_uiMessageThread.Load());
}
Expand Down Expand Up @@ -517,7 +520,7 @@ std::shared_ptr<IRedBoxHandler> ReactInstanceWin::GetRedBoxHandler() noexcept {
return m_options.RedBoxHandler;
} else if (m_options.DeveloperSettings.IsDevModeEnabled) {
auto localWkReactHost = m_weakReactHost;
return CreateDefaultRedBoxHandler(std::move(localWkReactHost));
return CreateDefaultRedBoxHandler(std::move(localWkReactHost), Mso::Copy(m_uiQueue));
} else {
return {};
}
Expand Down
1 change: 1 addition & 0 deletions vnext/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ class ReactInstanceWin final : public Mso::ActiveObject<IReactInstanceInternal,
std::shared_ptr<react::uwp::AppTheme> m_appTheme;
Mso::CntPtr<react::uwp::AppearanceChangeListener> m_appearanceListener;
std::string m_bundleRootPath;
Mso::DispatchQueue m_uiQueue;
};

} // namespace Mso::React
2 changes: 1 addition & 1 deletion vnext/Microsoft.ReactNative/ReactInstanceSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ namespace Microsoft.ReactNative {
String DebugBundlePath { get; set; };
String BundleRootPath { get; set; };
UInt16 DebuggerPort { get; set; };
Microsoft.ReactNative.IRedBoxHandler RedBoxHandler { get; set; };
IRedBoxHandler RedBoxHandler { get; set; };
}
}
Loading