diff --git a/c/c.go b/c/c.go index 9a20d8b1..2b8eada1 100644 --- a/c/c.go +++ b/c/c.go @@ -28,6 +28,7 @@ const ( ) type ( + Void = [0]byte Char = int8 Float = float32 Double = float64 diff --git a/x/io/_demo/asyncdemo/async.go b/x/io/_demo/asyncdemo/async.go new file mode 100644 index 00000000..6d5362ae --- /dev/null +++ b/x/io/_demo/asyncdemo/async.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "time" + + "github.com/goplus/llgo/x/io" +) + +var GetUser = io.Async[any](func(string) any { + panic("todo: GetUser") +}) + +var GetScore = io.Async[float64](func() float64 { + panic("todo: GetScore") +}) + +var DoUpdate = io.Async[io.Void](func(op string) io.Void { + panic("todo: DoUpdate") +}) + +func main() { + user, err := GetUser("123").Await() + fmt.Println(user, err) + + user, err = io.Race(GetUser("123"), GetUser("456"), GetUser("789")).Await() + fmt.Println(user, err) + + user, score, _, err := io.Await3[any, float64, io.Void](GetUser("123"), GetScore(), DoUpdate("update sth.")) + fmt.Println(user, score, err) + + select { + case user := <-GetUser("123"): + fmt.Println("user:", user) + case score := <-GetScore(): + fmt.Println("score:", score) + case <-io.Timeout(5 * time.Second): + fmt.Println("timeout") + } +} diff --git a/x/io/io.go b/x/io/io.go new file mode 100644 index 00000000..8748673d --- /dev/null +++ b/x/io/io.go @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io + +import ( + _ "unsafe" + + "time" +) + +const ( + LLGoPackage = "decl" +) + +type Void = [0]byte + +// ----------------------------------------------------------------------------- + +type AsyncCall[OutT any] chan OutT + +// llgo:link AsyncCall.Await llgo.await +func (AsyncCall[OutT]) Await(timeout ...time.Duration) (ret OutT, err error) { + return +} + +//go:linkname Timeout llgo.timeout +func Timeout(time.Duration) (ret AsyncCall[Void]) + +// llgo:link Race llgo.race +func Race[OutT any](acs ...AsyncCall[OutT]) (ret AsyncCall[OutT]) { + return +} + +// llgo:link Await2 llgo.await +func Await2[OutT1, OutT2 any]( + ac1 AsyncCall[OutT1], ac2 AsyncCall[OutT2], + timeout ...time.Duration) (ret1 OutT1, ret2 OutT2, err error) { + return +} + +// llgo:link Await3 llgo.await +func Await3[OutT1, OutT2, OutT3 any]( + ac1 AsyncCall[OutT1], ac2 AsyncCall[OutT2], ac3 AsyncCall[OutT3], + timeout ...time.Duration) (ret1 OutT1, ret2 OutT2, ret3 OutT3, err error) { + return +} + +// ----------------------------------------------------------------------------- + +type Promise[OutT any] func(...any) AsyncCall[OutT] + +// llgo:link Async llgo.async +func Async[OutT any](fn any) (ret Promise[OutT]) { + return +} + +// -----------------------------------------------------------------------------