Commit 11dddae1 authored by ForkCreativeMedia's avatar ForkCreativeMedia

Added files

parent 9102a907
cmake_minimum_required (VERSION 3.1.3)
if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
message(FATAL_ERROR "In-source builds not allowed. Please delete CMakeCache.txt and CMakeFiles folder from the source directory.")
endif()
set(PACKAGE_NAME "basic_web_demos")
set(EXPORT_NAME ${PACKAGE_NAME}-targets)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(INCLUDE_INSTALL_DIR "include")
set(LIB_INSTALL_DIR "lib")
set(BIN_INSTALL_DIR "bin")
set(CMAKE_CONFIG_INSTALL_DIR "cmake")
project(${PACKAGE_NAME})
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
#Global settings
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(BUILD_WASM "Build WebAssembly demos" FALSE)
if(BUILD_WASM)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=1")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s WASM=0")
endif()
if(WIN32)
option(BUILD_USE_SOLUTION_FOLDERS "Usage of solution folders in visual studio" ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ${BUILD_USE_SOLUTION_FOLDERS})
endif()
#----------------------------------------------------------------------------------------------------------------------------
add_subdirectory(demos)
include(CMakePackageConfigHelpers)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/ DESTINATION bin/data)
if(BUILD_WASM)
install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/ DESTINATION bin/data/js FILES_MATCHING PATTERN "*.wasm")
endif()
fieldset.demo {
border: 1px solid black;
padding: 10px;
border-radius: 8px;
}
div.demo {
display: flex;
flex-wrap: wrap;
border:0px solid black
}
textarea.demo {
width: 100%;
height: 100%;
outline: none;
resize: vertical;
background-color: black;
color: white;
font-family: 'Lucida Console', Monaco, monospace;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
canvas.demo{
border: 1px solid;
margin: 10px;
}
button.demo{
margin: 5px;
padding: 10px;
}
label.demo {
display: block;
margin-bottom: 10px;
font-size: 20px;
}
//Print output to HTML textarea which simulates C/C++ console output.
//Set print_js_log to true to print to js console as well. Set is_error to true to print an error.
function printConsole(textarea_name = 'textarea_console_output', print_js_log = true, is_error = false){
//Code snippet taken from emscriptens shell_minimal.html with slight modifications.
//https://github.com/emscripten-core/emscripten/blob/master/src/shell_minimal.html
var element = document.getElementById(textarea_name);
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
if(print_js_log){
if(is_error) console.error(text);
else console.log(text);
}
if (element) {
if(is_error) element.value += "Error: " + text + "\n";
else element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom.
}
};
}
//Enables the fieldset with the given name and updates the status message.
function enableIOFieldset(fieldset_io_id = 'fieldset_input_output', p_status_id = 'p_status') {
let status_output = document.getElementById(p_status_id);
let fieldset_io = document.getElementById(fieldset_io_id);
if(status_output)
status_output.innerHTML = 'Script is ready!';
if(fieldset_io)
fieldset_io.disabled = false;
}
function objToString (obj, verbose) {
verbose = typeof verbose === 'undefined' ? true : false;
if(Object.keys(obj).length === 0)
return '[]';
var str = '[';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
if(verbose === true)
str += p + ': ' + obj[p] + ', ' ;
else
str += obj[p] + ', ' ;
}
}
return str.slice(0, -2) + ']';
}
//Draws image data onto the canvas.
function setCanvas(image_data, width, height, canvas_name) {
var canvas = document.getElementById(canvas_name);
var imageData = new ImageData(new Uint8ClampedArray(image_data), width, height);
canvas.width = width;
canvas.height = height;
if (canvas)
canvas.getContext('2d').putImageData(imageData, 0, 0);
}
add_subdirectory(classes)
add_subdirectory(hello_world)
add_subdirectory(image_handling)
add_subdirectory(lerp)
add_subdirectory(module)
cmake_minimum_required(VERSION 3.0.2)
set(TARGET_NAME "classes_example")
project (${TARGET_NAME})
set(DEMO_SRC classes_example.cpp)
add_executable (${TARGET_NAME} ${DEMO_SRC})
set(EMSCRIPTEN_LINK_FLAGS "--bind")
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin/data/js)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/classes_example.html DESTINATION bin)
\ No newline at end of file
#include <emscripten/bind.h>
#include <emscripten/emscripten.h>
#include <string>
#include <memory>
#include <iostream>
class Animal{
public:
Animal(std::string animal, int num_legs) : animal_(animal), num_legs_(num_legs){
std::cout<<"Animal constructor! ("<<animal_<<") ";
}
virtual ~Animal(){
std::cout<<"Animal destructor! ("<<animal_<<") "<<std::endl;
}
int getNumLegs(bool print = true) const{
if(print) std::cout<<"Num legs: "<<num_legs_<<std::endl;
return num_legs_;
}
virtual void printInfo() const{
std::cout<<"Animal: "<<animal_<<std::endl;
std::cout<<"Number of legs: "<<num_legs_<<std::endl;
speak();
}
virtual std::string speak(bool print = true) const = 0;
protected:
int num_legs_;
std::string animal_;
};
class Chicken : public Animal{
public:
Chicken() : Animal("Chicken", 2){
std::cout<<"Chicken constructor! "<<std::endl;
}
virtual ~Chicken(){
std::cout<<"Chicken destructor! ";
}
virtual std::string speak(bool print = true) const{
std::string sound = "Cluck!";
if(print) std::cout<<sound<<std::endl;
return sound;
}
};
class Dog : public Animal{
public:
Dog(std::string name = "") : Animal("Dog", 4){
name_ = name;
std::cout<<"Dog constructor! "<<name_ <<std::endl;
}
virtual ~Dog(){
std::cout<<"Dog destructor!"<<(name_.empty() ? " " : " " + name_ +" ");
}
virtual std::string speak(bool print = true) const{
std::string sound = "Woof!";
if(print) std::cout<<sound<<std::endl;
return sound;
}
std::string getName() const{
return name_;
}
void setName(std::string name){
name_ = name;
}
virtual void printInfo() const{
if(!name_.empty()) std::cout<<"Name: "<<name_<<std::endl;
Animal::printInfo();
}
private:
std::string name_;
};
class DogOwner{
public:
DogOwner(){
std::cout<<"DogOwner constructor!"<<std::endl;
//Dog owner has at least one dog.
dogs_.push_back(std::make_shared<Dog>("Bello"));
}
~DogOwner(){
std::cout<<"DogOwner destructor!"<<std::endl;
}
void addDog(std::shared_ptr<Dog> dog){
dogs_.push_back(dog);
std::cout<<"Added dog: "<<dog->getName()<<"! Number of dogs now: "<<dogs_.size()<<std::endl;
}
void printDogs() const{
std::cout<<"Dogs owned by dog owner: "<<std::endl;
for(size_t i = 0; i < dogs_.size(); ++i){
std::cout<<i + 1<<". "<<dogs_.at(i)->getName()<<": "<<dogs_.at(i)->speak(false)<<" ---> ref count: "<<dogs_.at(i).use_count()<<std::endl;
}
}
private:
std::vector<std::shared_ptr<Dog>> dogs_;
};
Animal* createAnimalRawPointer(const std::string animal){
if(animal == "Dog") return new Dog();
else if(animal == "Chicken") return new Chicken();
else return nullptr;
}
std::shared_ptr<Dog> createDogSharedPointer(std::string name){
return std::make_shared<Dog>(name);
}
void consolePrintLine(){
std::cout<<"-------------------------------------------------"<<std::endl;
}
void consolePrintHeader(std::string header_line){
std::cout<<"-----------------------------------------------------------------------------"<<std::endl;
std::cout<<header_line<<std::endl;
std::cout<<"-----------------------------------------------------------------------------"<<std::endl;
}
int main(int argc, char ** argv) {
std::cout<<"---------- C++ main reached. ----------\n"<<std::endl;
std::vector<std::shared_ptr<Animal>> animals;
animals.push_back(std::make_shared<Dog>());
animals.push_back(std::make_shared<Chicken>());
for(size_t i = 0; i <animals.size(); ++i){
std::cout<<std::endl;
animals.at(i)->printInfo();
}
std::cout<<"\n---------- C++ main end reached. ----------"<<std::endl;
}
EMSCRIPTEN_BINDINGS(my_module) {
emscripten::class_<Animal>("Animal")
.function("getNumLegs", &Animal::getNumLegs)
.function("printInfo", &Animal::printInfo)
.function("speak", &Animal::speak)
;
emscripten::class_<Chicken, emscripten::base<Animal>>("Chicken")
.constructor()
;
emscripten::class_<Dog, emscripten::base<Animal>>("Dog")
.constructor()
.constructor<std::string>()
.smart_ptr<std::shared_ptr<Dog>>("shared_ptr<Dog>")
.property("name", &Dog::getName, &Dog::setName)
;
emscripten::class_<DogOwner>("DogOwner")
.smart_ptr_constructor("DogOwner", &std::make_shared<DogOwner>)
.function("addDog", &DogOwner::addDog)
.function("printDogs", &DogOwner::printDogs)
;
emscripten::function("consolePrintLine", &consolePrintLine);
emscripten::function("consolePrintHeader", &consolePrintHeader);
emscripten::function("createDogSharedPointer", &createDogSharedPointer);
emscripten::function("createAnimalRawPointer", &createAnimalRawPointer, emscripten::allow_raw_pointers());
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Classes</title>
<link rel="stylesheet" href="data/css/demo_theme.css">
</head>
<body>
<h2>Classes</h2>
<p id="p_status">Javascript file is loading...</p>
<fieldset class="demo" id="fieldset_input_output" disabled="false">
<input type="button" value="Create Animals" id="button_interaction_animals" onclick="createAnimals();">
<input type="button" value="Create DogOwner" id="button_interaction_dog_owner" onclick="createDogOwner()">
<hr><label class="demo" for="textarea_console_output">C++ output:</label>
<textarea class="demo" id="textarea_console_output" name="textarea_console_output" rows="25"></textarea>
</fieldset>
<script src="data/js/tools.js"></script>
<script type="text/javascript">
var Module = {};
//Module['noInitialRun'] = true; //Don't run main function.
Module['print'] = printConsole('textarea_console_output', true, false);
Module['printErr'] = printConsole('textarea_console_output', true, true);
Module['onRuntimeInitialized'] = function() {
enableIOFieldset('fieldset_input_output', 'p_status');
}
function createAnimals(){
document.getElementById('textarea_console_output').value = '';
Module.consolePrintHeader('CREATE ANIMALS');
//Create an array and add a dog as the first element.
var animals = [new Module.Dog()];
//Generate 4 random animals and add them to the array.
var animal_types = ['Dog', 'Chicken'];
for (n = 0; n < 4; n++) {
let random = Math.round(Math.random());
animals.push(Module.createAnimalRawPointer(animal_types[random]));
}
Module.consolePrintLine();
for (i = 0; i < animals.length; i++) {
animals[i].speak(true);
}
Module.consolePrintLine();
//Give first dog a name.
animals[0].name = 'Lissi';
for (i = 0; i < animals.length; i++) {
animals[i].delete();
}
}
function createDogOwner(){
document.getElementById('textarea_console_output').value = '';
Module.consolePrintHeader('CREATE DOG OWNER');
let dog_owner = new Module.DogOwner();
let dog = Module.createDogSharedPointer('Fiffi');
Module.consolePrintLine();
dog_owner.printDogs();
Module.consolePrintLine();
dog_owner.addDog(dog);
Module.consolePrintLine();
dog_owner.printDogs();
dog.delete(); // Destructor isn't called here because there is still a reference in dog_owner.
Module.consolePrintLine();
dog_owner.printDogs();
Module.consolePrintLine();
dog_owner.delete();
}
</script>
<script src="data/js/classes_example.js" type="text/javascript"></script>
</body>
</html>
cmake_minimum_required(VERSION 3.0.2)
set(TARGET_NAME "hello_world")
project (${TARGET_NAME})
set(DEMO_SRC hello_world.cpp)
add_executable (${TARGET_NAME} ${DEMO_SRC})
set(EMSCRIPTEN_LINK_FLAGS "--bind")
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin/data/js)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello_world.html DESTINATION bin)
#include <iostream>
int main(int argc, char ** argv) {
std::cout<<"C++ main reached. (Hello world!)"<<std::endl;
std::cerr<<"Test error!"<<std::endl;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Hello world</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="">
<link rel="stylesheet" href="data/css/demo_theme.css">
</head>
<body>
<h2>Hello world </h2>
<p id="p_status">Javascript file is loading...</p>
<fieldset class="demo" id="fieldset_input_output" disabled>
<label class="demo" for="textarea_console_output">C++ output:</label>
<textarea class="demo" id="textarea_console_output" name="textarea_console_output" rows="10"></textarea>
</fieldset>
<script sync src="data/js/tools.js" type="text/javascript" ></script>
<script type='text/javascript'>
var Module = {};
Module['print'] = printConsole('textarea_console_output', true, false);
Module['printErr'] = printConsole('textarea_console_output', true, true);
Module['onRuntimeInitialized'] = function() {setRuntimeInitialized();}
Module['preInit'] = function() {console.log('preInit'); }
Module['preRun'] = function() {console.log('preRun'); }
Module['postRun'] = function() {console.log('postRun'); }
function setRuntimeInitialized() {
console.log("onRuntimeInitialized");
enableIOFieldset('fieldset_input_output', 'p_status');
}
</script>
<script async src="data/js/hello_world.js" type="text/javascript"></script>
</body>
</html>
\ No newline at end of file
cmake_minimum_required(VERSION 3.0.2)
set(TARGET_NAME "hello_world")
project (${TARGET_NAME})
set(DEMO_SRC hello_world.cpp)
add_executable (${TARGET_NAME} ${DEMO_SRC})
set(EMSCRIPTEN_LINK_FLAGS "--bind")
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
#install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin/data/js)
#install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello_world.html DESTINATION bin)
#include <iostream>
int main(int argc, char ** argv) {
std::cout<<"C++ main reached. (Hello world!)"<<std::endl;
std::cerr<<"Test error!"<<std::endl;
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Hello world</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="">
<link rel="stylesheet" href="data/css/demo_theme.css">
</head>
<body>
<h2>Hello world </h2>
<p id="p_status">Javascript file is loading...</p>
<fieldset class="demo" id="fieldset_input_output" disabled>
<label class="demo" for="textarea_console_output">C++ output:</label>
<textarea class="demo" id="textarea_console_output" name="textarea_console_output" rows="10"></textarea>
</fieldset>
<script sync src="data/js/tools.js" type="text/javascript" ></script>
<script type='text/javascript'>
var Module = {};
Module['print'] = printConsole('textarea_console_output', true, false);
Module['printErr'] = printConsole('textarea_console_output', true, true);
Module['onRuntimeInitialized'] = function() {setRuntimeInitialized();}
Module['preInit'] = function() {console.log('preInit'); }
Module['preRun'] = function() {console.log('preRun'); }
Module['postRun'] = function() {console.log('postRun'); }
function setRuntimeInitialized() {
console.log("onRuntimeInitialized");
enableIOFieldset('fieldset_input_output', 'p_status');
}
</script>
<script async src="data/js/hello_world.js" type="text/javascript"></script>
</body>
</html>
\ No newline at end of file
cmake_minimum_required(VERSION 3.0.2)
set(TARGET_NAME "image_handling")
project (${TARGET_NAME})
set(DEMO_SRC
image_handling.cpp
image_handling_bindings.cpp
)
add_executable (${TARGET_NAME} ${DEMO_SRC})
set(EMSCRIPTEN_LINK_FLAGS "--bind -s ALLOW_MEMORY_GROWTH")
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin/data/js)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/image_creation.html DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/image_modification.html DESTINATION bin)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/image_modification_loaded.html DESTINATION bin)
\ No newline at end of file
## Image handling
Create or modify an image in C++ using parameters given by the user.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Image creation Grid/Chessboard image</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="">
<link rel="stylesheet" href="data/css/demo_theme.css">
</head>
<body>
<h2>Image creation Grid/Chessboard image</h2>
<p id="p_status">Javascript file is loading...</p>
<fieldset class="demo" id="fieldset_input_output" disabled>
<canvas id="canvas_input_image" ></canvas><p>
<input type=number step=1 value="2" min="1" id="enter_blocks_x" oninput=" createImage();"/> Blocks X <p>
<input type=number step=1 value="3" min="1" id="enter_blocks_y" oninput=" createImage();" /> Blocks Y<p>
<input type=number step=1 value="4" min="1" id="enter_block_size" oninput="createImage();" /> Block size (pixel)<p>
<input type=checkbox id="cb_chessboard" name="cb_chessboard" oninput="createImage();"/>
<label for="cb_chessboard">Draw Chessboard </label>
<hr><label class="demo" for="textarea_console_output">C++ output:</label>
<textarea class="demo" id="textarea_console_output" name="textarea_console_output" rows="10"></textarea>
</fieldset>
<script sync src="data/js/tools.js"></script>
<script>
var Module = {};
Module['print'] = printConsole('textarea_console_output', true, false);
Module['printErr'] = printConsole('textarea_console_output', true, true);
Module['onRuntimeInitialized'] = function() {setRuntimeInitialized();}
function setRuntimeInitialized() {
enableIOFieldset('fieldset_input_output', 'p_status');
createImage();
}
function createImage() {
let image_handling = new Module.ImageHandling();
let blocks_x = parseInt(document.getElementById('enter_blocks_x').value);
let blocks_y = parseInt(document.getElementById('enter_blocks_y').value);
let block_size = parseInt(document.getElementById('enter_block_size').value);
let checkBox = document.getElementById("cb_chessboard");
let image_width = (blocks_x * block_size);
let image_height = (blocks_y * block_size);