-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Console display refactoring #11
base: main
Are you sure you want to change the base?
Changes from all commits
8be5b95
9820471
7966b5a
086e9ac
a8fedb1
8649d09
19979b1
7133f5e
3893674
9e0ac7f
f7ce3c9
d2145bc
ec39eed
1e982d5
88f34af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ morserino_display | |
dist/* | ||
notes/help.txt | ||
cover.out | ||
coverage.txt | ||
coverage.txt | ||
*.log |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,6 +37,12 @@ var cfgFile string | |||||||||||||||||||||||
//Global variable with the port name | ||||||||||||||||||||||||
var morserinoPortName string | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
//Global variable with the debug level | ||||||||||||||||||||||||
var morserinoDebugLevel string | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
//Global variable with the name of the log file (if defined) | ||||||||||||||||||||||||
var morserinoDebugFilename string | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
Comment on lines
+40
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||
// rootCmd represents the base command when called without any subcommands | ||||||||||||||||||||||||
var rootCmd = &cobra.Command{ | ||||||||||||||||||||||||
Use: "morserino_display", | ||||||||||||||||||||||||
|
@@ -51,7 +57,7 @@ For easy reading, a new line is inserted after a "=" sign. | |||||||||||||||||||||||
// Run: func(cmd *cobra.Command, args []string) { }, | ||||||||||||||||||||||||
// Run: func(cmd *cobra.Command, args []string) { | ||||||||||||||||||||||||
// //Displaying on console is de default behaviour | ||||||||||||||||||||||||
// morserino_com.ConsoleListen(morserinoPortName) | ||||||||||||||||||||||||
// morserino_com.Listen(morserinoPortName) | ||||||||||||||||||||||||
// }, | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
@@ -69,12 +75,11 @@ func init() { | |||||||||||||||||||||||
// will be global for your application. | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
rootCmd.PersistentFlags().StringVar(&morserinoPortName, "port", "auto", "Morserino port (if set to \"auto\", will try to identify the port)") | ||||||||||||||||||||||||
rootCmd.PersistentFlags().StringVar(&morserinoDebugLevel, "debug", "", "Activtes debug tracing and its level (\"info\", \"debug\", \"trace\")") | ||||||||||||||||||||||||
rootCmd.PersistentFlags().StringVar(&morserinoDebugFilename, "logfile", "", "Specifices a specific filename to collect the debug info (\"stdout\" is a valid filename") | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.morserino_display.yaml)") | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
// Cobra also supports local flags, which will only run | ||||||||||||||||||||||||
// when this action is called directly. | ||||||||||||||||||||||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
// initConfig reads in config file and ENV variables if set. | ||||||||||||||||||||||||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||
package morserino_console | ||||||
package morserino | ||||||
|
||||||
/* | ||||||
Copyright © 2021 Jean-Marc Meessen, ON4KJM <[email protected]> | ||||||
|
@@ -22,30 +22,25 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||||
THE SOFTWARE. | ||||||
*/ | ||||||
|
||||||
import ( | ||||||
"fmt" | ||||||
"strings" | ||||||
) | ||||||
// Structure containing all the channels used by the application | ||||||
type MorserinoChannels struct { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Design nit: What is this structure role? What is its responsibility in regard of your application logic? Alsoooo, is repeating |
||||||
// Channel for the data flow from serial port to display goroutines | ||||||
MessageBuffer chan string | ||||||
|
||||||
//FIXME: Add comment | ||||||
type ConsoleDisplay struct { | ||||||
currentLine string | ||||||
newLine string | ||||||
} | ||||||
// Channel indicating that all data has been displayed and that the | ||||||
// application can be closed | ||||||
DisplayCompleted chan bool | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
If you don't care about the actual data carried inside the channel, use You can use it like this c := make(chan struct{})
c <- struct{}{} |
||||||
|
||||||
func (cd *ConsoleDisplay) String() string { | ||||||
//FIXME: add something useful here | ||||||
return "" | ||||||
} | ||||||
Done chan bool | ||||||
|
||||||
func (cd *ConsoleDisplay) Add(buff string) { | ||||||
if strings.Contains(buff, "=") { | ||||||
//FIXME: is the buffer one char long | ||||||
fmt.Println("=") | ||||||
} else { | ||||||
fmt.Printf("%s", buff) | ||||||
} | ||||||
// Channel used to report back errors in goroutines | ||||||
Error chan error | ||||||
} | ||||||
|
||||||
//TODO: add break on column | ||||||
//TODO: Add tests | ||||||
//Initialize the channels | ||||||
func (mc *MorserinoChannels) Init() { | ||||||
mc.MessageBuffer = make(chan string, 10) | ||||||
mc.DisplayCompleted = make(chan bool) | ||||||
mc.Done = make(chan bool) | ||||||
mc.Error = make(chan error, 10) | ||||||
} | ||||||
Comment on lines
+41
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Prefer using Initialization function instead of var c MorserinoChannels
// c is in an ill state, if I call anything on it it will panic
c.Init()
// now we're good VS cs := NewMorserinoChannels()
// And we're good :tada:, no risk of panics here. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package morserino_com | ||
package morserino | ||
|
||
/* | ||
Copyright © 2021 Jean-Marc Meessen, ON4KJM <[email protected]> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package morserino_com | ||
package morserino | ||
|
||
/* | ||
Copyright © 2021 Jean-Marc Meessen, ON4KJM <[email protected]> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package morserino_com | ||
package morserino | ||
|
||
/* | ||
Copyright © 2021 Jean-Marc Meessen, ON4KJM <[email protected]> | ||
|
@@ -25,33 +25,41 @@ THE SOFTWARE. | |
import ( | ||
"fmt" | ||
"io" | ||
"log" | ||
"strings" | ||
"testing/iotest" | ||
|
||
"github.com/on4kjm/morserino_display/pkg/morserino_console" | ||
// "github.com/rs/zerolog" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Careful with that commented line 😄 |
||
"go.bug.st/serial" | ||
) | ||
|
||
const exitString string = "\nExiting...\n" | ||
|
||
// Main listen function with display to the console | ||
func ConsoleListen(morserinoPortName string, genericEnumPorts comPortEnumerator) error { | ||
func OpenAndListen(morserinoPortName string, genericEnumPorts comPortEnumerator, channels *MorserinoChannels) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not in fond of this change: You're removing an How about keeping your error return and run the var errCh = make(chan error)
// ...
go func() {
if err := OpenAndListen(foo, bar); err != nil {
errCh <- err
}
}() There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, most of your operations here are Maybe leverage a struct here, WDYT ? type Listenser struct {
}
// Initialization function for the initialization phase
func NewListener(cfg Config) (*Listener, error) {
// Initialize things that could fail synchronously
smth, err := initializeSomething(cfg);
if err != nil {
return nil, err
}
return &Listener{smth: smth}, nil
} Another "smell" that makes me think this is your function name Does it make sense ? |
||
|
||
//If requested, use the simulator instead of a real Morserino | ||
if strings.HasPrefix("SIMULATOR", strings.ToUpper(morserinoPortName)) { | ||
AppLogger.Debug().Msg("Simulator mode listener") | ||
TestMessage := "cq cq de on4kjm on4kjm = tks fer call om = ur rst 599 = hw? \n73 de on4kjm = <sk> e e" | ||
return Listen(iotest.OneByteReader(strings.NewReader(TestMessage))) | ||
err := Listen(iotest.OneByteReader(strings.NewReader(TestMessage)), channels) | ||
channels.Error <- err | ||
return | ||
} | ||
|
||
//If portname "auto" was specified, we scan for the Morserino port | ||
if strings.ToUpper(morserinoPortName) == "AUTO" { | ||
AppLogger.Debug().Msg("Tying to detect the morsorino port") | ||
portName, err := DetectDevice(genericEnumPorts) | ||
channels.Error <- err | ||
if err != nil { | ||
return err | ||
channels.MessageBuffer <- exitString | ||
channels.Done <- true | ||
return | ||
} | ||
morserinoPortName = portName | ||
} | ||
|
||
log.Println("Listening to port \"" + morserinoPortName + "\"") | ||
AppLogger.Info().Msg("Listening to port \"" + morserinoPortName + "\"") | ||
|
||
//Port parameters for a Morserino | ||
mode := &serial.Mode{ | ||
|
@@ -61,20 +69,25 @@ func ConsoleListen(morserinoPortName string, genericEnumPorts comPortEnumerator) | |
StopBits: serial.OneStopBit, | ||
} | ||
|
||
AppLogger.Debug().Msg("Trying to open " + morserinoPortName) | ||
p, err := serial.Open(morserinoPortName, mode) | ||
if err != nil { | ||
return err | ||
AppLogger.Error().Err(err).Msg("Error opening port") | ||
channels.Error <- err | ||
return | ||
} | ||
defer p.Close() | ||
|
||
return Listen(p) | ||
err = Listen(p, channels) | ||
channels.Error <- err | ||
return | ||
} | ||
|
||
// Main receive loop | ||
func Listen(port io.Reader) error { | ||
func Listen(port io.Reader, channels *MorserinoChannels) error { | ||
|
||
//TODO: needs to be moved as a goroutine | ||
consoleDisplay := morserino_console.ConsoleDisplay{} | ||
// //TODO: needs to be moved as a goroutine | ||
// consoleDisplay := morserino_console.ConsoleDisplay{} | ||
|
||
// variables for tracking the exit pattern | ||
var ( | ||
|
@@ -88,7 +101,7 @@ func Listen(port io.Reader) error { | |
// Reads up to 100 bytes | ||
n, err := port.Read(buff) | ||
if err != nil { | ||
log.Fatal(err) | ||
AppLogger.Error().Err(err).Msg("Error reading on port") | ||
} | ||
|
||
// Check whether the "end of transmission" was sent | ||
|
@@ -110,23 +123,40 @@ func Listen(port io.Reader) error { | |
} | ||
|
||
if n == 0 { | ||
fmt.Println("\nEOF") | ||
AppLogger.Debug().Msg("EOF detectd") | ||
AppLogger.Trace().Msg("Sending EOF to the console displayer") | ||
channels.MessageBuffer <- "\nEOF" | ||
//sending the exit marker to the diplay goroutine | ||
Comment on lines
+126
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of exposing your synchronization primitive, how about hiding this being an interface, something like. type MessageWriter interface {
WriteMessage(msg string) error
} And hide the "technicalities` of how you actually send a message behind this ? From the caller It will be much more easier: _ = w.WriteMessage("\nEOF") |
||
AppLogger.Trace().Msg("Sending exit marker to the console displayer") | ||
channels.MessageBuffer <- exitString | ||
//waiting for it to complete (blocking read) | ||
AppLogger.Debug().Msg("Waiting for the signal that the display processing was completed") | ||
<-channels.DisplayCompleted | ||
AppLogger.Debug().Msg("Display processing completed (received signal)") | ||
break | ||
} | ||
|
||
// TODO: move this out and use a channel for that | ||
consoleDisplay.Add(string(buff[:n])) | ||
channels.MessageBuffer <- string(buff[:n]) | ||
|
||
if closeRequested { | ||
consoleDisplay.Add("\nExiting...\n") | ||
//sending the exit marker to the diplay goroutine | ||
AppLogger.Trace().Msg("Sending exit marker to the console displayer as we received the exit sequence") | ||
channels.MessageBuffer <- exitString | ||
//waiting for it to complete (blocking read) | ||
AppLogger.Debug().Msg("Waiting for the signal that the display processing was completed") | ||
<-channels.DisplayCompleted | ||
AppLogger.Debug().Msg("Display processing completed (received signal)") | ||
break | ||
} | ||
} | ||
AppLogger.Debug().Msg("Sending signal that all processing is done") | ||
channels.Done <- true | ||
|
||
AppLogger.Debug().Msg("Exiting Listen") | ||
return nil | ||
} | ||
|
||
// Tries to auto detect the Morserino port | ||
// Tries to auto detect the Morserino port based on the USB Vendor and Device ID | ||
func DetectDevice(genericEnumPorts comPortEnumerator) (string, error) { | ||
theComPortList, err := Get_com_list(genericEnumPorts) | ||
if err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit: you can inline this.
Also
Println
:/n
at the end of the line.