Adding Social Manager Rich Presence Polling and fixed lock issues
This commit is contained in:
Родитель
08dd6e8cc7
Коммит
a1c5904f71
|
@ -227,7 +227,7 @@
|
|||
<ClInclude Include="..\..\Tests\UnitTests\Tests\Services\SocialManagerHelper.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Casablanca\Release\src\build\vs14\casablanca140.static.vcxproj">
|
||||
<ProjectReference Include="..\..\External\cpprestsdk\Release\src\build\vs14\casablanca140.static.vcxproj">
|
||||
<Project>{04d42f35-e5d5-4d95-980e-1bd7e900f2dd}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -369,7 +369,7 @@ public:
|
|||
/// <summary>
|
||||
/// Internal function
|
||||
/// </summary>
|
||||
bool _Compare(_In_ const social_manager_presence_record& presenceRecord);
|
||||
bool _Compare(_In_ const social_manager_presence_record& presenceRecord) const;
|
||||
|
||||
/// <summary>
|
||||
/// Internal function
|
||||
|
@ -867,6 +867,17 @@ public:
|
|||
_In_ const std::shared_ptr<xbox_social_user_group>& group,
|
||||
_In_ const std::vector<string_t>& users
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable social manager to poll every 30 seconds from the presence service
|
||||
/// </summary>
|
||||
/// <param name="user">Xbox Live User</param>
|
||||
/// <param name="shouldEnablePolling">Whether or not polling should enabled</param>
|
||||
/// <returns>An xbox_live_result representing the success enabling polling</returns>
|
||||
_XSAPIIMP xbox_live_result<void> set_rich_presence_polling_status(
|
||||
_In_ xbox_live_user_t user,
|
||||
_In_ bool shouldEnablePolling
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Internal function
|
||||
|
|
|
@ -160,6 +160,19 @@ void SocialManager::UpdateSocialUserGroup(
|
|||
THROW_IF_ERR(result);
|
||||
}
|
||||
|
||||
void SocialManager::SetRichPresencePollingState(
|
||||
_In_ XboxLiveUser_t user,
|
||||
_In_ bool shouldEnablePolling
|
||||
)
|
||||
{
|
||||
THROW_INVALIDARGUMENT_IF_NULL(user);
|
||||
auto result = m_cppObj->set_rich_presence_polling_status(
|
||||
user_context::user_convert(user),
|
||||
shouldEnablePolling
|
||||
);
|
||||
|
||||
THROW_IF_ERR(result);
|
||||
}
|
||||
|
||||
void SocialManager::LogState()
|
||||
{
|
||||
|
|
|
@ -107,6 +107,17 @@ public:
|
|||
_In_ Windows::Foundation::Collections::IVectorView<Platform::String^>^ users
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable social manager to poll every 30 seconds from the presence service
|
||||
/// </summary>
|
||||
/// <param name="user">Xbox Live User</param>
|
||||
/// <param name="shouldEnablePolling">Whether or not polling should enabled</param>
|
||||
/// <returns>An xbox_live_result representing the success enabling polling</returns>
|
||||
void SetRichPresencePollingState(
|
||||
_In_ XboxLiveUser_t user,
|
||||
_In_ bool shouldEnablePolling
|
||||
);
|
||||
|
||||
internal:
|
||||
SocialManager();
|
||||
std::shared_ptr<xbox::services::social::manager::social_manager> GetCppObj() const;
|
||||
|
|
|
@ -53,7 +53,9 @@ social_graph::social_graph(
|
|||
m_perfTester(_T("social_graph")),
|
||||
m_wasDisconnected(false),
|
||||
m_numEventsThisFrame(0),
|
||||
m_userAddedContext(0)
|
||||
m_userAddedContext(0),
|
||||
m_shouldCancel(utility::details::make_unique<bool>(false)),
|
||||
m_isPollingRichPresence(false)
|
||||
{
|
||||
m_xboxLiveContextImpl->user_context()->set_caller_context_type(caller_context_type::social_manager);
|
||||
m_xboxLiveContextImpl->init();
|
||||
|
@ -70,8 +72,9 @@ social_graph::~social_graph()
|
|||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
m_perfTester.start_timer(_T("~social_graph"));
|
||||
m_xboxLiveContextImpl->real_time_activity_service()->deactivate();
|
||||
|
||||
m_perfTester.start_timer(_T("~social_graph"));
|
||||
try
|
||||
{
|
||||
if (m_graphDestructionCompleteCallback != nullptr)
|
||||
|
@ -86,7 +89,6 @@ social_graph::~social_graph()
|
|||
|
||||
LOG_DEBUG("social_graph destroyed");
|
||||
|
||||
|
||||
m_perfTester.stop_timer(_T("~social_graph"));
|
||||
}
|
||||
|
||||
|
@ -108,6 +110,18 @@ social_graph::initialize()
|
|||
}
|
||||
});
|
||||
|
||||
m_presencePollingTimer = std::make_shared<rta_trigger_timer>(
|
||||
[thisWeakPtr](std::vector<string_t> eventArgs, const fire_timer_completion_context&)
|
||||
{
|
||||
std::shared_ptr<social_graph> pThis(thisWeakPtr.lock());
|
||||
if (pThis)
|
||||
{
|
||||
pThis->presence_timer_callback(
|
||||
eventArgs
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
m_socialGraphRefreshTimer = std::make_shared<rta_trigger_timer>(
|
||||
[thisWeakPtr](std::vector<string_t> eventArgs, const fire_timer_completion_context& completionContext)
|
||||
{
|
||||
|
@ -142,22 +156,30 @@ social_graph::initialize()
|
|||
pThis->social_graph_refresh_callback();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
pplx::create_task([thisWeakPtr]()
|
||||
{
|
||||
try
|
||||
{
|
||||
static const std::chrono::milliseconds sleepTime(30);
|
||||
while (true)
|
||||
{
|
||||
std::shared_ptr<social_graph> pThis(thisWeakPtr.lock());
|
||||
if (pThis)
|
||||
bool hasRemainingEvent = false;
|
||||
{
|
||||
pThis->do_event_work();
|
||||
std::shared_ptr<social_graph> pThis(thisWeakPtr.lock());
|
||||
if (pThis)
|
||||
{
|
||||
hasRemainingEvent = pThis->do_event_work();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("exiting event processing loop");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!hasRemainingEvent)
|
||||
{
|
||||
LOG_DEBUG("exiting event processing loop");
|
||||
return;
|
||||
std::this_thread::sleep_for(sleepTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,57 +267,56 @@ social_graph::active_buffer_social_graph()
|
|||
return &m_userBuffer.active_buffer()->socialUserGraph;
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
social_graph::do_event_work()
|
||||
{
|
||||
static const std::chrono::milliseconds sleepTime(30);
|
||||
bool hasRemainingEvent = false;
|
||||
bool hasCachedEvents = false;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
set_state(social_graph_state::event_processing);
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(m_socialGraphStateMutex);
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
set_state(social_graph_state::event_processing);
|
||||
|
||||
m_perfTester.start_timer(_T("do_event_work: event_processing"));
|
||||
m_perfTester.start_timer(_T("do_event_work: has_cached_events"));
|
||||
hasCachedEvents = m_isInitialized && m_userBuffer.inactive_buffer() && !m_userBuffer.inactive_buffer()->socialUserEventQueue.empty(true);
|
||||
m_perfTester.stop_timer(_T("do_event_work: has_cached_events"));
|
||||
m_perfTester.start_timer(_T("do_event_work: event_processing"));
|
||||
m_perfTester.start_timer(_T("do_event_work: has_cached_events"));
|
||||
hasCachedEvents = m_isInitialized && m_userBuffer.inactive_buffer() && !m_userBuffer.inactive_buffer()->socialUserEventQueue.empty(true);
|
||||
m_perfTester.stop_timer(_T("do_event_work: has_cached_events"));
|
||||
if (hasCachedEvents)
|
||||
{
|
||||
m_perfTester.start_timer(_T("do_event_work: set_state"));
|
||||
LOG_INFO("set state: event_processing");
|
||||
m_perfTester.stop_timer(_T("do_event_work: set_state"));
|
||||
}
|
||||
m_perfTester.stop_timer(_T("do_event_work: event_processing"));
|
||||
}
|
||||
if (hasCachedEvents)
|
||||
{
|
||||
m_perfTester.start_timer(_T("do_event_work: set_state"));
|
||||
LOG_INFO("set state: event_processing");
|
||||
m_perfTester.stop_timer(_T("do_event_work: set_state"));
|
||||
process_cached_events();
|
||||
hasRemainingEvent = true;
|
||||
}
|
||||
m_perfTester.stop_timer(_T("do_event_work: event_processing"));
|
||||
}
|
||||
if (hasCachedEvents)
|
||||
{
|
||||
process_cached_events();
|
||||
hasRemainingEvent = true;
|
||||
}
|
||||
else if(m_isInitialized)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
m_perfTester.start_timer(_T("do_event_work: process_events"));
|
||||
set_state(social_graph_state::normal);
|
||||
hasRemainingEvent = process_events(); //effectively a coroutine here so that each event yields when it is done processing
|
||||
m_perfTester.stop_timer(_T("do_event_work: process_events"));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
else if (m_isInitialized)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
m_perfTester.start_timer(_T("do_event_work: process_events"));
|
||||
set_state(social_graph_state::normal);
|
||||
hasRemainingEvent = process_events(); //effectively a coroutine here so that each event yields when it is done processing
|
||||
m_perfTester.stop_timer(_T("do_event_work: process_events"));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
|
||||
m_perfTester.start_timer(_T("set_state: normal"));
|
||||
set_state(social_graph_state::normal);
|
||||
m_perfTester.stop_timer(_T("set_state: normal"));
|
||||
m_perfTester.start_timer(_T("set_state: normal"));
|
||||
set_state(social_graph_state::normal);
|
||||
m_perfTester.stop_timer(_T("set_state: normal"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRemainingEvent)
|
||||
{
|
||||
std::this_thread::sleep_for(sleepTime);
|
||||
}
|
||||
return hasRemainingEvent;
|
||||
}
|
||||
|
||||
void social_graph::initialize_social_buffers(
|
||||
|
@ -686,7 +707,7 @@ void social_graph::apply_presence_changed_event(
|
|||
}
|
||||
}
|
||||
|
||||
if (isFreshEvent)
|
||||
if (isFreshEvent && !userAddedVec.empty())
|
||||
{
|
||||
internal_social_event internalPresenceChangedEvent(internal_social_event_type::presence_changed, userAddedVec);
|
||||
m_socialEventQueue.push(internalPresenceChangedEvent, m_user, social_event_type::presence_changed);
|
||||
|
@ -926,6 +947,7 @@ social_graph::refresh_graph()
|
|||
{
|
||||
std::vector<uint64_t> userRefreshList;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(m_socialGraphStateMutex);
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
|
@ -993,6 +1015,7 @@ social_graph::perform_diff(
|
|||
_In_ const xsapi_internal_unordered_map(uint64_t, xbox_social_user)& xboxSocialUsers
|
||||
)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(m_socialGraphStateMutex);
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
|
@ -1341,8 +1364,8 @@ social_graph::presence_timer_callback(
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::weak_ptr<social_graph> thisWeakPtr = shared_from_this();
|
||||
|
||||
m_xboxLiveContextImpl->presence_service().get_presence_for_multiple_users(
|
||||
users,
|
||||
std::vector<presence_device_type>(),
|
||||
|
@ -1358,6 +1381,15 @@ social_graph::presence_timer_callback(
|
|||
{
|
||||
if (!presenceRecordsResult.err())
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(pThis->m_socialGraphStateMutex);
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(pThis->m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(pThis->m_socialGraphPriorityMutex);
|
||||
pThis->m_perfTester.start_timer(_T("social graph refresh state set"));
|
||||
pThis->set_state(social_graph_state::refresh);
|
||||
pThis->m_perfTester.start_timer(_T("social graph refresh state set"));
|
||||
}
|
||||
|
||||
auto presenceRecordReturnVec = presenceRecordsResult.payload();
|
||||
xsapi_internal_vector(social_manager_presence_record) socialManagerPresenceVec;
|
||||
socialManagerPresenceVec.reserve(presenceRecordReturnVec.size());
|
||||
|
@ -1366,10 +1398,38 @@ social_graph::presence_timer_callback(
|
|||
socialManagerPresenceVec.push_back(social_manager_presence_record(presenceRecord));
|
||||
}
|
||||
|
||||
std::vector<social_manager_presence_record> presenceRecordChanges;
|
||||
for (auto& record : socialManagerPresenceVec)
|
||||
{
|
||||
auto previousRecordIter = pThis->m_userBuffer.inactive_buffer()->socialUserGraph.find(record._Xbox_user_id());
|
||||
if (previousRecordIter == pThis->m_userBuffer.inactive_buffer()->socialUserGraph.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousRecordIter->second.socialUser == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto& previousRecord = previousRecordIter->second.socialUser->presence_record();
|
||||
if (previousRecord._Compare(record))
|
||||
{
|
||||
presenceRecordChanges.push_back(record);
|
||||
}
|
||||
}
|
||||
|
||||
pThis->m_internalEventQueue.push(
|
||||
internal_social_event_type::presence_changed,
|
||||
socialManagerPresenceVec
|
||||
);
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(pThis->m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(pThis->m_socialGraphPriorityMutex);
|
||||
pThis->m_perfTester.start_timer(_T("social graph refresh state set normal"));
|
||||
pThis->set_state(social_graph_state::normal);
|
||||
pThis->m_perfTester.stop_timer(_T("social graph refresh state set normal"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1379,7 +1439,6 @@ social_graph::presence_timer_callback(
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
social_graph::are_events_empty()
|
||||
{
|
||||
|
@ -1408,6 +1467,93 @@ social_graph::remove_users(
|
|||
m_internalEventQueue.push(internal_social_event_type::users_removed, utils::std_vector_to_xsapi_vector(users));
|
||||
}
|
||||
|
||||
void
|
||||
social_graph::presence_refresh_callback()
|
||||
{
|
||||
std::vector<string_t> userList;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(m_socialGraphStateMutex);
|
||||
|
||||
if (m_userBuffer.inactive_buffer() != nullptr)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
m_perfTester.start_timer(_T("presence refresh state set"));
|
||||
set_state(social_graph_state::refresh);
|
||||
m_perfTester.stop_timer(_T("presence refresh state set"));
|
||||
}
|
||||
userList.reserve(m_userBuffer.inactive_buffer()->socialUserGraph.size());
|
||||
for (auto& user : m_userBuffer.inactive_buffer()->socialUserGraph)
|
||||
{
|
||||
if (user.second.socialUser != nullptr)
|
||||
{
|
||||
userList.push_back(user.second.socialUser->xbox_user_id());
|
||||
}
|
||||
}
|
||||
|
||||
m_presencePollingTimer->fire(userList);
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
m_perfTester.start_timer(_T("presence refresh fire"));
|
||||
set_state(social_graph_state::normal);
|
||||
m_perfTester.stop_timer(_T("presence refresh fire"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::weak_ptr<social_graph> thisWeakPtr = shared_from_this();
|
||||
create_delayed_task(
|
||||
rta_trigger_timer::TIME_PER_CALL_MS,
|
||||
[thisWeakPtr]()
|
||||
{
|
||||
std::shared_ptr<social_graph> pThis(thisWeakPtr.lock());
|
||||
|
||||
if (pThis)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(pThis->m_socialGraphStateMutex);
|
||||
if (*pThis->m_shouldCancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pThis->presence_refresh_callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
social_graph::enable_rich_presence_polling(
|
||||
_In_ bool shouldEnablePolling
|
||||
)
|
||||
{
|
||||
bool isPollingRichPresence;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(m_socialGraphMutex);
|
||||
std::lock_guard<std::recursive_mutex> priorityLock(m_socialGraphPriorityMutex);
|
||||
isPollingRichPresence = m_isPollingRichPresence;
|
||||
m_isPollingRichPresence = shouldEnablePolling;
|
||||
}
|
||||
|
||||
if (shouldEnablePolling && !isPollingRichPresence)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(m_socialGraphStateMutex);
|
||||
*m_shouldCancel = false;
|
||||
}
|
||||
presence_refresh_callback();
|
||||
}
|
||||
else if(!shouldEnablePolling)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> socialGraphStateLock(m_socialGraphStateMutex);
|
||||
*m_shouldCancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
void social_graph::clear_debug_counters()
|
||||
{
|
||||
}
|
||||
|
@ -1439,22 +1585,39 @@ rta_trigger_timer::fire(
|
|||
_In_ const fire_timer_completion_context& usersAddedStruct
|
||||
)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_timerLock);
|
||||
|
||||
if (xboxUserIds.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_timerLock.get());
|
||||
|
||||
if (m_usersToCall.capacity() < m_usersToCall.size() + xboxUserIds.size())
|
||||
{
|
||||
m_usersToCall.reserve((m_usersToCall.size() + xboxUserIds.size()) - m_usersToCall.capacity());
|
||||
}
|
||||
for (auto& xboxUserId : xboxUserIds)
|
||||
{
|
||||
if (std::find(m_usersToCall.begin(), m_usersToCall.end(), xboxUserId) == m_usersToCall.end())
|
||||
if (m_usersToCallMap.find(xboxUserId) == m_usersToCallMap.end())
|
||||
{
|
||||
m_usersToCall.push_back(xboxUserId);
|
||||
m_usersToCallMap[xboxUserId] = true;
|
||||
}
|
||||
}
|
||||
|
||||
fire_helper(usersAddedStruct);
|
||||
std::weak_ptr<rta_trigger_timer> thisWeak = shared_from_this();
|
||||
|
||||
pplx::create_task([thisWeak, usersAddedStruct]()
|
||||
{
|
||||
std::shared_ptr<rta_trigger_timer> pThis(thisWeak.lock());
|
||||
if (pThis == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(pThis->m_timerLock);
|
||||
pThis->fire_helper(usersAddedStruct);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1466,8 +1629,7 @@ rta_trigger_timer::fire_helper(
|
|||
{
|
||||
std::chrono::milliseconds timeDiff = TIME_PER_CALL_MS - std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - m_previousTime);
|
||||
std::chrono::milliseconds timeRemaining = std::max<std::chrono::milliseconds>(std::chrono::milliseconds::zero(), timeDiff);
|
||||
auto usersToCall = m_usersToCall;
|
||||
m_usersToCall.clear();
|
||||
auto& usersToCall = m_usersToCall;
|
||||
|
||||
std::weak_ptr<rta_trigger_timer> thisWeakPtr = shared_from_this();
|
||||
m_isTaskInProgress = true;
|
||||
|
@ -1479,7 +1641,7 @@ rta_trigger_timer::fire_helper(
|
|||
std::shared_ptr<rta_trigger_timer> pThis(thisWeakPtr.lock());
|
||||
if (pThis != nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(pThis->m_timerLock.get());
|
||||
std::lock_guard<std::mutex> lock(pThis->m_timerLock);
|
||||
pThis->m_isTaskInProgress = false;
|
||||
pThis->m_fCallback(usersToCall, usersAddedStruct);
|
||||
|
||||
|
@ -1490,6 +1652,9 @@ rta_trigger_timer::fire_helper(
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
m_usersToCall.clear();
|
||||
m_usersToCallMap.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -365,8 +365,8 @@ social_manager::remove_local_user(
|
|||
std::lock_guard<std::mutex> lock(m_socialMangerLock);
|
||||
|
||||
auto xboxUserId = user_context::get_user_id(user);
|
||||
|
||||
if (m_localGraphs.find(xboxUserId) == m_localGraphs.end())
|
||||
auto graphIter = m_localGraphs.find(xboxUserId);
|
||||
if (graphIter == m_localGraphs.end())
|
||||
{
|
||||
return xbox_live_result<void>(xbox_live_error_code::logic_error, "User not found in graph");
|
||||
}
|
||||
|
@ -497,6 +497,23 @@ xbox_live_result<void> social_manager::update_social_user_group(
|
|||
return xbox_live_result<void>();
|
||||
}
|
||||
|
||||
xbox_live_result<void>
|
||||
social_manager::set_rich_presence_polling_status(
|
||||
_In_ xbox_live_user_t user,
|
||||
_In_ bool shouldEnablePolling
|
||||
)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_socialMangerLock);
|
||||
auto localGraphIter = m_localGraphs.find(user_context::get_user_id(user));
|
||||
if (localGraphIter == m_localGraphs.end())
|
||||
{
|
||||
return xbox_live_result<void>(xbox_live_error_code::logic_error, "User not found in graph");
|
||||
}
|
||||
|
||||
localGraphIter->second->enable_rich_presence_polling(shouldEnablePolling);
|
||||
return xbox_live_result<void>();
|
||||
}
|
||||
|
||||
void social_manager::_Log_state()
|
||||
{
|
||||
LOGS_DEBUG << "[SM] State: m_xboxSocialUserGroups: " << m_xboxSocialUserGroups.size()
|
||||
|
|
|
@ -150,8 +150,8 @@ public:
|
|||
void fire();
|
||||
void fire(_In_ const std::vector<string_t>& xboxUserIds, _In_ const fire_timer_completion_context& usersAddedStruct = fire_timer_completion_context());
|
||||
|
||||
private:
|
||||
static const std::chrono::milliseconds TIME_PER_CALL_MS;
|
||||
private:
|
||||
|
||||
void fire_helper(_In_ const fire_timer_completion_context& usersAddedStruct = fire_timer_completion_context());
|
||||
|
||||
|
@ -163,8 +163,9 @@ private:
|
|||
std::chrono::time_point<std::chrono::steady_clock> m_previousTime;
|
||||
#endif
|
||||
std::vector<string_t> m_usersToCall;
|
||||
std::unordered_map<string_t, bool> m_usersToCallMap; // duplicating data to make lookup faster. SHould be a better way to do this
|
||||
std::function<void(const std::vector<string_t>&, const fire_timer_completion_context&)> m_fCallback;
|
||||
xbox::services::system::xbox_live_mutex m_timerLock;
|
||||
std::mutex m_timerLock;
|
||||
};
|
||||
|
||||
struct xbox_social_user_context
|
||||
|
@ -433,6 +434,8 @@ public:
|
|||
void clear_debug_counters();
|
||||
|
||||
void print_debug_info();
|
||||
|
||||
void enable_rich_presence_polling(_In_ bool shouldEnablePolling);
|
||||
|
||||
const xsapi_internal_unordered_map(uint64_t, xbox_social_user_context)* active_buffer_social_graph();
|
||||
|
||||
|
@ -455,7 +458,9 @@ protected:
|
|||
|
||||
void social_graph_refresh_callback();
|
||||
|
||||
void do_event_work();
|
||||
void presence_refresh_callback();
|
||||
|
||||
bool do_event_work();
|
||||
|
||||
void presence_timer_callback(
|
||||
_In_ const std::vector<string_t>& users
|
||||
|
@ -530,6 +535,7 @@ protected:
|
|||
|
||||
bool m_isInitialized;
|
||||
bool m_wasDisconnected;
|
||||
bool m_isPollingRichPresence;
|
||||
|
||||
//rta function contexts
|
||||
function_context m_devicePresenceContext;
|
||||
|
@ -546,8 +552,10 @@ protected:
|
|||
social_graph_state m_socialGraphState;
|
||||
|
||||
xbox_live_user_t m_user;
|
||||
std::unique_ptr<bool> m_shouldCancel;
|
||||
std::shared_ptr<xbox_live_context_impl> m_xboxLiveContextImpl;
|
||||
std::shared_ptr<rta_trigger_timer> m_presenceRefreshTimer;
|
||||
std::shared_ptr<rta_trigger_timer> m_presencePollingTimer;
|
||||
std::shared_ptr<rta_trigger_timer> m_socialGraphRefreshTimer;
|
||||
std::shared_ptr<rta_trigger_timer> m_resyncRefreshTimer;
|
||||
std::shared_ptr<xbox::services::social::social_relationship_change_subscription> m_socialRelationshipChangeSubscription;
|
||||
|
@ -557,6 +565,7 @@ protected:
|
|||
xsapi_internal_unordered_map(uint64_t, xbox_social_user_subscriptions) m_socialUserSubscriptions;
|
||||
std::recursive_mutex m_socialGraphMutex;
|
||||
std::recursive_mutex m_socialGraphPriorityMutex;
|
||||
std::recursive_mutex m_socialGraphStateMutex;
|
||||
xbox::services::perf_tester m_perfTester;
|
||||
event_queue m_socialEventQueue;
|
||||
internal_event_queue m_internalEventQueue;
|
||||
|
|
|
@ -136,7 +136,7 @@ social_manager_presence_record::presence_title_records() const
|
|||
bool
|
||||
social_manager_presence_record::_Compare(
|
||||
_In_ const social_manager_presence_record& presenceRecord
|
||||
)
|
||||
) const
|
||||
{
|
||||
if (presenceRecord.m_userState != m_userState)
|
||||
{
|
||||
|
|
|
@ -159,6 +159,11 @@ change_list_enum xbox_social_user::_Compare(
|
|||
changeResult = static_cast<change_list_enum>(changeResult | change_list_enum::social_relationship_change);
|
||||
}
|
||||
|
||||
if (previous.m_presenceRecord._Compare(current.m_presenceRecord))
|
||||
{
|
||||
changeResult = static_cast<change_list_enum>(changeResult | change_list_enum::presence_change);
|
||||
}
|
||||
|
||||
return changeResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,10 @@ xbox_social_user_group::filter_list(
|
|||
}
|
||||
|
||||
auto user = userPair->second.socialUser;
|
||||
if (user == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((m_relationshipFilter == relationship_filter::favorite && user->is_favorite()) ||
|
||||
(m_relationshipFilter == relationship_filter::friends && user->is_followed_by_caller())
|
||||
)
|
||||
|
|
|
@ -500,6 +500,7 @@ public:
|
|||
{
|
||||
if (evt->EventType == SocialEventType::PresenceChanged)
|
||||
{
|
||||
assert(evt->UsersAffected->Size != 0);
|
||||
totalSize += evt->UsersAffected->Size;
|
||||
++numEvents;
|
||||
}
|
||||
|
@ -543,7 +544,7 @@ public:
|
|||
}
|
||||
|
||||
} while (shouldLoop);
|
||||
|
||||
Sleep(100);
|
||||
VERIFY_IS_TRUE(xblContext->real_time_activity_service()->_Subscription_Count() == 0);
|
||||
}
|
||||
|
||||
|
@ -1214,8 +1215,9 @@ public:
|
|||
pplx::task_completion_event<void> tce;
|
||||
|
||||
std::unordered_map<string_t, std::shared_ptr<HttpResponseStruct>> responses;
|
||||
|
||||
auto presenceResponse = StockMocks::CreateMockHttpCallResponse(devicePresenceResponse);
|
||||
auto devicePresenceResponseCopy = devicePresenceResponse;
|
||||
devicePresenceResponseCopy[0][L"state"] = web::json::value::string(L"Offline");
|
||||
auto presenceResponse = StockMocks::CreateMockHttpCallResponse(devicePresenceResponseCopy);
|
||||
auto presenceResponseStruct = std::make_shared<HttpResponseStruct>();
|
||||
presenceResponseStruct->responseList = { presenceResponse };
|
||||
|
||||
|
@ -1601,7 +1603,6 @@ public:
|
|||
|
||||
auto socialManagerInitializationStruct = Initialize(xboxLiveContext, true);
|
||||
|
||||
socialManagerInitializationStruct.socialManager->DoWork();
|
||||
auto group = socialManagerInitializationStruct.socialManager->CreateSocialUserGroupFromFilters(
|
||||
xboxLiveContext->user(),
|
||||
PresenceFilter::All,
|
||||
|
@ -1627,8 +1628,11 @@ public:
|
|||
m_mockXboxSystemFactory->add_http_state_response(responses);
|
||||
|
||||
m_mockXboxSystemFactory->GetMockWebSocketClient()->recieve_message(rtaResyncMessage);
|
||||
VERIFY_IS_TRUE(group->Users->GetAt(0)->PresenceRecord->PresenceTitleRecords->GetAt(0)->PresenceText == L"Home");
|
||||
|
||||
bool shouldLoop = true;
|
||||
bool foundProfileChange = false;
|
||||
bool foundPresenceChange = false;
|
||||
do
|
||||
{
|
||||
auto changeList = socialManagerInitializationStruct.socialManager->DoWork();
|
||||
|
@ -1638,9 +1642,18 @@ public:
|
|||
for (auto evt : socialManagerInitializationStruct.socialEvents)
|
||||
{
|
||||
if (evt->EventType == SocialEventType::ProfilesChanged)
|
||||
{
|
||||
foundProfileChange = true;
|
||||
}
|
||||
else if (evt->EventType == SocialEventType::PresenceChanged)
|
||||
{
|
||||
foundPresenceChange = true;
|
||||
VERIFY_IS_TRUE(group->Users->GetAt(0)->PresenceRecord->PresenceTitleRecords->GetAt(0)->PresenceText->IsEmpty());
|
||||
}
|
||||
|
||||
if (foundProfileChange && foundPresenceChange)
|
||||
{
|
||||
shouldLoop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (shouldLoop);
|
||||
|
@ -2502,6 +2515,65 @@ public:
|
|||
|
||||
Cleanup(socialManagerInitializationStruct, xboxLiveContext);
|
||||
}
|
||||
|
||||
DEFINE_TEST_CASE(TestSocialManagerRichPresencePolling)
|
||||
{
|
||||
DEFINE_TEST_CASE_PROPERTIES_FOCUS(TestSocialManagerRichPresencePolling);
|
||||
m_mockXboxSystemFactory->reinit();
|
||||
auto xboxLiveContext = GetMockXboxLiveContext_Cpp();
|
||||
auto socialManagerInitializationStruct = Initialize(xboxLiveContext, true);
|
||||
auto socialUserGroupAll = socialManagerInitializationStruct.socialManager->CreateSocialUserGroupFromFilters(
|
||||
xboxLiveContext->user(),
|
||||
PresenceFilter::All,
|
||||
RelationshipFilter::Friends
|
||||
);
|
||||
|
||||
auto presenceJSON = GenerateInitialPresenceJSON(false);
|
||||
auto presenceResponse = StockMocks::CreateMockHttpCallResponse(presenceJSON);
|
||||
std::shared_ptr<HttpResponseStruct> presenceResponseStruct = std::make_shared<HttpResponseStruct>();
|
||||
presenceResponseStruct->responseList = { presenceResponse };
|
||||
std::unordered_map<string_t, std::shared_ptr<HttpResponseStruct>> responses;
|
||||
// set up http response set
|
||||
responses[_T("https://userpresence.mockenv.xboxlive.com")] = presenceResponseStruct;
|
||||
|
||||
m_mockXboxSystemFactory->add_http_state_response(responses);
|
||||
VERIFY_IS_TRUE(socialUserGroupAll->Users->GetAt(0)->PresenceRecord->UserState == UserPresenceState::Online);
|
||||
|
||||
socialManagerInitializationStruct.socialManager->SetRichPresencePollingState(xboxLiveContext->user(), true);
|
||||
while (true)
|
||||
{
|
||||
auto userCount = 0;
|
||||
AppendToPendingEvents(socialManagerInitializationStruct.socialManager->DoWork(), socialManagerInitializationStruct);
|
||||
for (auto evt : socialManagerInitializationStruct.socialEvents)
|
||||
{
|
||||
if (evt->EventType == SocialEventType::PresenceChanged)
|
||||
{
|
||||
userCount += evt->UsersAffected->Size;
|
||||
}
|
||||
}
|
||||
|
||||
if (userCount == USER_LIST.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_IS_TRUE(socialUserGroupAll->Users->GetAt(0)->PresenceRecord->UserState == UserPresenceState::Offline);
|
||||
|
||||
socialManagerInitializationStruct.socialManager->SetRichPresencePollingState(xboxLiveContext->user(), false);
|
||||
|
||||
presenceJSON = GenerateInitialPresenceJSON(true);
|
||||
presenceResponse = StockMocks::CreateMockHttpCallResponse(presenceJSON);
|
||||
presenceResponseStruct = std::make_shared<HttpResponseStruct>();
|
||||
presenceResponseStruct->responseList = { presenceResponse };
|
||||
// set up http response set
|
||||
responses[_T("https://userpresence.mockenv.xboxlive.com")] = presenceResponseStruct;
|
||||
|
||||
socialManagerInitializationStruct.socialManager->DoWork();
|
||||
VERIFY_IS_TRUE(socialUserGroupAll->Users->GetAt(0)->PresenceRecord->UserState == UserPresenceState::Offline);
|
||||
|
||||
Cleanup(socialManagerInitializationStruct, xboxLiveContext);
|
||||
}
|
||||
};
|
||||
|
||||
NAMESPACE_MICROSOFT_XBOX_SERVICES_SYSTEM_CPP_END
|
Загрузка…
Ссылка в новой задаче