-
Notifications
You must be signed in to change notification settings - Fork 13
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
Cleanup the C++ ReflexGame and add an enclaved based keyboard input reactor #88
Conversation
Cool, thanks for the ping. I will look at implementing something similar with C, just need to get some bugs under control first :) |
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.
Very nice! I like the enclave version.
One big question: the playground examples in Cpp are laid out differently than in C. You have playground-lingua-franca/examples/Cpp/ReflexGame/src/ReflexGame.lf
whereas in C, we have playground-lingua-franca/examples/C/src/ReflexGame/ReflexGame.lf
.
These have two different views of what a "project" is. In C, it is the collection of examples. In Cpp, each example is its own project.
The Cpp approach does not work well with Epoch. In Epoch, you either have to separately create a project for each example (nobody is going to do that), or else you get different layouts depending on whether you compile within Epoch vs. using lfc.
Can we change the Cpp layout to match the C layout (and Python)?
Also, I get a number of compiler warnings when compiling these examples:
% lfc-dev ReflexGame/src/ReflexGame.lf
lfc: info: Generating code for: file:/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src/ReflexGame.lf
lfc: info: Generation mode: STANDALONE
lfc: info: Generating sources into: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame
Path: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame
--- Current working directory: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/build
--- Executing command: cmake --version
cmake version 3.27.6
CMake suite maintained and supported by Kitware (kitware.com/cmake).
--- Current working directory: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/build
--- Executing command: cmake -DCMAKE_BUILD_TYPE=Release -DREACTOR_CPP_VALIDATE=ON -DREACTOR_CPP_PRINT_STATISTICS=OFF -DREACTOR_CPP_TRACE=OFF -DREACTOR_CPP_LOG_LEVEL=3 -DLF_SRC_PKG_PATH=/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame -DCMAKE_INSTALL_PREFIX=/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame -DCMAKE_INSTALL_BINDIR=bin /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen
-- The CXX compiler identification is AppleClang 15.0.0.15000040
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Configuring done (12.2s)
-- Generating done (0.1s)
-- Build files have been written to: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/build
--- Current working directory: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/build
--- Executing command: cmake --build . --target ReflexGame --parallel 12 --config Release
[ 5%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/environment.cc.o
[ 10%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/assert.cc.o
[ 21%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/port.cc.o
[ 26%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/logical_time.cc.o
[ 26%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/action.cc.o
[ 36%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/time.cc.o
[ 42%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/scheduler.cc.o
[ 42%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/multiport.cc.o
[ 57%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/reaction.cc.o
[ 57%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/reactor_element.cc.o
[ 57%] Building CXX object reactor-cpp-default/lib/CMakeFiles/reactor-cpp-default.dir/reactor.cc.o
[ 63%] Linking CXX shared library libreactor-cpp-default.dylib
[ 63%] Built target reactor-cpp-default
[ 73%] Building CXX object ReflexGame/CMakeFiles/ReflexGame.dir/ReflexGame/RandomDelay.cc.o
[ 73%] Building CXX object ReflexGame/CMakeFiles/ReflexGame.dir/ReflexGame/GameLogic.cc.o
[ 94%] Building CXX object ReflexGame/CMakeFiles/ReflexGame.dir/ReflexGame/ReflexGame.cc.o
[ 94%] Building CXX object ReflexGame/CMakeFiles/ReflexGame.dir/ReflexGame/_lf_preamble.cc.o
[ 94%] Building CXX object ReflexGame/CMakeFiles/ReflexGame.dir/main.cc.o
[ 94%] Building CXX object ReflexGame/CMakeFiles/ReflexGame.dir/ReflexGame/KeyboardInput.cc.o
In file included from /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/KeyboardInput.cc:7:
/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/KeyboardInput.hh:31:22: warning: private field '__lf_parameters' is not used [-Wunused-private-field]
const Parameters __lf_parameters;
^
In file included from /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/RandomDelay.cc:7:
/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/RandomDelay.hh:60:48: warning: private field 'min_delay' is not used [-Wunused-private-field]
const typename Parameters::__lf_min_delay_t& min_delay = __lf_inner.min_delay;
^
/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/RandomDelay.hh:61:48: warning: private field 'max_delay' is not used [-Wunused-private-field]
const typename Parameters::__lf_max_delay_t& max_delay = __lf_inner.max_delay;
^
In file included from /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/GameLogic.cc:7:
/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/GameLogic.hh:31:22: warning: private field '__lf_parameters' is not used [-Wunused-private-field]
const Parameters __lf_parameters;
^
2 warnings generated.
1 warning generated.
In file included from /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/ReflexGame.cc:7:
/Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame/ReflexGame/ReflexGame.hh:33:22: warning: private field '__lf_parameters' is not used [-Wunused-private-field]
const Parameters __lf_parameters;
^
1 warning generated.
1 warning generated.
[100%] Linking CXX executable ReflexGame
[100%] Built target ReflexGame
--- Current working directory: /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/build
--- Executing command: cmake --build . --target install --parallel 12 --config Release
Install the project...
-- Install configuration: "Release"
SUCCESS (compiling generated C++ code)
Generated source code is in /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/src-gen/ReflexGame
Compiled binary is in /Users/edwardlee/git/playground-lingua-franca/examples/Cpp/ReflexGame/bin
lfc: warning: private field 'max_delay' is not used [RandomDelay.hh:61:48]
--> ReflexGame/src/ReflexGame.lf:1:1 -
lfc: warning: private field 'min_delay' is not used [RandomDelay.hh:60:48]
--> ReflexGame/src/ReflexGame.lf:1:1 -
lfc: info: Code generation finished.
@@ -2,104 +2,97 @@ | |||
* This example illustrates the use of logical and physical actions, asynchronous external inputs, | |||
* the use of startup and shutdown reactions, and the use of actions with values. |
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.
Probably should acknowledge the original source of the example:
* The example is fashioned after an Esterel implementation given by Berry and Gonthier in "The
* ESTEREL synchronous programming language: design, semantics, implementation," Science of Computer
* Programming, 19(2) pp. 87-152, Nov. 1992, DOI: 10.1016/0167-6423(92)90005-V.
We have been advocating for the latter approach, because this is how languages with a package manager work (and we will soon have a package manager, too); you group all files that constitute an application together in a package, and different applications would reside in different packages. See #34. |
Can we make it part of the effort then to fix how Epoch handles packages? Currently, it will create Or should we view this as another step towards burying Epoch? |
That is what
There is a continuous effort by myself and other to keep Epoch afloat. Every CI run checks that Epoch keeps working, and we publish a nightly release and made it installable through the installation script. Nobody is trying to bury epoch. But I don't think we should make decisions about how to lay out source trees, configure packages, and design our package manager based on how Eclipse works. |
It is bad that Epoch cannot handle this well... But I think the current directory layout is really how it should be.
Yes, I think we should consider this a bug in Epoch. @lhstrh to clarify Edwards statement: In Epoch you can add the Cpp directory (or any directory up the hierarchy) as a project. The |
Thanks for reporting those. These warnings are not related to the program here and consider "problems" in the generated code. I don't see them, but this is because usually I don't use clang. |
It occurs to me that there is no reason that the examples in the playground have to be laid out as one example per project. A project can consist of multiple programs regardless of how the package manager works, no? I think the examples should be one project per target language. |
I don't think it is a bug -- it was intentionally designed that way. It's hard to find generated files or binaries if they end up being buried somewhere deeply inside of an open project. The only way to avoid this, is to open a new project for each package, which @edwardalee stated no one would ever do. So, what is the solution then? For the record, I'm fine unifying the behavior and placing generated files close to the project sources, inside of the boundaries of the package, but I recall that doing so was perceived as problematic by Epoch users in the past... |
While it is possible to have multiple programs in a single package, the reason for putting them in the same package should be that they are related in some significant way. Programs could share code or configurations, for instance. This is not the case for most examples. It becomes more apparent why lumping unrelated programs into the same package is probably not the best idea once we start moving the target properties from the LF files into the package configuration... |
I think we are conflating the package concept with the concept of projects in Eclipse. An LF package is a directory that contains an I agree that there is no reason for which a project shouldn't be able to contain multiple programs. In fact, a project could contain multiple packages and each package may also contain multiple executables. This is exactly how the directory layout works right now. We can see the entire playground as a project, just a language subset, or just a single package. We and any user can freely choose what to consider a project and which scope to open in an editor. It is not the directory layout that is problematic, but Epoch's current requirements and assumptions about projects. |
I think most IDEs have the concept of a project that defines the entry point into the file systems displayed in the IDE, Eclipse just has multiple to not impose a common parent for your components. If the Xtext framework actually enforces that you do it this way, with |
Co-authored-by: Edward A. Lee <[email protected]>
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.
LGTM!
This revises the C++ implementation of the ReflexGame. I never really liked that the game logic is split between two reactors in the original implementation. This change revises the overall architecture. There is now one reactor implementing the game logic, one responsible for the random delay, and one responsible for the keyboard input.
Inspired by yesterday's discussion, this PR also adds another version of the ReflexGame which uses an enclave instead of an additional thread to handle the blocking calls to
getchar()
. This is probably also interesting for @erlingrj.