Skip to content

Commit

Permalink
Initial C++ engine and Typescript web package
Browse files Browse the repository at this point in the history
Web package is based on Typescript, React and Vite. Engine is compiled
to WASM.
  • Loading branch information
juztamau5 committed Mar 14, 2024
1 parent 2cc3a1b commit 6d83586
Show file tree
Hide file tree
Showing 32 changed files with 3,957 additions and 0 deletions.
109 changes: 109 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
################################################################################
#
# Copyright (C) 2023-2024 retro.ai
# This file is part of retro3 - https://github.com/retroai/retro3
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# See the file LICENSE.txt for more information.
#
################################################################################

name: Node.js CI

on: [push, pull_request]

jobs:
build-and-deploy:
# The type of runner that the job will run on
runs-on: ${{ matrix.os }}

defaults:
run:
# Set the working directory to frontend folder
working-directory: src/frontend

strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
node-version: 20
- os: ubuntu-22.04
node-version: 21

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Cache vite build files
id: cache-vite
uses: actions/cache@v4
with:
path: |
src/frontend/dist
key: cache-vite-${{ matrix.os }}-${{ matrix.node-version }}-${{ hashFiles('src/frontend/**') }}

- name: Cache pnpm modules
id: cache-modules
uses: actions/cache@v4
with:
path: |
src/frontend/node_modules
key: cache-modules-${{ matrix.os }}-${{ matrix.node-version }}-${{ hashFiles('src/frontend/pnpm-lock.yaml') }}

- name: Cache emsdk
id: cache-emsdk
uses: actions/cache@v4
with:
path: |
tools/emsdk
key: cache-emsdk-${{ hashFiles('tools/download-emscripten.sh') }}

- name: Cache WASM libraries
id: cache-wasm
uses: actions/cache@v4
with:
path: |
src/frontend/public/wasm
src/frontend/src/wasm
key: cache-wasm-${{ matrix.os }}-${{ matrix.node-version }}-${{ hashFiles('src/engine/**', 'tools/build-wasm.sh', 'tools/download-emscripten.sh') }}

- name: Install emsdk
if: steps.cache-emsdk.outputs.cache-hit != 'true'
run: |
./download-emscripten.sh
working-directory: tools

- name: Build wasm libraries
if: steps.cache-wasm.outputs.cache-hit != 'true'
run: |
./build-wasm.sh
working-directory: tools

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}

- name: Install pnpm
run: |
npm install -g pnpm
- name: pnpm install
if: steps.cache-modules.outputs.cache-hit != 'true'
run: |
pnpm install
- name: pnpm audit-ci
run: |
pnpm audit-ci
- name: pnpm lint
if: steps.cache-vite.outputs.cache-hit != 'true'
run: |
pnpm lint
- name: pnpm build
if: steps.cache-vite.outputs.cache-hit != 'true'
run: |
pnpm build
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ The following subfolders compose the repo architecture:

* `src/backend/` - The Cartesi Machine logic
* `src/frontend/` - The website and frontend logic
* `src/engine/` - The main emulator engine
* `src/learning/` - The Python code for AI agents
* `tools/` - Tooling for dependencies

Expand Down
78 changes: 78 additions & 0 deletions src/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
################################################################################
#
# Copyright (C) 2024 retro.ai
# This file is part of retro3 - https://github.com/retroai/retro3
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# See the file LICENSE.txt for more information.
#
################################################################################

################################################################################
# Project settings
################################################################################

project(retro_engine LANGUAGES CXX)
cmake_minimum_required(VERSION 3.10)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

################################################################################
# Dependencies
################################################################################

# TODO

################################################################################
# Sources
################################################################################

set(SOURCE_FILES
core/retro_engine.cpp
core/retro_engine_embinder.cpp
)

################################################################################
# Libraries
################################################################################

# Add the executable based on the source files
add_executable(retro_engine ${SOURCE_FILES})

# Add flags for Empscripten builds
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set_target_properties(retro_engine PROPERTIES
COMPILE_FLAGS " \
-O3 \
"
# 26214400 is 25 MiB
LINK_FLAGS " \
-gsource-map \
-s ALLOW_MEMORY_GROWTH=1 \
-s EXPORT_ES6=1 \
-s INITIAL_MEMORY=26214400 \
-s MODULARIZE=1 \
-s USE_WEBGL2=1 \
-s WASM=1 \
--bind \
--embind-emit-tsd retro_engine.d.ts \
--source-map-base https://retro.ai/ \
"
)
endif ()

################################################################################
# Install
################################################################################

INSTALL(
FILES
"${CMAKE_BINARY_DIR}/retro_engine.d.ts"
"${CMAKE_BINARY_DIR}/retro_engine.js"
"${CMAKE_BINARY_DIR}/retro_engine.wasm"
"${CMAKE_BINARY_DIR}/retro_engine.wasm.map"
DESTINATION
wasm
)
90 changes: 90 additions & 0 deletions src/engine/core/retro_engine.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2024 retro.ai
* This file is part of retro3 - https://github.com/retroai/retro3
*
* SPDX-License-Identifier: AGPL-3.0-or-later
* See the file LICENSE.txt for more information.
*/

#include "retro_engine.hpp"

#include <iostream>
#include <stdexcept>
#include <string>

#include <GLES3/gl3.h>

namespace
{
constexpr const char* CANVAS_ID = "#retroEngine";
}

RetroEngine::RetroEngine() : m_webGLContext(0)
{
}

RetroEngine::~RetroEngine()
{
Deinitialize();
}

bool RetroEngine::Initialize()
{
if (!InitializeWebGL())
return false;

return true;
}

void RetroEngine::Deinitialize()
{
DeinitializeWebGL();
}

bool RetroEngine::InitializeWebGL()
{
EmscriptenWebGLContextAttributes attrs;
emscripten_webgl_init_context_attributes(&attrs);

attrs.alpha = EM_TRUE;
attrs.depth = EM_TRUE;
attrs.stencil = EM_TRUE;
attrs.antialias = EM_TRUE;
attrs.preserveDrawingBuffer = EM_FALSE;
attrs.powerPreference = EM_WEBGL_POWER_PREFERENCE_HIGH_PERFORMANCE;
attrs.failIfMajorPerformanceCaveat = EM_FALSE;
attrs.majorVersion = 2;
attrs.minorVersion = 0;

const EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context =
emscripten_webgl_create_context(CANVAS_ID, &attrs);
if (context <= 0)
throw std::runtime_error("Failed to create WebGL context");

EMSCRIPTEN_RESULT result = emscripten_webgl_make_context_current(context);
if (result != EMSCRIPTEN_RESULT_SUCCESS)
throw std::runtime_error("Failed to make WebGL context current: " + std::to_string(result));

// Success
m_webGLContext = context;

// Set the clear color to black (RGBA)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);

return true;
}

void RetroEngine::DeinitializeWebGL()
{
if (m_webGLContext > 0)
{
EMSCRIPTEN_RESULT result = emscripten_webgl_destroy_context(m_webGLContext);
if (result != EMSCRIPTEN_RESULT_SUCCESS)
std::cerr << "Failed to destroy WebGL context (result=" << result << ")" << std::endl;

m_webGLContext = 0;
}
}
36 changes: 36 additions & 0 deletions src/engine/core/retro_engine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 retro.ai
* This file is part of retro3 - https://github.com/retroai/retro3
*
* SPDX-License-Identifier: AGPL-3.0-or-later
* See the file LICENSE.txt for more information.
*/

#pragma once

#include <emscripten/html5.h>

class RetroEngine
{
public:
RetroEngine();
~RetroEngine();

/*!
* \brief Initialize the engine
*
* \return true if successful, false otherwise
*/
bool Initialize();

/*!
* \brief Deinitialize the engine
*/
void Deinitialize();

private:
bool InitializeWebGL();
void DeinitializeWebGL();

EMSCRIPTEN_WEBGL_CONTEXT_HANDLE m_webGLContext;
};
19 changes: 19 additions & 0 deletions src/engine/core/retro_engine_embinder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (C) 2024 retro.ai
* This file is part of retro3 - https://github.com/retroai/retro3
*
* SPDX-License-Identifier: AGPL-3.0-or-later
* See the file LICENSE.txt for more information.
*/

#include "retro_engine.hpp"

#include <emscripten/bind.h>

EMSCRIPTEN_BINDINGS(engine)
{
emscripten::class_<RetroEngine>("RetroEngine")
.constructor<>()
.function("initialize", &RetroEngine::Initialize)
.function("deinitialize", &RetroEngine::Deinitialize);
}
8 changes: 8 additions & 0 deletions src/frontend/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Generated by Node
/dist
/node_modules
/pnpm-lock.yaml

# Generated WASM files
/public/wasm
/src/wasm
17 changes: 17 additions & 0 deletions src/frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "simple-import-sort"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"env": {
"browser": true,
"es2020": true,
"mocha": true,
"node": true
},
"rules": {
"brace-style": ["error", "1tbs", { "allowSingleLine": false }],
"curly": ["error", "all"],
"simple-import-sort/imports": "error"
}
}
8 changes: 8 additions & 0 deletions src/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Generated by Node
/dist
/node_modules
/yarn-*.log*

# Generated WASM files
/public/wasm
/src/wasm
8 changes: 8 additions & 0 deletions src/frontend/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Generated by Node
/dist
/node_modules
/pnpm-lock.yaml

# Generated WASM files
/public/wasm
/src/wasm
3 changes: 3 additions & 0 deletions src/frontend/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tabWidth": 2
}
Loading

0 comments on commit 6d83586

Please sign in to comment.