zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

thread.go (2089B)


      1 // Copyright 2018 The Ebiten Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package thread
     16 
     17 import (
     18 	"errors"
     19 )
     20 
     21 // Thread defines threading behavior in Ebiten.
     22 type Thread interface {
     23 	Call(func() error) error
     24 	Loop()
     25 }
     26 
     27 // OSThread represents an OS thread.
     28 type OSThread struct {
     29 	funcs   chan func() error
     30 	results chan error
     31 }
     32 
     33 // NewOSThread creates a new thread.
     34 //
     35 // It is assumed that the OS thread is fixed by runtime.LockOSThread when NewOSThread is called.
     36 func NewOSThread() *OSThread {
     37 	return &OSThread{
     38 		funcs:   make(chan func() error),
     39 		results: make(chan error),
     40 	}
     41 }
     42 
     43 // BreakLoop represents an termination of the loop.
     44 var BreakLoop = errors.New("break loop")
     45 
     46 // Loop starts the thread loop until a posted function returns BreakLoop.
     47 //
     48 // Loop must be called on the thread.
     49 func (t *OSThread) Loop() {
     50 	for f := range t.funcs {
     51 		err := f()
     52 		if err == BreakLoop {
     53 			t.results <- nil
     54 			return
     55 		}
     56 		t.results <- err
     57 	}
     58 }
     59 
     60 // Call calls f on the thread.
     61 //
     62 // Do not call this from the same thread. This would block forever.
     63 //
     64 // If f returns BreakLoop, Loop returns.
     65 //
     66 // Call blocks if Loop is not called.
     67 func (t *OSThread) Call(f func() error) error {
     68 	t.funcs <- f
     69 	return <-t.results
     70 }
     71 
     72 // NoopThread is used to disable threading.
     73 type NoopThread struct{}
     74 
     75 // NewNoopThread creates a new thread that does no threading.
     76 func NewNoopThread() *NoopThread {
     77 	return &NoopThread{}
     78 }
     79 
     80 // Loop does nothing
     81 func (t *NoopThread) Loop() {}
     82 
     83 // Call executes the func immediately
     84 func (t *NoopThread) Call(f func() error) error {
     85 	return f()
     86 }