TEST(TestStrand, AllFutureSignalPropertyPeriodicTaskAsyncTypeErasedDynamic) { static const int TOTAL = 50; srand(1828); callcount = 0; { boost::shared_ptr<MyActor> obj(new MyActor); qi::DynamicObjectBuilder builder; builder.setThreadingModel(qi::ObjectThreadingModel_SingleThread); builder.advertiseMethod("f", boost::function<void(int, qi::Promise<void>)>(boost::bind(&MyActor::f, obj, _1, _2))); builder.advertiseSignal("sig", &obj->sig); builder.advertiseProperty("prop", &obj->prop); qi::AnyObject aobj(builder.object()); qi::Promise<void> finished; for (int i = 0; i < 25; ++i) aobj.async<void>("f", TOTAL, finished); for (int i = 0; i < 50; ++i) aobj.setProperty("prop", rand()); QI_EMIT obj->sig(TOTAL); // we need one more call (the second test expects a periodic task to run at // least once) for (int i = 0; i < 26; ++i) aobj.async<void>("f", TOTAL, finished); finished.future().wait(); } ASSERT_EQ(TOTAL + 1, callcount); }
TEST(TestStrand, AllFutureSignalPropertyPeriodicTaskAsyncCallTypeErased) { static const int TOTAL = 300; srand(1828); callcount = 0; { boost::shared_ptr<MyActor> obj(new MyActor); qi::AnyObject aobj(obj); qi::Promise<void> finished; qi::PeriodicTask per; per.setUsPeriod(30); per.setCallback(&MyActor::f, obj.get(), TOTAL, finished); qi::Promise<void> prom; qi::Signal<int> signal; static_assert(std::is_same<decltype(prom.future().andThen(qi::bind(&MyActor::f, obj.get(), TOTAL, finished))), qi::Future<int>>::value, "andThen future type incorrect"); static_assert(std::is_same<decltype(prom.future().then(qi::bind(&MyActor::f, obj.get(), TOTAL, finished))), qi::Future<int>>::value, "then future type incorrect"); for (int i = 0; i < 25; ++i) prom.future().connect(&MyActor::f, obj.get(), TOTAL, finished); for (int i = 0; i < 10; ++i) prom.future().thenR<int>(&MyActor::f, obj.get(), TOTAL, finished); for (int i = 0; i < 10; ++i) prom.future().andThen(qi::bind(&MyActor::f, obj.get(), TOTAL, finished)); for (int i = 0; i < 5; ++i) prom.future().then(qi::bind(&MyActor::f, obj.get(), TOTAL, finished)); for (int i = 0; i < 50; ++i) signal.connect(&MyActor::f, obj.get(), _1, finished); for (int i = 0; i < 50; ++i) aobj.connect("sig", boost::function<void(int)>(obj->strand()->schedulerFor(boost::bind(&MyActor::f, obj, _1, finished)))); per.start(); for (int i = 0; i < 25; ++i) aobj.async<void>("f", TOTAL, finished); for (int i = 0; i < 25; ++i) qi::async(qi::bind(&MyActor::f, obj, TOTAL, finished)); for (int i = 0; i < 50; ++i) aobj.setProperty("prop", rand()); qi::Future<void> f = qi::async(boost::bind(chaincall, aobj, finished, TOTAL)); prom.setValue(0); QI_EMIT signal(TOTAL); QI_EMIT obj->sig(TOTAL); for (int i = 0; i < 25; ++i) aobj.async<void>("f", TOTAL, finished); for (int i = 0; i < 25; ++i) qi::async(qi::bind(&MyActor::f, obj, TOTAL, finished)); f.wait(); finished.future().wait(); } ASSERT_LT(TOTAL, callcount); }
TEST(TestStrand, TypeErasedCall) { boost::shared_ptr<MyActor> obj(new MyActor); qi::AnyObject aobj(obj); EXPECT_EQ(42, aobj.async<int>("val").value()); EXPECT_TRUE(aobj.async<int>("thrw").hasError()); EXPECT_TRUE(aobj.async<int>("fail").hasError()); EXPECT_EQ(42, aobj.call<int>("val")); EXPECT_ANY_THROW(aobj.call<int>("thrw")); EXPECT_ANY_THROW(aobj.call<int>("fail")); }
TEST(TestStrand, FutureThenActorCancel) { callcount = 0; { boost::shared_ptr<MyActor> obj(new MyActor); qi::AnyObject aobj(obj); qi::Promise<void> finished; qi::Promise<int> prom(qi::PromiseNoop<int>); qi::Future<int> masterFut = prom.future().thenR<int>(&MyActor::f, obj, _1, finished); masterFut.cancel(); ASSERT_TRUE(prom.isCancelRequested()); prom.setValue(0); ASSERT_EQ(42, masterFut.value()); ASSERT_NO_THROW(finished.future().value()); } }
void Post::Deserialize(Json::Value& root) { // General Post id_ = root.get("id", "").asString(); entity_ = root.get("entity", "").asString(); published_at_ = root.get("published_at", "").asString(); received_at_ = root.get("received_at", "").asString(); type_ = root.get("type", "").asString(); if(type_.find("#") != std::string::npos) base_type_ = type_.substr(0, type_.find("#")+1); jsn::DeserializeObject(&version_, root["version"]); jsn::DeserializeIntoVector(root["licenses"], licenses_); jsn::DeserializeObjectValueIntoMap(root["content"], content_); // Deserialize this into an array of objects Json::Value jsn_attch(Json::arrayValue); jsn_attch = root["attachments"]; if(jsn_attch.size() > 0) { Json::ValueIterator itr = jsn_attch.begin(); for(; itr != jsn_attch.end(); itr++) { //Attachment* pAtch = new Attachment; Attachment attch; Json::Value aobj(Json::objectValue); aobj = (*itr); if(aobj.isObject()) { if(aobj.size() >= 4) { Json::ValueIterator ii = aobj.begin(); for(; ii != aobj.end(); ii++) { attch.AssignKeyValue(ii.key().asString(), (*ii)); } } } PushBackAttachment(attch); } } Json::Value mentions_array(Json::arrayValue); mentions_array = root["mentions"]; if(mentions_array.size() > 0) { Json::ValueIterator itr = mentions_array.begin(); for(;itr != mentions_array.end(); itr++) { Mention mention; Json::Value mobj; mobj = (*itr); if(mobj.isObject()) { jsn::DeserializeObject(&mention, mobj); PushBackMention(mention); } } } if(root.isMember("app")) { tent_app_.Deserialize(root["app"]); } else { std::cout<<" post has no app " << std::endl; } jsn::DeserializeObjectValueIntoMap(root["views"], views_); jsn::DeserializeObject(&permissions_,root["permissions"]); }