Add example application.

Add Python script to upload artifacts to official Screeps server.
This commit is contained in:
Kirill Kirilenko 2021-06-13 22:45:26 +03:00
parent 07c0b0ac80
commit df40a222e5
7 changed files with 150 additions and 1 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.idea
cmake-build-*
example/dist

View file

@ -2,7 +2,8 @@ cmake_minimum_required(VERSION 3.16)
project(screepsxx CXX)
option(SCREEPSXX_ENABLE_PCH ON "Enable precompiled headers")
option(SCREEPSXX_ENABLE_PCH "Enable precompiled headers" ON)
option(SCREEPSXX_BUILD_EXAMPLE "Build example WASM application" OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
@ -26,3 +27,7 @@ if (SCREEPSXX_ENABLE_PCH)
<emscripten/val.h>
)
endif()
if (SCREEPSXX_BUILD_EXAMPLE)
add_subdirectory(example)
endif()

19
example/CMakeLists.txt Normal file
View file

@ -0,0 +1,19 @@
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s ENVIRONMENT=shell")
add_executable(example loop.cpp)
target_link_libraries(example screepsxx)
target_link_options(example PUBLIC -sMODULARIZE=1 --no-entry --bind)
# Collect all artifacts in 'dist' directory
add_custom_command(TARGET example POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/example.wasm ${CMAKE_CURRENT_SOURCE_DIR}/dist/my_module.wasm)
add_custom_command(TARGET example POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/example.js ${CMAKE_CURRENT_SOURCE_DIR}/dist/my_loader.js)
add_custom_command(TARGET example POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/js/main.js ${CMAKE_CURRENT_SOURCE_DIR}/dist/main.js)
add_custom_command(TARGET example POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/js/wasm_loader.js ${CMAKE_CURRENT_SOURCE_DIR}/dist/wasm_loader.js)
# You can add post-build step to automatically upload artifacts to
# official Screeps server using Python script in 'tools' directory.
# To do so, uncomment following lines and set SCREEPS_TOKEN environment
# variable to your Screeps API token (https://docs.screeps.com/auth-tokens.html).
#
#find_package(Python COMPONENTS Interpreter REQUIRED)
#add_custom_command(TARGET example POST_BUILD COMMAND ${Python_EXECUTABLE} ${screepsxx_SOURCE_DIR}/tools/upload.py ${CMAKE_CURRENT_SOURCE_DIR}/dist $ENV{SCREEPS_TOKEN})

14
example/js/main.js Normal file
View file

@ -0,0 +1,14 @@
'use strict';
const wasm_loader = require('wasm_loader')
var mod;
wasm_loader('my_loader', 'my_module').then((instance) => {
console.log("WASM module loaded.");
mod = instance;
});
module.exports.loop = function () {
if (mod !== undefined)
mod.loop();
}

24
example/js/wasm_loader.js Normal file
View file

@ -0,0 +1,24 @@
'use strict';
module.exports = ((mod_js, mod_wasm, opts) => {
const mod_file = require(mod_js);
const bin_file = require(mod_wasm);
opts = opts || {};
opts.wasmBinary = bin_file;
opts.print = opts.print || ((text) => console.log(text));
opts.printErr = opts.printErr || ((text) => console.log(`error: ${text}`));
opts.onAbort = opts.onAbort || (() => console.log('WASM aborted!!!'));
// == don't call main()
if (typeof opts.noInitialRun === "undefined")
opts.noInitialRun = true;
// == don't terminate after returning from main()
if (typeof opts.noExitRuntime === "undefined")
opts.noExitRuntime = true;
return mod_file(opts);
});

20
example/loop.cpp Normal file
View file

@ -0,0 +1,20 @@
#include <Screeps/Context.hpp>
#include <Screeps/Creep.hpp>
#include <emscripten.h>
#include <emscripten/bind.h>
EMSCRIPTEN_KEEPALIVE
extern "C" void loop()
{
Screeps::Context::update();
auto creeps = Screeps::Game.creeps();
for (auto& creep : creeps)
creep.second.say("screepsxx");
}
EMSCRIPTEN_BINDINGS(loop)
{
emscripten::function("loop", &loop);
}

66
tools/upload.py Normal file
View file

@ -0,0 +1,66 @@
import os
import sys
import glob
import base64
import requests
import humanize
def get_file_list(directory):
return glob.glob(directory + '/*')
def read_file_to_json_string(filename):
file_ext = os.path.splitext(os.path.basename(filename))[1]
if file_ext == '.js':
with open(filename, 'r') as reader:
return reader.read()
else:
with open(filename, 'rb') as reader:
return {'binary': base64.b64encode(reader.read()).decode('utf-8')}
def upload_files(files, token, branch):
modules = {}
for file in files:
name = os.path.splitext(os.path.basename(file))[0]
content = read_file_to_json_string(file)
modules[name] = content
print('Read {} from {}'.format(humanize.naturalsize(os.path.getsize(file)), file))
request_body = {
'branch': branch,
'modules': modules
}
headers = {'X-Token': token}
r = requests.post('https://screeps.com/api/user/code', headers=headers, json=request_body)
response = r.json()
if 'ok' in response:
print('done')
return 0
elif 'error' in response:
print('failed: ' + response['error'])
return 1
else:
print('unexpected response: ' + r.text)
return 1
argc = len(sys.argv)
if argc != 3 and argc != 4:
print('Usage: upload.py <directory> <token> [branch=default]')
exit(1)
target_directory = sys.argv[1]
token = sys.argv[2]
if argc == 4:
branch = sys.argv[3]
else:
branch = 'default'
files = get_file_list(target_directory)
status = upload_files(files, token, branch)
exit(status)