#include <iostream>
#include <string>
#include <vector>
#include <condition_variable>
#include <cvb/device_factory.hpp>
#include <cvb/global.hpp>
#include <cvb/driver/composite_stream.hpp>
#include <cvb/genapi/node_map_enumerator.hpp>
#include <cvb/async/async.hpp>
#include <cvb/async/stream_handler_base.hpp>
static const constexpr auto TIMEOUT = std::chrono::milliseconds(3000);
static const constexpr int NUM_ELEMENTS_TO_ACQUIRE = 10;
static std::map<Cvb::WaitStatus, const char *> WAIT_ERROR_STATES{{Cvb::WaitStatus::Timeout, "timeout"},
{Cvb::WaitStatus::Abort, "abort"}};
{
struct PrivateTag
{
};
public:
static std::unique_ptr<CustomStreamHandler>
{
return std::make_unique<CustomStreamHandler>(streams, PrivateTag{});
}
, numDeliverables_(0)
{
}
std::cv_status WaitUntil(std::unique_lock<std::mutex> &lock, const std::chrono::system_clock::time_point &absTime)
{
return observer_.wait_until(lock, absTime);
}
private:
{
std::vector<Cvb::WaitResultTuple<Cvb::Composite>> waitResultList;
waitResultList.reserve(streams.size());
for (auto n = 0; n < streams.size(); ++n)
waitResultList.emplace_back(streams[n]->WaitFor(TIMEOUT));
}
{
std::cout << "round: #" << numDeliverables_ << "\n";
for (auto m = 0; m < waitResultList.size(); ++m)
{
auto waitStatus = std::get<Cvb::WaitStatus>(waitResultList[m]);
std::cout << "stream #" << m << "\n";
std::cout << "wait status: ";
if (waitStatus != Cvb::WaitStatus::Ok)
{
switch (waitStatus)
{
case Cvb::WaitStatus::Abort:
case Cvb::WaitStatus::Timeout:
std::cout << WAIT_ERROR_STATES[waitStatus];
break;
default:
std::cout << "unknown";
}
std::cout << "; no deliverable is available.\n";
continue;
}
else
std::cout << "ok\n";
auto composite = std::get<Cvb::CompositePtr>(waitResultList[m]);
const auto numItems = composite->ItemCount();
std::cout << "number of items: " << numItems << "\n";
for (auto n = 0; n < numItems; ++n)
{
auto item = composite->ItemAt(n);
auto item_type = std::string("unknown");
item_type = "image";
item_type = "plane";
item_type = "plane enumerator";
item_type = "buffer";
item_type = "pfnc buffer";
std::cout << "composite item #" << n << ": " << item_type << "\n";
}
}
std::cout << "\n";
++numDeliverables_;
if (numDeliverables_ == NUM_ELEMENTS_TO_ACQUIRE)
observer_.notify_all();
}
private:
std::condition_variable observer_;
int numDeliverables_;
};
int main()
{
try
{
for (const auto &info : infoList)
if (info.AccessToken().find("MockTL") != Cvb::String::npos)
accessToken = info.AccessToken();
if (accessToken.empty())
throw std::runtime_error("there is no available device for this demonstration.");
auto device =
std::vector<Cvb::CompositeStreamPtr> streams;
streams.reserve(device->StreamCount());
for (auto n = 0; n < device->StreamCount(); ++n)
auto handler = CustomStreamHandler::Create(streams);
handler->Run();
{
std::mutex mutex;
std::unique_lock<std::mutex> lock(mutex);
if (std::cv_status::no_timeout != handler->WaitUntil(lock, std::chrono::system_clock::now() + TIMEOUT))
throw std::runtime_error("could not complete the job");
}
handler->TryFinish();
}
catch (const std::exception &e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
virtual void HandleAsyncWaitResult(const std::vector< WaitResult< typename Internal::DeliverableTraits< STREAMTYPE >::type > > &waitResultVector)
std::vector< StreamPtrType > StreamVectorType
static std::unique_ptr< StreamHandlerBase > Create(const StreamVectorType &streamVector)
virtual void HandleAsyncStream(const StreamVectorType &streamVector)
static std::vector< DiscoveryInformation > Discover()
static std::shared_ptr< T > Open(const String &provider, AcquisitionStack acquisitionStack=AcquisitionStack::PreferVin)
StreamHandlerBase< CompositeStream > CompositeStreamHandler
std::tuple< std::shared_ptr< T >, WaitStatus, NodeMapEnumerator > WaitResultTuple
bool holds_alternative(const variant< TS... > &var) noexcept