From 8337610e1e852b7058f54cfd3d1d11f6b71ca3a7 Mon Sep 17 00:00:00 2001 From: brenocq Date: Sat, 17 Sep 2022 15:17:17 +0200 Subject: [PATCH 01/28] Chore: New version and fix warnings --- CMakeLists.txt | 2 +- scripts/build.sh => build.sh | 2 +- src/atta/component/components/camera.cpp | 3 +-- src/atta/io/bluetooth/linuxBluetoothMsg.cpp | 16 ++++++++-------- src/atta/io/http/jsonParse.cpp | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) rename scripts/build.sh => build.sh (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9b0a35d..a52d3cd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.14) -project(atta VERSION 0.2.0.0 LANGUAGES CXX C) +project(atta VERSION 0.3.0.0 LANGUAGES CXX C) OPTION(ATTA_BUILD_TESTS "Set to ON to build also the test executables" diff --git a/scripts/build.sh b/build.sh similarity index 99% rename from scripts/build.sh rename to build.sh index 0ed9746b..3e969b0d 100755 --- a/scripts/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ set -e SCRIPT_PATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" -SOURCE_PATH="$SCRIPT_PATH/.." +SOURCE_PATH="$SCRIPT_PATH" BUILD_PATH="$SOURCE_PATH/build" CMAKE_BUILD_TYPE="-DCMAKE_BUILD_TYPE=Release" CMAKE_COMPILER="" diff --git a/src/atta/component/components/camera.cpp b/src/atta/component/components/camera.cpp index 88887ea5..829515dc 100644 --- a/src/atta/component/components/camera.cpp +++ b/src/atta/component/components/camera.cpp @@ -56,8 +56,7 @@ const std::vector& Camera::getFrame() { for (auto& cameraInfo : cameraInfos) if (cameraInfo.component == this) return cameraInfo.data; - LOG_ERROR("component::Camera", "Could not get camera frame from sensor::Manager"); - return {}; + ASSERT(false, "(component::Camera) Could not get camera frame from sensor::Manager"); } } // namespace atta::component diff --git a/src/atta/io/bluetooth/linuxBluetoothMsg.cpp b/src/atta/io/bluetooth/linuxBluetoothMsg.cpp index c9211dd6..a639b244 100644 --- a/src/atta/io/bluetooth/linuxBluetoothMsg.cpp +++ b/src/atta/io/bluetooth/linuxBluetoothMsg.cpp @@ -235,12 +235,12 @@ int LinuxBluetooth::bluezParseDevice1(sd_bus_message* m, const char* opath, Devi } if (strcmp(str, "Name") == 0) { - r = bluezReadVariant(m, "s", &str); + r = bluezReadVariant(m, (char*)"s", &str); if (r < 0) return r; dev->name = str; } else if (strcmp(str, "Address") == 0) { - r = bluezReadVariant(m, "s", &str); + r = bluezReadVariant(m, (char*)"s", &str); if (r < 0) return r; @@ -264,18 +264,18 @@ int LinuxBluetooth::bluezParseDevice1(sd_bus_message* m, const char* opath, Devi // Will be populated with LinuxBluetooth::PopulateDeviceServices } else if (strcmp(str, "ServicesResolved") == 0) { int b; - r = bluezReadVariant(m, "b", &b); + r = bluezReadVariant(m, (char*)"b", &b); if (r < 0) return r; lDev->servicesResolved = b; } else if (strcmp(str, "Connected") == 0) { int b; - r = bluezReadVariant(m, "b", &b); + r = bluezReadVariant(m, (char*)"b", &b); if (r < 0) return r; dev->connected = b; } else if (strcmp(str, "RSSI") == 0) { - r = bluezReadVariant(m, "n", &dev->rssi); + r = bluezReadVariant(m, (char*)"n", &dev->rssi); if (r < 0) return r; } else { @@ -328,7 +328,7 @@ int LinuxBluetooth::bluezParseService1(sd_bus_message* m, const char* opath, Lin } if (strcmp(str, "UUID") == 0) { - r = bluezReadVariant(m, "s", &uuid); + r = bluezReadVariant(m, (char*)"s", &uuid); if (r < 0) { LOG_ERROR(_debugName.getString(), "Failed to parse service1 (read UUID)"); return r; @@ -392,7 +392,7 @@ int LinuxBluetooth::bluezParseCharacteristic1(sd_bus_message* m, const char* opa } if (strcmp(str, "UUID") == 0) { - r = bluezReadVariant(m, "s", &uuid); + r = bluezReadVariant(m, (char*)"s", &uuid); if (r < 0) return r; } else if (strcmp(str, "Flags") == 0) { @@ -486,7 +486,7 @@ int LinuxBluetooth::bluezParseNotify(sd_bus_message* m, Char* ch, LinuxChar* lch // Ignore all except Value if (strcmp(str, "Notifying") == 0) { int b; - r = bluezReadVariant(m, "b", &b); + r = bluezReadVariant(m, (char*)"b", &b); if (r < 0) { return -2; } diff --git a/src/atta/io/http/jsonParse.cpp b/src/atta/io/http/jsonParse.cpp index 40cdb86a..2ace69b1 100644 --- a/src/atta/io/http/jsonParse.cpp +++ b/src/atta/io/http/jsonParse.cpp @@ -189,7 +189,7 @@ std::map Json::parseMap(const std::string& str, unsigned& pos while (str[pos] == ' ' || str[pos] == '\n' || str[pos] == '\r' || str[pos] == '\t') { if (pos == str.size()) { - LOG_WARN("io::Json", "Expecting map key [w]\"[] or map end [w]\}[], but reached end of string"); + LOG_WARN("io::Json", "Expecting map key [w]\"[] or map end [w]}[], but reached end of string"); return {}; } pos++; @@ -227,7 +227,7 @@ std::map Json::parseMap(const std::string& str, unsigned& pos // Map end continue; } else { - LOG_WARN("io::Json", "Expecting map key [w]\"[] or map end [w]\}[], but found [w]$0[]", str[pos]); + LOG_WARN("io::Json", "Expecting map key [w]\"[] or map end [w]}[], but found [w]$0[]", str[pos]); return {}; } } From dacdbea5dd584b2aaf1a8f44c07251ba1ae7b656 Mon Sep 17 00:00:00 2001 From: brenocq Date: Sat, 17 Sep 2022 19:18:19 +0200 Subject: [PATCH 02/28] Refactor: Linux script reloading #37 --- src/atta/script/compilers/linuxCompiler.cpp | 4 +-- src/atta/script/linkers/linuxLinker.cpp | 38 ++++++++++++++------- src/atta/script/managerDynamic.cpp | 9 ++--- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/atta/script/compilers/linuxCompiler.cpp b/src/atta/script/compilers/linuxCompiler.cpp index 47edc99a..8f108ed0 100644 --- a/src/atta/script/compilers/linuxCompiler.cpp +++ b/src/atta/script/compilers/linuxCompiler.cpp @@ -50,7 +50,7 @@ void LinuxCompiler::compileAll() { // Show time std::chrono::time_point end = std::chrono::system_clock::now(); auto micro = std::chrono::duration_cast(end - begin); - LOG_INFO("script::LinuxCompiler", "Time to compile all: $0 ms", micro.count() / 1000.0f); + LOG_INFO("script::LinuxCompiler", "Time to compile all: [w]$0[] ms", micro.count() / 1000.0f); } void LinuxCompiler::compileTarget(StringId target) { @@ -88,7 +88,7 @@ void LinuxCompiler::compileTarget(StringId target) { // Show time std::chrono::time_point end = std::chrono::system_clock::now(); auto micro = std::chrono::duration_cast(end - begin); - LOG_INFO("script::LinuxCompiler", "Time to compile target $1: $0 ms", micro.count() / 1000.0f, target); + LOG_INFO("script::LinuxCompiler", "Time to compile target [*w]$1[]: [w]$0[] ms", micro.count() / 1000.0f, target); } void LinuxCompiler::updateTargets() { diff --git a/src/atta/script/linkers/linuxLinker.cpp b/src/atta/script/linkers/linuxLinker.cpp index a367e25b..76cbddc3 100644 --- a/src/atta/script/linkers/linuxLinker.cpp +++ b/src/atta/script/linkers/linuxLinker.cpp @@ -23,9 +23,17 @@ void LinuxLinker::linkTarget(StringId target, Script** script, ProjectScript** p fs::path projectDir = file::getProject()->getDirectory(); fs::path lib = projectDir / "build" / ("lib" + target.getString() + ".so").c_str(); - // LOG_DEBUG("script::LinuxLinker", "Linking target $0", lib); - - void* fLib = dlopen(fs::absolute(lib).c_str(), RTLD_LAZY); + // Copy lib to temporary file (should not reload same .so file) + fs::path libCpyDir = projectDir / "build" / "atta" / "script" / target.getString(); + if (fs::exists(libCpyDir)) + fs::remove_all(libCpyDir); + fs::create_directories(libCpyDir); + unsigned long uniqueNum = std::chrono::duration_cast(begin.time_since_epoch()).count(); + fs::path libCpy = libCpyDir / ("lib" + target.getString() + "." + std::to_string(uniqueNum) + ".so").c_str(); + fs::copy(lib, libCpy); + + // Open shared library + void* fLib = dlopen(fs::absolute(libCpy).c_str(), RTLD_LAZY); if (fLib) { //---------- Script ----------// using ScriptCreator = std::pair (*)(); @@ -59,20 +67,26 @@ void LinuxLinker::linkTarget(StringId target, Script** script, ProjectScript** p else if (*script) type = "Script " + name; else - type = "Component"; - //LOG_INFO("script::LinuxLinker", "Time to link [w]$0[]: $1 ms ($2)", target, micro.count() / 1000.0f, type); - } else { - LOG_WARN("script::LinuxLinker", "Cannot open library $0. Error: $1", lib.filename(), dlerror()); - return; - } + type = "Other"; + LOG_INFO("script::LinuxLinker", "Time to link [*w]$0[]: [w]$1[] ms ([w]$2[])", target, micro.count() / 1000.0f, type); + } else + LOG_ERROR("script::LinuxLinker", "Cannot open library [w]$0[]. Error: $1", libCpy.filename(), dlerror()); } void LinuxLinker::releaseTarget(StringId target) { if (_targetHandles.find(target) != _targetHandles.end()) { - // FIXME error when releasing target - // dlclose(_targetHandles[target]); + dlclose(_targetHandles[target]); + + const char* errStr = dlerror(); + if (errStr) { + LOG_ERROR("script::LinuxLinker", "Could not release target [w]$0[]: [w]$1", target, errStr); + return; + } + + LOG_INFO("script::LinuxLinker", "Target [*w]$0[] released", target); _targetHandles.erase(target); - } + } else + LOG_WARN("script::LinuxLinker", "Could not release target [w]$0[]: [w]Target not found", target); } } // namespace atta::script diff --git a/src/atta/script/managerDynamic.cpp b/src/atta/script/managerDynamic.cpp index 5a7afec9..3af6b725 100644 --- a/src/atta/script/managerDynamic.cpp +++ b/src/atta/script/managerDynamic.cpp @@ -79,11 +79,6 @@ void Manager::onProjectClose(event::Event& event) { // Release all targets for (auto target : _compiler->getTargets()) releaseTarget(target); - - // Publish event - event::ScriptTarget evt; - evt.scriptSids = getScriptSidsImpl(); - event::publish(evt); } void Manager::updateAllTargets() { @@ -98,7 +93,6 @@ void Manager::updateAllTargets() { // Link each target in the project for (auto target : _compiler->getTargets()) linkTarget(target); - // LOG_DEBUG("Manager", "Targets updated: $0", _compiler->getTargets()); } void Manager::updateTarget(StringId target) { @@ -117,9 +111,12 @@ void Manager::linkTarget(StringId target) { ProjectScript* projectScript = nullptr; std::string name; _linker->linkTarget(target, &script, &projectScript, name); + + // If target is script if (script != nullptr) _scripts[StringId(name)] = script; + // If target is project script if (projectScript != nullptr) { if (_projectScript.second != nullptr) LOG_WARN("script::Manager", From 1206c34b54f7523a8a52b340dd4a2ce7d4f1e126 Mon Sep 17 00:00:00 2001 From: brenocq Date: Sat, 17 Sep 2022 19:19:29 +0200 Subject: [PATCH 03/28] Chore: Test new linux workflow --- .github/workflows/linux.yml | 17 ++++++++--------- build.sh | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c8e273b0..fba734d6 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -11,8 +11,13 @@ jobs: config: - { name: "Ubuntu Latest", - os: ubuntu-latest, - build_type: "Release" + os: ubuntu-latest + compiler: "g++" + } + - { + name: "Ubuntu Latest", + os: ubuntu-latest + compiler: "clang++" } steps: @@ -27,14 +32,8 @@ jobs: cmake --version gcc --version - - name: Configure - run: | - mkdir build - cd build - cmake .. - - name: Build - run: cmake --build build --parallel --config ${{ matrix.config.build_type }} + run: ./build.sh --jobs 2 --compiler ${{ matrix.config.compiler }} - name: Test run: ctest diff --git a/build.sh b/build.sh index 3e969b0d..8beb0fe5 100755 --- a/build.sh +++ b/build.sh @@ -14,6 +14,7 @@ BUILD_TYPE="default" RUN_AFTER="false" PROJECT_TO_RUN="" INSTALL_AFTER="false" +NUM_JOBS="" printHelp() { @@ -39,6 +40,9 @@ printHelp() echo "-c or --compiler " echo " Select the compiler." echo + echo "-j or --jobs " + echo " Set number of jobs to use when building." + echo echo "-s or --static " echo " Build statically linked to a project." echo " The file should be a valid .atta" @@ -59,7 +63,7 @@ buildDefault() echo "---------- Building ----------" # Build cmake $CMAKE_BUILD_TYPE $CMAKE_COMPILER $CMAKE_ATTA_STATIC $SOURCE_PATH - make -j + make -j $NUM_JOBS # Install if [[ "$INSTALL_AFTER" == "true" ]]; then @@ -97,7 +101,7 @@ buildWeb() # Build echo "---------- Building web ----------" emcmake cmake $CMAKE_MODULE $CMAKE_BUILD_TYPE $CMAKE_ATTA_STATIC $SOURCE_PATH - make -j + make -j $NUM_JOBS # Run if [[ "$RUN_AFTER" == "true" ]]; then @@ -112,7 +116,7 @@ buildDocs() { echo "---------- Building docs ----------" cmake -ATTA_BUILD_DOCS=ON -DATTA_BUILD_TESTS=OFF $SOURCE_PATH - make -j + make -j $NUM_JOBS exit } @@ -136,6 +140,11 @@ while [[ $# -gt 0 ]]; do RUN_AFTER="true" shift # past argument ;; + -j|--jobs) + NUM_JOBS="$2" + shift # past argument + shift # past value + ;; -p|--project) PROJECT_TO_RUN="$2" shift # past argument From 8cde9f8bf2de987e3e114ed62662fa72386fb90b Mon Sep 17 00:00:00 2001 From: brenocq Date: Sat, 17 Sep 2022 19:20:37 +0200 Subject: [PATCH 04/28] Chore: Fix workflow comma --- .github/workflows/linux.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index fba734d6..9959b3b2 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -11,12 +11,12 @@ jobs: config: - { name: "Ubuntu Latest", - os: ubuntu-latest + os: ubuntu-latest, compiler: "g++" } - { name: "Ubuntu Latest", - os: ubuntu-latest + os: ubuntu-latest, compiler: "clang++" } From 4cc2d160dc39d798213469b74022ef4dd08da273 Mon Sep 17 00:00:00 2001 From: brenocq Date: Sun, 18 Sep 2022 12:49:11 +0200 Subject: [PATCH 05/28] Chore: Linux workflow renaming --- .github/workflows/linux.yml | 11 ++++------- build.sh | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9959b3b2..e29c2df4 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -10,12 +10,12 @@ jobs: matrix: config: - { - name: "Ubuntu Latest", + name: "Ubuntu g++", os: ubuntu-latest, compiler: "g++" } - { - name: "Ubuntu Latest", + name: "Ubuntu clang++", os: ubuntu-latest, compiler: "clang++" } @@ -24,17 +24,14 @@ jobs: - name: Checkout atta uses: actions/checkout@v2 - - name: Install dependencies on ubuntu - if: startsWith(matrix.config.os, 'ubuntu') + - name: Install dependencies run: | sudo apt-get update sudo apt-get install cmake xorg-dev curl - cmake --version - gcc --version - name: Build run: ./build.sh --jobs 2 --compiler ${{ matrix.config.compiler }} - name: Test run: ctest - working-directory: build + working-directory: build/release diff --git a/build.sh b/build.sh index 8beb0fe5..64e3c5df 100755 --- a/build.sh +++ b/build.sh @@ -20,9 +20,9 @@ printHelp() { echo "Atta build script" echo - echo "Usage: ./build.sh [args ...]" + echo "Usage: ./build.sh [option(s)]" echo - echo "options:" + echo "Options:" echo echo "-h or --help" echo " This help menu" From cca594d6d708d359a5f5045d54407c49baaddac7 Mon Sep 17 00:00:00 2001 From: brenocq Date: Sun, 18 Sep 2022 12:49:48 +0200 Subject: [PATCH 06/28] Docs: Better OS specific instructions --- README.md | 66 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index a84b2acd..0a3a3fb8 100644 --- a/README.md +++ b/README.md @@ -77,40 +77,60 @@ Arrows show dependencies between modules. Green boxes show which features are im This project aims to simulate complex systems like this, mainly composed of robots. ## Build & test -#### Dependencies -To build atta properly, you need to have cmake installed. -Dependencies for some operating systems: - -**Windows:** -```bash -choco install cmake -``` -**MacOS:** -```bash -brew install cmake -``` + +
Windows +

Dependencies

+To build atta properly, you need to have cmake installed. +
choco install cmake
+Also, be sure that your **compiller supports C++17** (g++ >= 9.0). -**Linux:** -```bash -sudo apt-get install cmake xorg-dev curl -``` +

Run

+
git clone git@github.com:brenocq/atta.git
+cd atta
+mkdir build
+cd build
+cmake ..
+
+ +You can now use Visual Studio to open the atta.sln file. +
+ +
MacOS +

Dependencies

+To build atta properly, you need to have cmake installed. +
brew install cmake
+Also, be sure that your **compiller supports C++17** (g++ >= 9.0). -#### Clone -Atta should build without errors when the **compiller supports C++17** (g++ >= 9.0). +

Run

+
git clone git@github.com:brenocq/atta.git
+cd atta
+./scripts/build.sh --help
+./scripts/build.sh
+./build/release/bin/atta_test
+./build/release/bin/atta
+
+
+ +
Linux +

Dependencies

+To build atta properly, you need to have cmake installed. +
sudo apt-get install cmake xorg-dev curl
-If you found any errors, please do not hesitate to [create an issue](https://github.com/brenocq/atta/issues/new?assignees=brenocq&labels=fix&template=bug_report.md&title=) :wink:. +Also, be sure that your **compiller supports C++17** (g++ >= 9.0). -```bash -git clone git@github.com:brenocq/atta.git +

Run

+
git clone git@github.com:brenocq/atta.git
 cd atta
 ./scripts/build.sh --help
 ./scripts/build.sh
 ./build/release/bin/atta_test
 ./build/release/bin/atta
-```
+
+
+ +If you found any errors, please do not hesitate to [create an issue](https://github.com/brenocq/atta/issues/new?assignees=brenocq&labels=fix&template=bug_report.md&title=) :wink:. -_Obs: The build script should help the user with dependencies. If you found ploblems please let me know_ ## Discussions If you want to contribute, have ideas, or have questions about atta, feel free to [start a discussion](https://github.com/brenocq/atta/discussions). From d7777f4116b9697c24ded6ccad03f6c1ea4e36bc Mon Sep 17 00:00:00 2001 From: brenocq Date: Mon, 19 Sep 2022 14:50:39 +0200 Subject: [PATCH 07/28] Feat: Linux scripting with included files #37 --- CMakeLists.txt | 3 +- README.md | 6 +- src/atta/atta.cpp | 81 +++++++++++---------- src/atta/component/factory.cpp | 22 ------ src/atta/pch.h | 3 +- src/atta/script/compilers/compiler.cpp | 46 +++++++++++- src/atta/script/compilers/compiler.h | 3 +- src/atta/script/compilers/linuxCompiler.cpp | 42 ++++++----- src/atta/script/compilers/linuxCompiler.h | 2 +- src/atta/script/compilers/nullCompiler.h | 1 - src/atta/script/linkers/linuxLinker.cpp | 2 - src/atta/script/managerDynamic.cpp | 1 - src/atta/ui/layers/editor/editorLayer.cpp | 6 +- src/main.cpp | 18 ++--- 14 files changed, 135 insertions(+), 101 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a52d3cd5..fac48632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,8 +22,8 @@ set(ATTA_VERSION_SAFE atta-${CMAKE_PROJECT_VERSION}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/atta/cmakeConfig.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/atta/cmakeConfig.h) +# Set flags necessary for the script system to work correctly if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # Set flags necessary for the script system to work correctly set(CMAKE_CXX_FLAGS "-Wl,--export-dynamic") set(CMAKE_EXE_LINKER_FLAGS "-Wl,--export-dynamic") endif() @@ -262,6 +262,7 @@ if(NOT (ATTA_SYSTEM_NAME MATCHES "Web") AND NOT ATTA_STATIC_PROJECT_FILE) list(APPEND ATTA_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}) list(APPEND ATTA_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}/extern/imgui) list(APPEND ATTA_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}/extern/implot) + list(APPEND ATTA_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}/extern/segvcatch/lib) list(APPEND ATTA_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}/extern/glad/include) list(APPEND ATTA_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}/extern/stb_image) set(ATTA_INSTALL_PCH ${CMAKE_INSTALL_PREFIX}/include/${ATTA_VERSION_SAFE}/atta/pch.h) diff --git a/README.md b/README.md index 0a3a3fb8..1136031b 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ This project aims to simulate complex systems like this, mainly composed of robo

Dependencies

To build atta properly, you need to have cmake installed.
choco install cmake
-Also, be sure that your **compiller supports C++17** (g++ >= 9.0). +Also, be sure that your compiller supports C++17 (g++ >= 9.0).

Run

git clone git@github.com:brenocq/atta.git
@@ -100,7 +100,7 @@ You can now use Visual Studio to open the atta.sln file.
 

Dependencies

To build atta properly, you need to have cmake installed.
brew install cmake
-Also, be sure that your **compiller supports C++17** (g++ >= 9.0). +Also, be sure that your compiller supports C++17 (g++ >= 9.0).

Run

git clone git@github.com:brenocq/atta.git
@@ -117,7 +117,7 @@ cd atta
 To build atta properly, you need to have cmake installed.
 
sudo apt-get install cmake xorg-dev curl
-Also, be sure that your **compiller supports C++17** (g++ >= 9.0). +Also, be sure that your compiller supports C++17 (g++ >= 9.0).

Run

git clone git@github.com:brenocq/atta.git
diff --git a/src/atta/atta.cpp b/src/atta/atta.cpp
index fb96f53b..ab09e8cf 100644
--- a/src/atta/atta.cpp
+++ b/src/atta/atta.cpp
@@ -69,9 +69,8 @@ Atta::Atta(const CreateInfo& info) : _shouldFinish(false), _simulationState(Simu
         LOG_WARN("Atta", "Project [w]$0[] will not be open because atta was built statically linked to [w]$1[]", info.projectFile, projectFile);
 #else
     // If a project was defined as argument, open project
-    if (!info.projectFile.empty())
-    {
-        graphics::update();// Need to update to register the viewports
+    if (!info.projectFile.empty()) {
+        graphics::update(); // Need to update to register the viewports
         file::openProject(info.projectFile);
     }
 #endif
@@ -123,24 +122,32 @@ void Atta::loop() {
         if (project)
             project->onUpdateBefore(dt);
 
-        // Run entity scripts
-        // TODO keep list of entities that have script (and are not prototype entities)
+        // Run clone scripts
+        for (auto& factory : component::getFactories())
+            factory.runScripts(dt);
+
+        // Run scripts of other entities (not clones)
+        const auto& factories = component::getFactories();
+        std::vector> beginEndClones(factories.size());
+        for (const auto& factory : factories)
+            beginEndClones.push_back({factory.getFirstClone(), factory.getLastClone()});
         std::vector entities = component::getScriptView();
         for (component::EntityId entity : entities) {
+            // Check if it it not clone entity
+            for(auto [begin, end] : beginEndClones)
+                if(entity >= begin && entity <= end)
+                    continue;
+            
+            // Check if it is not prototype entity
             component::Script* scriptComponent = component::getComponent(entity);
             component::Prototype* prototypeComponent = component::getComponent(entity);
             if (scriptComponent && !prototypeComponent) {
-                // std::vector components = component::getComponents(entity);
                 script::Script* script = script::getScript(scriptComponent->sid);
                 if (script)
                     script->update(component::Entity(entity), dt);
             }
         }
 
-        // Run clone scripts
-        for (auto& factory : component::getFactories())
-            factory.runScripts(dt);
-
         if (project)
             project->onUpdateAfter(dt);
     }
@@ -171,33 +178,33 @@ void Atta::onWindowClose(event::Event& event) { _shouldFinish = true; }
 void Atta::onSimulationStateChange(event::Event& event) {
     script::ProjectScript* project = script::getProjectScript();
     switch (event.getType()) {
-    case event::SimulationStart::type: {
-        if (project)
-            project->onStart();
-        _simulationState = SimulationState::RUNNING;
-        break;
-    }
-    case event::SimulationContinue::type: {
-        if (project)
-            project->onContinue();
-        _simulationState = SimulationState::RUNNING;
-        break;
-    }
-    case event::SimulationPause::type: {
-        if (project)
-            project->onPause();
-        _simulationState = SimulationState::PAUSED;
-        break;
-    }
-    case event::SimulationStop::type: {
-        if (project)
-            project->onStop();
-        _simulationState = SimulationState::NOT_RUNNING;
-        break;
-    }
-    default: {
-        LOG_WARN("Atta", "Unknown simulation event");
-    }
+        case event::SimulationStart::type: {
+            if (project)
+                project->onStart();
+            _simulationState = SimulationState::RUNNING;
+            break;
+        }
+        case event::SimulationContinue::type: {
+            if (project)
+                project->onContinue();
+            _simulationState = SimulationState::RUNNING;
+            break;
+        }
+        case event::SimulationPause::type: {
+            if (project)
+                project->onPause();
+            _simulationState = SimulationState::PAUSED;
+            break;
+        }
+        case event::SimulationStop::type: {
+            if (project)
+                project->onStop();
+            _simulationState = SimulationState::NOT_RUNNING;
+            break;
+        }
+        default: {
+            LOG_WARN("Atta", "Unknown simulation event");
+        }
     }
 }
 } // namespace atta
diff --git a/src/atta/component/factory.cpp b/src/atta/component/factory.cpp
index 7bbf835f..e866b75a 100644
--- a/src/atta/component/factory.cpp
+++ b/src/atta/component/factory.cpp
@@ -70,7 +70,6 @@ void Factory::destroyClones() {
 }
 
 void Factory::runScripts(float dt) {
-    // TODO faster
     unsigned cloneId = 0;
     for (EntityId entity = _firstCloneEid; entity < EntityId(_firstCloneEid + _maxClones); entity++) {
         Script* scriptComponent = component::getComponent