Skip to content
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

Task 3, libSMCE console #51

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

Ryllee
Copy link

@Ryllee Ryllee commented Nov 23, 2021

We are aware that the code is in need of refactoring, but we are not sure how we should go about it and also what to prioritize.

Ryllee and others added 16 commits October 9, 2021 15:22
Added SMCE_Client, a terminal interface for libSMCE.
Implemented a way to handle more then one input, to make it possible for example sending message
NOT WORKING!
KNOWN BUG.
Move SMCE_Client to its own folder, created a CMakeLists that installs SMCE_Client.exe and copys the SMCE.dll from the path of enviroment variable SMCE_ROOT.
Fixed bugg with recompile causing thread to crash.
Added termcolor library to set color for uart messages.
Added mute for uart messages.
Added functionality to set Arduino root folder
Added functionality to set SMCE_RESOURCE at runtime
Added so incoming uart messages can be written to a file instead of console. Set at start by setting the start argument -u or --file to true.
@codecov
Copy link

codecov bot commented Nov 23, 2021

Codecov Report

Merging #51 (79ed7ca) into master (47c8e01) will increase coverage by 23.18%.
The diff coverage is 5.26%.

❗ Current head 79ed7ca differs from pull request most recent head 100b84e. Consider uploading reports for the commit 100b84e to get more accurate results
Impacted file tree graph

@@             Coverage Diff             @@
##           master      #51       +/-   ##
===========================================
+ Coverage   40.08%   63.26%   +23.18%     
===========================================
  Files          33       82       +49     
  Lines        1497     2986     +1489     
===========================================
+ Hits          600     1889     +1289     
- Misses        897     1097      +200     
Impacted Files Coverage Δ
client/CMakeLists.txt 0.00% <0.00%> (ø)
CMakeLists.txt 94.21% <100.00%> (ø)
src/SMCE/Board.cpp 86.76% <0.00%> (-1.38%) ⬇️
src/SMCE/Toolchain.cpp 67.44% <0.00%> (-0.40%) ⬇️
src/Ardrivo/MQTT.cpp 6.57% <0.00%> (-0.28%) ⬇️
src/SMCE/Sketch.cpp 100.00% <0.00%> (ø)
include/SMCE/Board.hpp 100.00% <0.00%> (ø)
include/SMCE/BoardView.hpp 94.44% <0.00%> (ø)
include/SMCE/Toolchain.hpp 66.66% <0.00%> (ø)
CMake/Modules/BindGen.cmake 96.00% <0.00%> (ø)
... and 61 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 47c8e01...100b84e. Read the comment docs.

Copy link
Member

@AeroStun AeroStun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is barely readable; reformat it (ClangFormat is your friend).
Also the general conditional complexity in main tends to be overwhelming; try factorizing it out using lookup tables, functions, etc...

@@ -129,7 +129,7 @@ target_sources (HostUDD PRIVATE
)


add_library (objSMCE OBJECT)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Superfluous change

@@ -153,6 +153,7 @@ target_sources (objSMCE PRIVATE
include/SMCE/SketchConf.hpp
include/SMCE/internal/BoardDeviceSpecification.hpp
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Superfluous change

)
FetchContent_MakeAvailable(Termcolor Lyra)

include_directories(${PROJECT_SOURCE_DIR}/src)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never use global include_directories; see target_include_directories for a pure alternative

Comment on lines +38 to +41
target_include_directories (${PROJECT_NAME} PUBLIC
"${termcolor_SOURCE_DIR}/include/termcolor"
"${lyra_SOURCE_DIR}/include/lyra"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be incredibly surprised that the termcolor::termcolor and bfg::Lyra targets don't already provide those directories in their interface properties

client/README.md Outdated
Comment on lines 11 to 18
To be able to build SMCE_client, the enviroment variable SMCE_ROOT needs to point to a current installed release of libSMCE.
These can be found under releases on git. Or it can be build directly from the source code with the commands below.
These should be ran in the libSMCE folder.
```shell
cmake -S . -B build/
cmake --build build/
cmake --build build/ --config Release
cmake --install build/ --prefix <path to installation folder>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These instructions are both wrong and misplaced; this README is in a subfolder of the libSMCE project, so it stands to reason that readers have already read the top-level README


}else if (input.starts_with("-ra ")){
bool read = true;
int index_pin = stoi(input.substr(3));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const-incorrect


}else if (input.starts_with("-rd ")){
bool read = true;
int index_pin = stoi(input.substr(3));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const-incorrect

@@ -0,0 +1,28 @@
#include <UartToFile.hpp>
#include <ctime>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use <chrono>'s stuff

#include <fstream>
#include <iostream>

using namespace std;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are trying to give me a heart attack, this is definitely the way to go

Comment on lines 22 to 28
int uart_to_file(std::string message, std::string path){
ofstream file;
file.open(path, std::ios_base::app);
file << get_time() +": " +message + "\n";
file.close();
return 0;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opening/closing a file every time you need to write to it should be a definition of inefficiency.

Copy link
Contributor

@RuthgerD RuthgerD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Focus on parting everything into components, just constantly ask yourself, "how would I test this", "could someone reuse this code as a library" and stuff like that.

- Sketch path: Relative or absolute path to the sketch to run

### Start arguments
-f,--fqbn <fqbn> -> <fqbn> = Fully qualified board name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a note in general, fqbn is basically deprecated, so I would default this parameter

Comment on lines 9 to 20
std::string get_time(){
time_t currentTime;
struct tm *localTime;

time( &currentTime );
localTime = localtime( &currentTime );

int hour = localTime->tm_hour;
int min = localTime->tm_min;
int sec = localTime->tm_sec;
return(to_string(hour)+":"+to_string(min)+":"+to_string(sec));
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this use the way better library:
https://en.cppreference.com/w/cpp/chrono#Clocks

#include <fstream>
#include <iostream>

using namespace std;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using std is a bad practice

Comment on lines 22 to 28
int uart_to_file(std::string message, std::string path){
ofstream file;
file.open(path, std::ios_base::app);
file << get_time() +": " +message + "\n";
file.close();
return 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a highly specifically named module and a highly specifically named function name even though all it does write to a file. I would generalize this, also, this is one of the cases where you might want to keep the file open for the duration of the program as constantly opening a file is not very nice.

Comment on lines 38 to 40
void print_help(const char* argv0){
std::cout << "Usage: " << argv0 << " <fully-qualified-board-name> <path-to-sketch>" << std::endl;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stuff like this can just be in the main function

print_menu();

}else if (input == "-p"){ //pause or resume
if(!suspended){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better read the state from the board instead of keeping track of it yourself

}else if (input == "-rc"){ //recompile
std::cout << "Recompiling.." << std::endl;
t_lock.lock(); // aquire lock before recompiling, so uart_listener is forced to wait
compile_and_start(sketch,toolchain,board,arduino_root_dir);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a function like this just makes things opaque imo, why not have a compile function and a start function that you just calls after each other? they dont need to be composed.

std::cout << "Complete" << std::endl;

}else if (input.starts_with("-m ")){ //send message on uart
std::string message = input.substr(3);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needless clone

Comment on lines 260 to 270
if(!apin.exists()){
std::cout << "Pin does not exist!" << std::endl;
write=false;
}
if(!apin.can_write()){
std::cout << "Can't write to pin!" << std::endl;
write=false;
}
if(write){
apin.write(value);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if () else if() else { ::write }

Comment on lines 286 to 292
if(value == 0){
apin.write(false);
}else if(value == 1){
apin.write(true);
}else{
std::cout << "Value must be 0 or 1 for digital pins" << std::endl;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh apin.write(value > 0), it works like this internally as well

static std::atomic_bool mute_uart = false;
static std::mutex t_lock;
//Listen to the uart input from board, writes what it read to terminal
void uart_listener(smce::VirtualUart uart,bool file_write,std::string path){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah as discussed, taking the VirtualUart by value and reusing it across recompilations is completely wrong and likely reads invalid memory

Focused on the smaller problems from the pull request review. Still has several bugs / changes that needs to be done.
}else if (input.starts_with("-rd ")){
bool read = true;
int index_pin = stoi(input.substr(3));
}else if (!pin.can_read()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because the board cannot read does not mean the user should not be able to see the value

Comment on lines 318 to 277
}
if(!pin.can_read()){
}else if (!pin.can_read()) {
std::cout << "Can't read from pin!" << std::endl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

std::cout << "Value from pin " << index_pin << " is " << pin.read() << std::endl;
}

}else if (input == "-q"){ //power off and quit
} else if (input == "-q") { // power off and quit
std::cout << "Quitting..." << std::endl;
run_threads = false;
board.stop();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Board::stop may fail

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants