Skip to content

Commit

Permalink
(libviolet/downloader) Implements downloader ffi
Browse files Browse the repository at this point in the history
  • Loading branch information
violet-dev committed Jul 26, 2020
1 parent c20d207 commit 76fa296
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 32 deletions.
Binary file modified assets/libviolet/arm64-v8a/libviolet.so
Binary file not shown.
Binary file modified assets/libviolet/armeabi-v7a/libviolet.so
Binary file not shown.
Binary file modified assets/libviolet/x86/libviolet.so
Binary file not shown.
Binary file modified assets/libviolet/x86_64/libviolet.so
Binary file not shown.
2 changes: 1 addition & 1 deletion lib/pages/download/builtin_downloader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:violet/component/downloadable.dart' as violetd;

class BuiltinDownloader {
static const int maxDownloadCount = 2;
static const int maxDownloadFileCount = 24;
static const int maxDownloadFileCount = 8;

int _curDownloadCount = 0;
int _curDonwloadFileCount = 0;
Expand Down
11 changes: 6 additions & 5 deletions lib/pages/download/download_item_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ class _DownloadItemWidgetState extends State<DownloadItemWidget> {
}

// Download
var _timer = new Timer.periodic(Duration(seconds: 1), (Timer timer) {
var _timer =
new Timer.periodic(Duration(milliseconds: 100), (Timer timer) {
setState(() {
if (downloadSec / 1024 < 500.0)
downloadSpeed = (downloadSec / 1024).toStringAsFixed(1) + " KB/S";
Expand Down Expand Up @@ -212,7 +213,7 @@ class _DownloadItemWidgetState extends State<DownloadItemWidget> {
}
_timer.cancel();

await (await BuiltinDownloader.getInstance()).returnDownload();
// await (await BuiltinDownloader.getInstance()).returnDownload();

// Postprocess

Expand Down Expand Up @@ -338,9 +339,9 @@ class _DownloadItemWidgetState extends State<DownloadItemWidget> {
break;

case 3:
state =
'[$downloadedFileCount/$downloadTotalFileCount] ($downloadSpeed ${(download / 1024.0 / 1024.0).toStringAsFixed(1)} MB)';
// state = '[$downloadedFileCount/$downloadTotalFileCount]';
// state =
// '[$downloadedFileCount/$downloadTotalFileCount] ($downloadSpeed ${(download / 1024.0 / 1024.0).toStringAsFixed(1)} MB)';
state = '[$downloadedFileCount/$downloadTotalFileCount]';
pp = Translations.instance.trans('progress') + ': ';
break;

Expand Down
64 changes: 49 additions & 15 deletions lib/pages/download/native_downloader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:device_info/device_info.dart';
import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:synchronized/synchronized.dart' as sync;
import 'package:path_provider/path_provider.dart';
import 'package:violet/component/downloadable.dart';

Expand All @@ -30,18 +31,18 @@ class NativeDownloadTask {

NativeDownloadTask({this.id, this.url, this.fullpath, this.header});

static NativeDownloadTask fromDownloadTask(DownloadTask task) {
static NativeDownloadTask fromDownloadTask(int taskId, DownloadTask task) {
var header = Map<String, String>();
header['referer'] = task.referer;
header['accept'] = task.accept;
header['user-agent'] = task.userAgent;
if (task.referer != null) header['referer'] = task.referer;
if (task.accept != null) header['accept'] = task.accept;
if (task.userAgent != null) header['user-agent'] = task.userAgent;
if (task.headers != null) {
task.headers.entries.forEach((element) {
header[element.key.toLowerCase()] = element.value;
});
}
return NativeDownloadTask(
id: task.taskId,
id: taskId,
url: task.url,
fullpath: task.downloadPath,
header: header,
Expand All @@ -50,7 +51,7 @@ class NativeDownloadTask {

String toString() {
return jsonEncode({
"id": 1,
"id": id,
"url": url,
"fullpath": fullpath,
"header": header,
Expand All @@ -64,6 +65,9 @@ class NativeDownloader {
DownloaderDispose downloaderDispose;
DownloaderStatus downloaderStatus;
DownloaderAppend downloaderAppend;
List<DownloadTask> downloadTasks = List<DownloadTask>();

sync.Lock lock = sync.Lock();

Future<void> init() async {
final soPath = await _checkSharedLibrary();
Expand All @@ -85,7 +89,7 @@ class NativeDownloader {
.lookup<NativeFunction<downloader_append>>("downloader_append")
.asFunction();

downloaderInit(8);
downloaderInit(32);
}

static NativeDownloader _instance;
Expand All @@ -98,16 +102,46 @@ class NativeDownloader {
return _instance;
}

void addTask(DownloadTask task) {
downloaderAppend(
Utf8.toUtf8(NativeDownloadTask.fromDownloadTask(task).toString()));
NativeDownloader() {
Future.delayed(Duration(seconds: 1)).then((value) async {
// int prev = 0;
while (true) {
var x = Utf8.fromUtf8(downloaderStatus());
// var y = int.parse(x.split('|')[2]);
// print(x + ' ' + ((y - prev) / 1024.0).toString() + ' KB/S');
// prev = y;
var ll = x.split('|');
if (ll.length == 5) {
var complete = ll.last.split(',');
complete.forEach((element) {
int v = int.tryParse(element);
if (v != null) {
downloadTasks[v].completeCallback();
}
});
}
await Future.delayed(Duration(milliseconds: 100));
}
});
}

void addTasks(List<DownloadTask> tasks) {
tasks.forEach((task) {
// print(NativeDownloadTask.fromDownloadTask(task).toString());
downloaderAppend(
Utf8.toUtf8(NativeDownloadTask.fromDownloadTask(task).toString()));
Future<void> addTask(DownloadTask task) async {
await lock.synchronized(() {
downloadTasks.add(task);
downloaderAppend(Utf8.toUtf8(
NativeDownloadTask.fromDownloadTask(downloadTasks.length, task)
.toString()));
});
}

Future<void> addTasks(List<DownloadTask> tasks) async {
await lock.synchronized(() {
tasks.forEach((task) {
downloadTasks.add(task);
downloaderAppend(Utf8.toUtf8(
NativeDownloadTask.fromDownloadTask(downloadTasks.length - 1, task)
.toString()));
});
});
}

Expand Down
34 changes: 23 additions & 11 deletions libviolet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,29 @@ pub extern fn downloader_dispose() {

#[no_mangle]
pub extern fn downloader_status() -> *mut c_char {
let completed: String = DOWNLOAD_COMPLETE_INFO.clone().lock().unwrap().iter().enumerate().fold(String::new(), |res, (i, ch)| {
res + &format!("{},", ch)
});

CString::new(format!("{}|{}|{}|{}|{}",
DOWNLOAD_TOTAL_COUNT.load(Ordering::SeqCst),
DOWNLOAD_COMPLETED_COUNT.load(Ordering::SeqCst),
DOWNLOADED_BYTES.load(Ordering::SeqCst),
DOWNLOAD_ERROR_COUNT.load(Ordering::SeqCst),
completed
)).unwrap().into_raw()
let clone = DOWNLOAD_COMPLETE_INFO.clone();
let mut complete = clone.lock().unwrap();

if complete.len() == 0 {
return CString::new(format!("{}|{}|{}|{}",
DOWNLOAD_TOTAL_COUNT.load(Ordering::SeqCst),
DOWNLOAD_COMPLETED_COUNT.load(Ordering::SeqCst),
DOWNLOADED_BYTES.load(Ordering::SeqCst),
DOWNLOAD_ERROR_COUNT.load(Ordering::SeqCst),
)).unwrap().into_raw()
} else {
let completed: String = complete.iter().enumerate().fold(String::new(), |res, (_i, ch)| {
res + &format!("{},", ch)
});
complete.clear();
return CString::new(format!("{}|{}|{}|{}|{}",
DOWNLOAD_TOTAL_COUNT.load(Ordering::SeqCst),
DOWNLOAD_COMPLETED_COUNT.load(Ordering::SeqCst),
DOWNLOADED_BYTES.load(Ordering::SeqCst),
DOWNLOAD_ERROR_COUNT.load(Ordering::SeqCst),
completed
)).unwrap().into_raw();
}
}

#[no_mangle]
Expand Down

0 comments on commit 76fa296

Please sign in to comment.