Skip to content

Commit

Permalink
增加 net/FetchImage
Browse files Browse the repository at this point in the history
  • Loading branch information
3dgen committed Apr 15, 2024
1 parent 0869485 commit 29591d0
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 23 deletions.
44 changes: 22 additions & 22 deletions waroot/src/net/fetch.wa → waroot/src/net/fetch_blob.wa
Original file line number Diff line number Diff line change
Expand Up @@ -15,58 +15,58 @@ func FetchBlob(resource: string, fetcher: BlobFetcher) {
if fetcher == nil {
panic("Fetcher can't be nil.")
}
tid := allocTask(resource, fetcher)
tid := allocBlobTask(resource, fetcher)
jsFetchBlob(tid, resource)
}

func FetchBlobWithHandler(resource: string, handler: BlobHandler) {
if handler == nil {
panic("Handler can't be nil.")
}
tid := allocTask(resource, handler)
tid := allocBlobTask(resource, handler)
jsFetchBlob(tid, resource)
}

#wa:export net.onFetchBlobDone
func onFetchBlobDone(tid: int, ok: bool, status: u32, data: []byte) {
switch h := tasks[tid].fetcher.(type) {
switch h := blobTasks[tid].fetcher.(type) {
case BlobFetcher:
h.OnDone(tasks[tid].resource, ok, status, data)
h.OnDone(blobTasks[tid].resource, ok, status, data)

case BlobHandler:
h(tasks[tid].resource, ok, status, data)
h(blobTasks[tid].resource, ok, status, data)
}
freeTask(tid)
freeBlobTask(tid)
}

type fetchTask struct {
resource: string
fetcher: interface{}
}

global tasks: []fetchTask
global freeTaskIDs: []int
global blobTasks: []fetchTask
global freeBlobTaskIDs: []int

func allocTask(resource: string, fetcher: interface{}) => (taskid: int) {
if len(freeTaskIDs) > 0 {
i := len(freeTaskIDs) - 1
taskid = freeTaskIDs[i]
freeTaskIDs = freeTaskIDs[:i]
func allocBlobTask(resource: string, fetcher: interface{}) => (taskid: int) {
if len(freeBlobTaskIDs) > 0 {
i := len(freeBlobTaskIDs) - 1
taskid = freeBlobTaskIDs[i]
freeBlobTaskIDs = freeBlobTaskIDs[:i]
} else {
taskid = len(tasks)
tasks = append(tasks, fetchTask{})
taskid = len(blobTasks)
blobTasks = append(blobTasks, fetchTask{})
}
tasks[taskid].resource = resource
tasks[taskid].fetcher = fetcher
blobTasks[taskid].resource = resource
blobTasks[taskid].fetcher = fetcher
return
}

func freeTask(taskid: int) {
if tasks[taskid].fetcher == nil {
func freeBlobTask(taskid: int) {
if blobTasks[taskid].fetcher == nil {
panic("Task has been freed.")
}
tasks[taskid].resource = ""
tasks[taskid].fetcher = nil
blobTasks[taskid].resource = ""
blobTasks[taskid].fetcher = nil

freeTaskIDs = append(freeTaskIDs, taskid)
freeBlobTaskIDs = append(freeBlobTaskIDs, taskid)
}
69 changes: 69 additions & 0 deletions waroot/src/net/fetch_image.wa
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 版权 @2024 凹语言 作者。保留所有权利。

import "js"

type ImageFetcher interface {
OnDone(resource: string, ok: bool, status: u32, extobj: js.Handle)
}

type ImageHandler func(resource: string, ok: bool, status: u32, extobj: js.Handle)

/*
*/
#wa:import net fetch_image
func jsFetchImage(tid: int, resource: string) => js.Handle
#wa:generic FetchImageWithHandler
func FetchImage(resource: string, fetcher: ImageFetcher) {
if fetcher == nil {
panic("Fetcher can't be nil.")
}
tid := allocImageTask(resource, fetcher)
jsFetchImage(tid, resource)
}

func FetchImageWithHandler(resource: string, handler: ImageHandler) {
if handler == nil {
panic("Handler can't be nil.")
}
tid := allocImageTask(resource, handler)
jsFetchImage(tid, resource)
}

#wa:export net.onFetchImageDone
func onFetchImageDone(tid: int, ok: bool, status: u32, extobj: js.Handle) {
switch h := imageTasks[tid].fetcher.(type) {
case ImageFetcher:
h.OnDone(imageTasks[tid].resource, ok, status, extobj)

case ImageHandler:
h(imageTasks[tid].resource, ok, status, extobj)
}
freeImageTask(tid)
}

global imageTasks: []fetchTask
global freeImageTaskIDs: []int

func allocImageTask(resource: string, fetcher: interface{}) => (taskid: int) {
if len(freeImageTaskIDs) > 0 {
i := len(freeImageTaskIDs) - 1
taskid = freeImageTaskIDs[i]
freeImageTaskIDs = freeImageTaskIDs[:i]
} else {
taskid = len(imageTasks)
imageTasks = append(imageTasks, fetchTask{})
}
imageTasks[taskid].resource = resource
imageTasks[taskid].fetcher = fetcher
return
}

func freeImageTask(taskid: int) {
if imageTasks[taskid].fetcher == nil {
panic("Task has been freed.")
}
imageTasks[taskid].resource = ""
imageTasks[taskid].fetcher = nil

freeImageTaskIDs = append(freeImageTaskIDs, taskid)
}
25 changes: 24 additions & 1 deletion waroot/src/net/net.import.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ net: new function() {
return response.arrayBuffer();
})
.then((data) => {
let u8a = new Uint8Array(data)
let u8a = new Uint8Array(data);
let slice = app._mem_util.set_bytes(u8a);
app._wasm_inst.exports["net.onFetchBlobDone"](tid, 1, status, ...slice);
app._mem_util.block_release(slice[0]);
Expand All @@ -22,4 +22,27 @@ net: new function() {
})
}

this.fetch_image = (tid, res_b, res_d, res_l) => {
let resource = app._mem_util.get_string(res_d, res_l)
let status = 0
fetch(resource)
.then((response) => {
status = response.status;
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.blob();
})
.then((blob) => {
return createImageBitmap(blob);
})
.then((img) => {
let imgid = app._extobj.insert_obj(img);
app._wasm_inst.exports["net.onFetchImageDone"](tid, 1, status, imgid);
})
.catch((err) => {
app._wasm_inst.exports["net.onFetchImageDone"](tid, 0, status, 0);
console.log(err)
})
}
},

0 comments on commit 29591d0

Please sign in to comment.