Ben bazı derin mülkiyet yoluyla sinyalini yuvaları bağlamak gerekir çünkü bunu yapmak istiyorum daha nesnelerin önceki örneklerini örnekleme yaşıyorum bir sorun var ve bir ile gelip istiyorum yolu, yuvaları saklamak ve iletmek için, üye değişkenleri yerine kullanmak yerine, kullanım sitelerine daha yakın nesneler oluşturabileceğim şekilde.Yuvaları :: signal2'yi kullanarak nasıl depolayabilir ve iletebilirim?
Temel sorunum, numaralı bir güncelleştirmeyi ayrı bir iş parçacığına karşıdan yükleyen bir işlemin olması ve ile ilgilenen herkese bir ilerleme sinyali göndermesidir. sinyal esas olarak:
typedef boost::signals2::signal<void (double)> DownloadProgress;
progress
fonksiyonunun uygulanması Aşağıda bu uygun söz varsayalım; sinyalin doğası çok önemli değil (çoğu zaman için functor kullanıyorum rağmen) çok önemli değil .
sinyal ayarlanır ve kod böyle bir şey denir:
Updater updater;
updater.onDownloadProgress(&progress);
updater.runDownloadTask();
Eğer updater.runDownloadTask()
çağırdığınızda, bir HTTPRequest
başlar ve bir HTTPResponse
döndürür UpdaterDownloadTask
, başlayacaktır. HTTPResponse
, ağ katmanı ile etkileşime giren ve verileri alan ve DownloadProgress
sinyalini içeren parçadır.
class HTTPResponse
{
public:
// this will be called for every "chunk" the underlying HTTP
// library receives
void processData(const char* data, size_t size)
{
// process the data and then send the progress signal
// assume that currentSize_ and totalSize_ are properly set
progressSignal_(currentSize_ * 100.0/totalSize_);
}
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
progressSignal_.connect(slot);
}
private:
DownloadProgress progressSignal_;
};
class HTTPRequest
{
public:
HTTPRequest() : response_(new HTTPResponse) { }
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
response_->connect(slot);
}
boost::shared_ptr<HTTPResponse> perform()
{
// start the request, which operates on response_.
return response_;
}
private:
boost::shared_ptr<HTTPResponse> response_;
};
class UpdaterDownloadTask : public AsyncTask
{
public:
DownloadTask() : request_(new HTTPRequest) { }
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
request_->connect(slot);
}
void run()
{
// set up the request_ and:
request_>perform();
}
private:
boost::shared_ptr<HTTPRequest> request_;
};
class Updater
{
public:
Updater() : downloadTask_(new UpdaterDownloadTask) { }
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
downloadTask_->onDownloadProgress(slot);
}
void runDownloadTask() { downloadTask_.submit() }
private:
boost::shared_ptr<UpdaterDownloadTask> downloadTask_;
};
Yani, benim Güncelleyicisi sahiptir
varUpdaterDownloadTask
bir örneğini olması: Bununla, benim uygulaması gibi biraz (
HTTPResponse
itibaren aşağıdan yukarıya, ağır özellikle açıklayıcı olmayan yöntemler elide için kısaltılır) bakar I (sinyal ait)
HTTPResponse
için
Updater
yank bağlantı (genel API giriş noktası) iletmek zorunda çünkü
HTTPResponse
-just bir örneği vardır
HTTPRequest
bir örneğini sahip her zaman yaklaşık .
Doğrusu şöyle UpdaterDownloadTask::run()
uygulayacağını: Bu HTTPRequest seviyesinde benzer etkileri olacaktır
void run()
{
HTTPRequest request;
request.onDownloadProgress(slots_);
#if 0
// The above is more or less equivalent to
BOOST_FOREACH(const DownloadProgress::slot_type& slot, slots_)
{
request.onDownloadProgress(slot);
}
#endif
request.perform();
}
ve genel markasını (bu yüzden isteği gerçekleştirene kadar HTTPResponse inşa etmek gerekmez ) güçlü RAII semantikleri ile daha güzel bir veri akışı için. Ben daha önce bir vektörü olarak slots_
değişken tanımlama denedim:
std::vector<DownloadProgress::slot_type> slots_;
Oysa ben sadece onDownloadProgress(boost::ref(slot));
aramaya arayanları zorlarsanız çalışmak için bu alabilirsiniz.
Bunu başarılı bir şekilde yapan birileri var mı, yoksa ürününün ne yaptığımdan başka bir yere nasıl iletileceğine dair öneriniz var mı?
Önceden bir vektörle bazı şeyleri denedim, ancak bölümümde bir hata olmuş olabilir. Bence haklısın. –