C++/WASM Scripting
Write high-performance scripts using C++ with optional WebAssembly compilation for computationally intensive tasks.
Overview
C++ scripting provides maximum performance for computationally intensive tasks. Scripts can be compiled to WebAssembly for near-native execution speed within FaustBot's sandboxed environment.
Native Performance
Near-native execution speed for heavy computation.
WebAssembly
Compile to WASM for sandboxed, portable execution.
Low-Level Control
Direct memory management when needed.
C Libraries
Access to C/C++ libraries and headers.
Advanced Users
C++ scripting is recommended for experienced developers. For most use cases, Python or Lua provide sufficient performance with easier development.
Setup
C++ scripts require a compiler. For WASM output, you'll need Emscripten.
Install Compiler
For native C++, install GCC or Clang. For WASM, install Emscripten.
# Install Emscripten
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latestGet FaustBot Headers
Copy the FaustBot headers to your project from the installation directory.
# Headers are in the FaustBot install directory
cp -r /path/to/faustbot/include/faustbot ./Compile Your Script
Compile to WASM and place in FaustBot's scripts directory.
# Compile to WASM
emcc script.cpp -o script.wasm \
-I./faustbot \
-s EXPORTED_FUNCTIONS='["_Execute"]' \
-O3Script Structure
C++ scripts require an Execute() function that returns a boolean.
#include <faustbot/CPH.h>
bool Execute() {
// Your code here
CPH::SendMessage("Hello from C++!");
return true;
}Header Reference
The faustbot/CPH.h header provides access to all API functions.
// faustbot/CPH.h - Available functions
namespace CPH {
// Logging
void LogVerbose(const std::string& message);
void LogDebug(const std::string& message);
void LogInfo(const std::string& message);
void LogWarn(const std::string& message);
void LogError(const std::string& message);
// Arguments
std::string GetArg(const std::string& key);
template<typename T> T GetArg(const std::string& key, T defaultValue);
void SetArgument(const std::string& key, const std::string& value);
// Variables
template<typename T> T GetGlobalVar(const std::string& name, T defaultValue = T());
template<typename T> void SetGlobalVar(const std::string& name, T value, bool persist = false);
template<typename T> T GetUserVar(const std::string& user, const std::string& name, T defaultValue = T());
template<typename T> void SetUserVar(const std::string& user, const std::string& name, T value, bool persist = false);
// Chat
void SendMessage(const std::string& message, bool asBot = false);
void TwitchAnnounce(const std::string& message, const std::string& color = "");
// Actions
bool RunAction(const std::string& name, bool immediate = false);
// OBS
void ObsSetScene(const std::string& scene, const std::string& connection = "");
void ObsShowSource(const std::string& scene, const std::string& source);
void ObsHideSource(const std::string& scene, const std::string& source);
}CPH API Access
Access FaustBot functionality through the CPH namespace.
Variables and Arguments
#include <faustbot/CPH.h>
#include <string>
bool Execute() {
// Get event data
std::string user = CPH::GetArg("user");
std::string message = CPH::GetArg("message");
// Get variables with defaults
int points = CPH::GetUserVar<int>(user, "points", 0);
std::string rank = CPH::GetUserVar<std::string>(user, "rank", "Newcomer");
// Global variables
int totalSubs = CPH::GetGlobalVar<int>("totalSubs", 0);
// Set variables
CPH::SetUserVar(user, "points", points + 100);
CPH::SetGlobalVar("lastUser", user, true);
return true;
}Full API Example
#include <faustbot/CPH.h>
#include <string>
#include <sstream>
bool Execute() {
// Logging
CPH::LogInfo("Script started");
CPH::LogDebug("Debug information");
// Chat messages
CPH::SendMessage("Hello, chat!");
CPH::TwitchAnnounce("Big announcement!", "purple");
// Actions
CPH::RunAction("MyAction", true);
// OBS control
CPH::ObsSetScene("Gaming");
CPH::ObsShowSource("Gaming", "Webcam");
// Set output arguments
CPH::SetArgument("result", "success");
CPH::SetArgument("count", 42);
return true;
}Memory Management
Use modern C++ memory management practices to avoid leaks and crashes.
#include <faustbot/CPH.h>
#include <memory>
#include <vector>
#include <string>
bool Execute() {
// Use smart pointers for automatic cleanup
auto data = std::make_unique<std::vector<std::string>>();
// Process data
data->push_back("item1");
data->push_back("item2");
// Use RAII for resource management
{
std::vector<int> temp_buffer(1000);
// Process buffer
// Automatically freed when scope exits
}
// Avoid raw new/delete
// BAD: int* ptr = new int[100];
// GOOD: std::vector<int> vec(100);
CPH::SendMessage("Processed " + std::to_string(data->size()) + " items");
return true;
}Memory Best Practices
- Use
std::unique_ptrandstd::shared_ptr - Prefer stack allocation when possible
- Use RAII for resource management
- Avoid raw
new/delete - Use containers like
std::vector
Performance Tips
Maximize performance with these C++ optimization techniques.
#include <faustbot/CPH.h>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
// Use constexpr for compile-time constants
constexpr int MAX_USERS = 1000;
constexpr double POINT_MULTIPLIER = 1.5;
bool Execute() {
std::vector<int> scores = {100, 200, 300, 400, 500};
// Use algorithms instead of loops
int total = std::accumulate(scores.begin(), scores.end(), 0);
// Use references to avoid copies
const std::string& user = CPH::GetArg("user");
// Use move semantics
std::string result = BuildResult();
CPH::SetArgument("output", std::move(result));
// Parallel processing for heavy computation
// std::for_each(std::execution::par, ...)
return true;
}
std::string BuildResult() {
return "Processed successfully";
}Do
- Use
constreferences - Use move semantics
- Prefer algorithms over loops
- Use
constexprfor constants - Pre-allocate container capacity
Avoid
- Passing large objects by value
- Unnecessary string copies
- Dynamic allocation in loops
- Virtual functions in hot paths
- Excessive exception usage
WebAssembly
Compile to WebAssembly for sandboxed execution with near-native performance.
// Compile with Emscripten for WASM
// emcc script.cpp -o script.wasm -s EXPORTED_FUNCTIONS='["_Execute"]'
#include <faustbot/CPH.h>
extern "C" {
// Export function for WASM
bool Execute() {
CPH::LogInfo("Running in WebAssembly!");
// Heavy computation runs at near-native speed
double result = HeavyCalculation();
CPH::SetArgument("result", result);
CPH::SendMessage("Calculation complete!");
return true;
}
}
double HeavyCalculation() {
double sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i * 0.001;
}
return sum;
}Compilation Options
| Flag | Purpose |
|---|---|
-O3 | Maximum optimization |
-Os | Optimize for size |
-s WASM=1 | Output WASM (default) |
-s EXPORTED_FUNCTIONS | Functions to export |
-s ALLOW_MEMORY_GROWTH=1 | Allow dynamic memory growth |
-s STACK_SIZE=1048576 | Set stack size (1MB) |
WASM Limitations
- No direct file system access
- Network requests go through CPH API
- Memory is sandboxed
- Some C++ features may have limited support