AppUtils.h#
Fully qualified name: omni/kit/AppUtils.h
File members: omni/kit/AppUtils.h
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
#pragma once
#include "../../carb/InterfaceUtils.h"
#include "../../carb/cpp/StringView.h"
#include "../../carb/eventdispatcher/IEventDispatcher.h"
#include "../../carb/eventdispatcher/IMessageQueue.h"
#include "IApp.h"
namespace omni::kit
{
template <class... Args>
bool queueEventToRunLoop(carb::RString deferredEventName,
carb::RString immediateEventName,
const carb::cpp::string_view runloopName,
Args&&... payload)
{
using namespace carb;
auto ed = getCachedInterface<eventdispatcher::IEventDispatcher>();
auto mqf = getCachedInterface<eventdispatcher::IMessageQueueFactory>();
if (!ed || !mqf)
return false;
std::array<eventdispatcher::NamedVariant, sizeof...(payload)> variants{ eventdispatcher::detail::translate(
std::forward<Args>(payload))... };
if constexpr (sizeof...(payload) != 0)
{
std::sort(variants.begin(), variants.end(), eventdispatcher::detail::NamedVariantLess{});
CARB_ASSERT(std::adjacent_find(variants.begin(), variants.end(), eventdispatcher::detail::NamedVariantEqual{}) ==
variants.end(),
"Event has duplicate keys");
}
eventdispatcher::EventData event = { immediateEventName, variants.size(), variants.data() };
ed->internalDispatch(event);
RStringKey mqName;
if (runloopName.empty() || runloopName == cpp::string_view(kRunLoopDefault))
{
mqName = kGlobalMessageBus;
}
else
{
omni::string scratch;
constexpr static cpp::string_view kPrefix("runloop:");
constexpr static cpp::string_view kSuffix(":messageBus");
scratch.reserve(kPrefix.size() + kSuffix.size() + runloopName.size());
scratch.append(kPrefix);
scratch.append(runloopName);
scratch.append(kSuffix);
mqName = RStringKey(scratch.c_str(), scratch.length());
}
auto mq = mqf->getMessageQueue(mqName);
CARB_UNLIKELY_IF(!mq)
{
if (auto app = carb::getCachedInterface<IApp>())
{
app->ensureRunLoop(runloopName.empty() ? kRunLoopDefault : omni::string(runloopName).c_str());
}
// Try again after ensuring the runloop
mq = mqf->getMessageQueue(mqName);
if (!mq)
return false;
}
eventdispatcher::IMessageQueue::ExpectedType expect;
event.eventName = deferredEventName;
mq->internalPush(expect, event, false, nullptr, nullptr);
return expect.has_value();
}
template <class... Args>
bool queueEvent(carb::RString deferredEventName, carb::RString immediateEventName, Args&&... payload)
{
return queueEventToRunLoop(deferredEventName, immediateEventName, kRunLoopDefault, std::forward<Args>(payload)...);
}
} // namespace omni::kit