mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/ui: more precise detection of directory on browsers
Updates #1868
This commit is contained in:
parent
e03cb0d4df
commit
84e32c2e4e
@ -97,6 +97,7 @@ type userInterfaceImpl struct {
|
||||
keyboardLayoutMap js.Value
|
||||
|
||||
m sync.Mutex
|
||||
dropFileM sync.Mutex
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -640,14 +641,44 @@ func setCanvasEventHandlers(v js.Value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
files := data.Get("files")
|
||||
for i := 0; i < files.Length(); i++ {
|
||||
theUI.inputState.DroppedFiles = append(theUI.inputState.DroppedFiles, &file{v: files.Index(i)})
|
||||
}
|
||||
go theUI.appendDroppedFiles(data)
|
||||
return nil
|
||||
}))
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) appendDroppedFiles(data js.Value) {
|
||||
u.dropFileM.Lock()
|
||||
defer u.dropFileM.Unlock()
|
||||
|
||||
chFile := make(chan js.Value, 1)
|
||||
cbFile := js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||
chFile <- args[0]
|
||||
return nil
|
||||
})
|
||||
defer cbFile.Release()
|
||||
|
||||
items := data.Get("items")
|
||||
for i := 0; i < items.Length(); i++ {
|
||||
entry := items.Index(i).Call("webkitGetAsEntry")
|
||||
var f fs.File
|
||||
switch {
|
||||
case entry.Get("isFile").Bool():
|
||||
entry.Call("file", cbFile)
|
||||
jsFile := <-chFile
|
||||
f = &file{
|
||||
v: jsFile,
|
||||
}
|
||||
case entry.Get("isDirectory").Bool():
|
||||
f = &dir{
|
||||
entry: entry,
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
u.inputState.DroppedFiles = append(u.inputState.DroppedFiles, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) forceUpdateOnMinimumFPSMode() {
|
||||
if u.fpsMode != FPSModeVsyncOffMinimum {
|
||||
return
|
||||
@ -781,8 +812,6 @@ func (f *file) Close() error {
|
||||
|
||||
type fileInfo struct {
|
||||
v js.Value
|
||||
isDir bool
|
||||
isDirOnce sync.Once
|
||||
}
|
||||
|
||||
func (f *fileInfo) Name() string {
|
||||
@ -802,31 +831,53 @@ func (f *fileInfo) ModTime() time.Time {
|
||||
}
|
||||
|
||||
func (f *fileInfo) IsDir() bool {
|
||||
f.isDirOnce.Do(func() {
|
||||
ch := make(chan struct{})
|
||||
|
||||
cbThen := js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||
close(ch)
|
||||
return nil
|
||||
})
|
||||
defer cbThen.Release()
|
||||
|
||||
cbCatch := js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||
// This is not a reliable way to check whether the file is a directory or not.
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/File
|
||||
// TODO: Should the file system API be used?
|
||||
f.isDir = true
|
||||
close(ch)
|
||||
return nil
|
||||
})
|
||||
defer cbCatch.Release()
|
||||
|
||||
f.v.Call("arrayBuffer").Call("then", cbThen).Call("catch", cbCatch)
|
||||
<-ch
|
||||
})
|
||||
return f.isDir
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *fileInfo) Sys() any {
|
||||
return nil
|
||||
}
|
||||
|
||||
type dir struct {
|
||||
entry js.Value
|
||||
}
|
||||
|
||||
func (d *dir) Stat() (fs.FileInfo, error) {
|
||||
return &dirInfo{entry: d.entry}, nil
|
||||
}
|
||||
|
||||
func (d *dir) Read(buf []byte) (int, error) {
|
||||
return 0, fmt.Errorf("%s is a directory", d.entry.Get("name").String())
|
||||
}
|
||||
|
||||
func (d *dir) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type dirInfo struct {
|
||||
entry js.Value
|
||||
}
|
||||
|
||||
func (d *dirInfo) Name() string {
|
||||
return d.entry.Get("name").String()
|
||||
}
|
||||
|
||||
func (d *dirInfo) Size() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (d *dirInfo) Mode() fs.FileMode {
|
||||
return 0400 | fs.ModeDir
|
||||
}
|
||||
|
||||
func (d *dirInfo) ModTime() time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (d *dirInfo) IsDir() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *dirInfo) Sys() any {
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user