pull/1223/merge
Cocoa 2021-11-25 22:51:31 -08:00 committed by GitHub
commit 1ae8f55c89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 118 additions and 13 deletions

View File

@ -34,6 +34,7 @@
/* copyright --> */
#include "ApiCallbackDownloadEventListener.h"
#include "RequestGroup.h"
#include "Segment.h"
namespace aria2 {
@ -46,9 +47,16 @@ ApiCallbackDownloadEventListener::ApiCallbackDownloadEventListener(
ApiCallbackDownloadEventListener::~ApiCallbackDownloadEventListener() = default;
void ApiCallbackDownloadEventListener::onEvent(DownloadEvent event,
const RequestGroup* group)
const RequestGroup* group,
const Segment* segment)
{
callback_(session_, event, group->getGID(), userData_);
struct SegmentInfo info;
if (segment) {
info.index = segment->getIndex();
info.position = segment->getPosition();
info.length = segment->getLength();
}
callback_(session_, event, group->getGID(), userData_, &info);
}
} // namespace aria2

View File

@ -46,7 +46,8 @@ public:
void* userData);
virtual ~ApiCallbackDownloadEventListener();
virtual void onEvent(DownloadEvent event,
const RequestGroup* group) CXX11_OVERRIDE;
const RequestGroup* group,
const Segment* segment = nullptr) CXX11_OVERRIDE;
private:
Session* session_;

View File

@ -328,4 +328,9 @@ void DownloadContext::updateUploadLength(size_t bytes)
}
}
void DownloadContext::completedSegment(const std::shared_ptr<Segment>& segment) const
{
ownerRequestGroup_->completedSegment(segment);
}
} // namespace aria2

View File

@ -54,6 +54,7 @@ namespace aria2 {
class RequestGroup;
class Signature;
class FileEntry;
class Segment;
class DownloadContext {
private:
@ -233,6 +234,10 @@ public:
// RequestGroupMan via getOwnerRequestGroup().
void updateUploadLength(size_t bytes);
void updateUploadSpeed(size_t bytes);
// This method will be called by corresponding SegmentMan
// if a Segment get downloaded
void completedSegment(const std::shared_ptr<Segment>& segment) const;
};
} // namespace aria2

View File

@ -48,10 +48,11 @@ void Notifier::addDownloadEventListener(DownloadEventListener* listener)
}
void Notifier::notifyDownloadEvent(DownloadEvent event,
const RequestGroup* group)
const RequestGroup* group,
const Segment* segment)
{
for (auto listener : listeners_) {
listener->onEvent(event, group);
listener->onEvent(event, group, segment);
}
}

View File

@ -45,25 +45,38 @@
namespace aria2 {
class RequestGroup;
class Segment;
struct DownloadEventListener {
virtual ~DownloadEventListener() = default;
virtual void onEvent(DownloadEvent event, const RequestGroup* group) = 0;
virtual void onEvent(DownloadEvent event,
const RequestGroup* group,
const Segment* segment = nullptr) = 0;
};
class Notifier {
public:
Notifier();
~Notifier();
void addDownloadEventListener(DownloadEventListener* listener);
// Notifies the download event to all listeners.
void notifyDownloadEvent(DownloadEvent event, const RequestGroup* group);
void notifyDownloadEvent(DownloadEvent event,
const RequestGroup* group,
const Segment* segment=nullptr);
void notifyDownloadEvent(DownloadEvent event,
const std::shared_ptr<RequestGroup>& group)
{
notifyDownloadEvent(event, group.get());
}
void notifyDownloadSegmentEvent(DownloadEvent event,
const std::shared_ptr<RequestGroup>& group,
const std::shared_ptr<Segment>& segment)
{
notifyDownloadEvent(event, group.get(), segment.get());
}
private:
std::vector<DownloadEventListener*> listeners_;

View File

@ -882,6 +882,11 @@ void RequestGroup::createNextCommand(
}
}
void RequestGroup::completedSegment(const std::shared_ptr<Segment>& segment) const
{
requestGroupMan_->completedSegment(requestGroupMan_->findGroup(this->gid_->getNumericId()), segment);
}
std::string RequestGroup::getFirstFilePath() const
{
assert(downloadContext_);

View File

@ -70,6 +70,7 @@ struct DownloadResult;
class URISelector;
class URIResult;
class RequestGroupMan;
class Segment;
#ifdef ENABLE_BITTORRENT
class BtRuntime;
class PeerStorage;
@ -240,6 +241,10 @@ public:
void createNextCommand(std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e);
// This method will be called by corresponding DownloadContext
// if a Segment get downloaded
void completedSegment(const std::shared_ptr<Segment>& segment) const;
bool downloadFinished() const;

View File

@ -248,6 +248,16 @@ void notifyDownloadEvent(DownloadEvent event,
}
}
void notifyDownloadSegmentEvent(DownloadEvent event,
const std::shared_ptr<RequestGroup>& group,
const std::shared_ptr<Segment>& segment)
{
// Check NULL to make unit test easier.
if (SingletonHolder<Notifier>::instance()) {
SingletonHolder<Notifier>::instance()->notifyDownloadSegmentEvent(event, group, segment);
}
}
} // namespace
namespace {
@ -1112,4 +1122,11 @@ int RequestGroupMan::optimizeConcurrentDownloads()
return maxConcurrentDownloads;
}
void RequestGroupMan::completedSegment(const std::shared_ptr<RequestGroup>& group,
const std::shared_ptr<Segment>& segment) const
{
notifyDownloadSegmentEvent(EVENT_ON_SEGMENT_COMPLETE, group, segment);
}
} // namespace aria2

View File

@ -61,6 +61,7 @@ class OutputFile;
class UriListParser;
class WrDiskCache;
class OpenedFileCounter;
class Segment;
typedef IndexedList<a2_gid_t, std::shared_ptr<RequestGroup>> RequestGroupList;
typedef IndexedList<a2_gid_t, std::shared_ptr<DownloadResult>>
@ -213,6 +214,11 @@ public:
}
bool setupOptimizeConcurrentDownloads();
// This method will be called by corresponding RequestGroup
// if a segment get downloaded
void completedSegment(const std::shared_ptr<RequestGroup>& group,
const std::shared_ptr<Segment>& segment) const;
void showDownloadResults(OutputFile& o, bool full) const;

View File

@ -376,6 +376,7 @@ bool SegmentMan::completeSegment(cuid_t cuid,
pieceStorage_->completePiece(segment->getPiece());
pieceStorage_->advertisePiece(cuid, segment->getPiece()->getIndex(),
global::wallclock());
downloadContext_->completedSegment(segment);
auto itr = std::find_if(usedSegmentEntries_.begin(),
usedSegmentEntries_.end(), FindSegmentEntry(segment));
if (itr == usedSegmentEntries_.end()) {

View File

@ -66,7 +66,8 @@ void WebSocketSessionMan::removeSession(
}
void WebSocketSessionMan::addNotification(const std::string& method,
const RequestGroup* group)
const RequestGroup* group,
const Segment* segment)
{
auto dict = Dict::g();
dict->put("jsonrpc", "2.0");
@ -89,6 +90,7 @@ const std::string ON_DOWNLOAD_START = "aria2.onDownloadStart";
const std::string ON_DOWNLOAD_PAUSE = "aria2.onDownloadPause";
const std::string ON_DOWNLOAD_STOP = "aria2.onDownloadStop";
const std::string ON_DOWNLOAD_COMPLETE = "aria2.onDownloadComplete";
const std::string ON_SEGMENT_COMPLETE = "aria2.onSegmentComplete";
const std::string ON_DOWNLOAD_ERROR = "aria2.onDownloadError";
const std::string ON_BT_DOWNLOAD_COMPLETE = "aria2.onBtDownloadComplete";
} // namespace
@ -105,6 +107,8 @@ const std::string& getMethodName(DownloadEvent event)
return ON_DOWNLOAD_STOP;
case EVENT_ON_DOWNLOAD_COMPLETE:
return ON_DOWNLOAD_COMPLETE;
case EVENT_ON_SEGMENT_COMPLETE:
return ON_SEGMENT_COMPLETE;
case EVENT_ON_DOWNLOAD_ERROR:
return ON_DOWNLOAD_ERROR;
case EVENT_ON_BT_DOWNLOAD_COMPLETE:
@ -119,9 +123,10 @@ const std::string& getMethodName(DownloadEvent event)
} // namespace
void WebSocketSessionMan::onEvent(DownloadEvent event,
const RequestGroup* group)
const RequestGroup* group,
const Segment* segment)
{
addNotification(getMethodName(event), group);
addNotification(getMethodName(event), group, segment);
}
} // namespace rpc

View File

@ -59,9 +59,12 @@ public:
~WebSocketSessionMan();
void addSession(const std::shared_ptr<WebSocketSession>& wsSession);
void removeSession(const std::shared_ptr<WebSocketSession>& wsSession);
void addNotification(const std::string& method, const RequestGroup* group);
void addNotification(const std::string& method,
const RequestGroup* group,
const Segment* segment = nullptr);
virtual void onEvent(DownloadEvent event,
const RequestGroup* group) CXX11_OVERRIDE;
const RequestGroup* group,
const Segment* segment = nullptr) CXX11_OVERRIDE;
private:
WebSocketSessions sessions_;

View File

@ -119,6 +119,10 @@ enum DownloadEvent {
* Indicating download has completed.
*/
EVENT_ON_DOWNLOAD_COMPLETE,
/**
* Indicating a segment has completed.
*/
EVENT_ON_SEGMENT_COMPLETE,
/**
* Indicating download has stopped because of the error.
*/
@ -130,6 +134,29 @@ enum DownloadEvent {
EVENT_ON_BT_DOWNLOAD_COMPLETE
};
/**
* @struct
*
* The segment information.
*/
struct SegmentInfo {
/**
* The index of a piece.
* The default value is ``0``.
*/
size_t index;
/**
* Specify the beginning offset of file.
* The default value is ``0``.
*/
int64_t position;
/**
* Specify number of bytes containing in the segment.
* The default value is ``0``.
*/
int64_t length;
};
/**
* @functypedef
*
@ -138,12 +165,15 @@ enum DownloadEvent {
* |gid| refers to the download which this event was fired on. The
* |userData| is a pointer specified in
* :member:`SessionConfig::userData`.
* |segmentInfo| will be non-default values if the event
* is `aria2::EVENT_ON_SEGMENT_COMPLETE`.
*
* At the moment, the return value is ignored, but the implementation
* of this callback should return 0 for compatibility.
*/
typedef int (*DownloadEventCallback)(Session* session, DownloadEvent event,
A2Gid gid, void* userData);
A2Gid gid, void* userData,
SegmentInfo* segmentInfo);
/**
* @struct