#include <condition_variable>
#include <iostream>
#include <string>
#include <vector>
#include <cvb/async/async.hpp>
#include <cvb/async/stream_handler_base.hpp>
#include <cvb/device_factory.hpp>
#include <cvb/driver/composite_stream.hpp>
#include <cvb/genapi/node_map_enumerator.hpp>
#include <cvb/global.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{});
}
explicit CustomStreamHandler(
PrivateTag)
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:
&streams) override {
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));
}
override {
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");
if (Cvb::holds_alternative<Cvb::ImagePtr>(item))
item_type = "image";
else if (Cvb::holds_alternative<Cvb::PlanePtr>(item))
item_type = "plane";
else if (Cvb::holds_alternative<Cvb::PlaneEnumeratorPtr>(item))
item_type = "plane enumerator";
else if (Cvb::holds_alternative<Cvb::BufferPtr>(item))
item_type = "buffer";
else if (Cvb::holds_alternative<Cvb::PFNCBufferPtr>(item))
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 {
auto infoList =
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.");
infoList.front().AccessToken(), Cvb::AcquisitionStack::GenTL);
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