-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make the writing of characters to the console pluggable. (#86)
* Make the writing of characters to the console pluggable. Once complete this pull-request will close #85 by allowing us to change output drivers at runtime. We'll also remove the messy ADM-3A output handling from our core CPM package. * Make the console output driver selectable via CLI flag * Working selectable output, via BIOS.
- Loading branch information
Showing
13 changed files
with
319 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package consoleout | ||
|
||
import "fmt" | ||
|
||
// AnsiOutputDriver holds our state. | ||
type AnsiOutputDriver struct { | ||
} | ||
|
||
// GetName returns the name of this driver. | ||
// | ||
// This is part of the OutputDriver interface. | ||
func (ad *AnsiOutputDriver) GetName() string { | ||
return "ansi" | ||
} | ||
|
||
// PutCharacter writes the specified character to the console. | ||
// | ||
// This is part of the OutputDriver interface. | ||
func (ad *AnsiOutputDriver) PutCharacter(c uint8) { | ||
fmt.Printf("%c", c) | ||
} | ||
|
||
// init registers our driver, by name. | ||
func init() { | ||
Register("ansi", func() ConsoleDriver { | ||
return &AnsiOutputDriver{} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Package consoleout is an abstruction over console output. | ||
// | ||
// We know we need an ANSI/RAW output, and we have an ADM-3A driver, | ||
// so we want to create a factory that can instantiate and change a driver, | ||
// given just a name. | ||
package consoleout | ||
|
||
import "fmt" | ||
|
||
// ConsoleDriver is the interface that must be implemented by anything | ||
// that wishes to be used as a console driver. | ||
// | ||
// Providing this interface is implemented an object may register itself, | ||
// by name, via the Register method. | ||
type ConsoleDriver interface { | ||
|
||
// PutCharacter will output the specified character to STDOUT. | ||
PutCharacter(c uint8) | ||
|
||
// GetName will return the name of the driver. | ||
GetName() string | ||
} | ||
|
||
// This is a map of known-drivers | ||
var handlers = struct { | ||
m map[string]Constructor | ||
}{m: make(map[string]Constructor)} | ||
|
||
// Constructor is the signature of a constructor-function | ||
// which is used to instantiate an instance of a driver. | ||
type Constructor func() ConsoleDriver | ||
|
||
// Register makes a console driver available, by name. | ||
// | ||
// When one needs to be created the constructor can be called | ||
// to create an instance of it. | ||
func Register(name string, obj Constructor) { | ||
handlers.m[name] = obj | ||
} | ||
|
||
// ConsoleOut holds our state, which is basically just a | ||
// pointer to the object handling our output. | ||
type ConsoleOut struct { | ||
|
||
// driver is the thing that actually writes our output. | ||
driver ConsoleDriver | ||
} | ||
|
||
// New is our constructore, it creates an output device which uses | ||
// the specified driver. | ||
func New(name string) (*ConsoleOut, error) { | ||
|
||
// Do we have a constructor with the given name? | ||
ctor, ok := handlers.m[name] | ||
if !ok { | ||
return nil, fmt.Errorf("failed to lookup driver by name '%s'", name) | ||
} | ||
|
||
// OK we do, return ourselves with that driver. | ||
return &ConsoleOut{ | ||
driver: ctor(), | ||
}, nil | ||
} | ||
|
||
// ChangeDriver allows changing our driver at runtime. | ||
func (co *ConsoleOut) ChangeDriver(name string) error { | ||
|
||
// Do we have a constructor with the given name? | ||
ctor, ok := handlers.m[name] | ||
if !ok { | ||
return fmt.Errorf("failed to lookup driver by name '%s'", name) | ||
} | ||
|
||
// change the driver by creating a new object | ||
co.driver = ctor() | ||
return nil | ||
} | ||
|
||
// GetName returns the name of our selected driver. | ||
func (co *ConsoleOut) GetName() string { | ||
return co.driver.GetName() | ||
} | ||
|
||
// PutCharacter outputs a character, using our selected driver. | ||
func (co *ConsoleOut) PutCharacter(c byte) { | ||
co.driver.PutCharacter(c) | ||
} |
Oops, something went wrong.