-
Notifications
You must be signed in to change notification settings - Fork 680
Add C++ Bindings #3544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add C++ Bindings #3544
Conversation
8a32cdb to
7b372b7
Compare
…_exports to carry defaults
… as exceptions are not available for C++ yet
…r to how Views worked with errors + added a version of IterBuf for C++ to start to reduce allocations
7b372b7 to
fa45b54
Compare
|
/update-llm-benchmark |
LLM Benchmark Results (ci-quickfix)
Compared against master branch baseline Generated at: 2026-01-21T23:43:33.764Z Failure Analysis (click to expand)Benchmark Failure AnalysisGenerated from: Summary
Analysis of SpacetimeDB Benchmark FailuresThis document provides an analysis of the failures in SpacetimeDB benchmark tests, organized by language and failure type. Each entry includes the generated code, the expected golden example, the error message, an explanation of the differences, the root cause of the issue, and specific recommendations for documentation changes. Rust / rustdoc_json Failures1. Compile/Publish Errorst_002_scheduled_tableGenerated Code: use spacetimedb::{reducer, table, ReducerContext, ScheduleAt, Table};
#[table(name = tick_timer, scheduled(reducer = tick, column = scheduled_at))]
pub struct TickTimer {
#[primary_key]
#[auto_inc]
scheduled_id: u64,
scheduled_at: ScheduleAt,
}
#[reducer(init)]
pub fn init(ctx: &ReducerContext) {
let tbl = ctx.db.tick_timer();
match tbl.count() {
0 => {
tbl.insert(TickTimer {
scheduled_id: 0,
scheduled_at: ScheduleAt::repeat_micros(50_000),
});
}
n if n > 1 => {
let mut keep_one = true;
for row in tbl.iter() {
if keep_one {
keep_one = false;
} else {
tbl.scheduled_id().delete(&row.scheduled_id);
}
}
}
_ => {}
}
}Expected (golden): use spacetimedb::{reducer, table, ReducerContext, ScheduleAt, Table};
use std::time::Duration;
#[table(name = tick_timer, scheduled(tick))]
pub struct TickTimer {
#[primary_key]
#[auto_inc]
pub scheduled_id: u64,
pub scheduled_at: ScheduleAt,
}
#[reducer]
pub fn tick(_ctx: &ReducerContext, _row: TickTimer) -> Result<(), String> {
Ok(())
}
#[reducer(init)]
pub fn init(ctx: &ReducerContext) -> Result<(), String> {
ctx.db.tick_timer().insert(TickTimer {
scheduled_id: 0,
scheduled_at: ScheduleAt::Interval(Duration::from_millis(50).into()),
});
Ok(())
}Error: Explanation of Difference:
Root Cause:
Recommendation:
t_008_index_lookupGenerated Code: use spacetimedb::{ReducerContext, Table};
#[spacetimedb::table(name = user)]
pub struct User {
#[primary_key]
id: i32,
name: String,
age: i32,
active: bool,
}
#[spacetimedb::table(name = result)]
pub struct ResultRow {
#[primary_key]
id: i32,
name: String,
}
#[spacetimedb::reducer]
pub fn lookup_user_name(ctx: &ReducerContext, id: i32) {
if let Some(u) = ctx.db.user().id().find(id) {
let row = ResultRow { id: u.id, name: u.name.clone() };
if ctx.db.result().try_insert(row.clone()).is_err() {
ctx.db.result().id().update(row);
}
}
}Expected (golden): use spacetimedb::{reducer, table, ReducerContext, Table};
#[table(name = user)]
pub struct User {
#[primary_key]
pub id: i32,
pub name: String,
pub age: i32,
pub active: bool,
}
#[table(name = result)]
pub struct ResultRow {
#[primary_key]
pub id: i32,
pub name: String,
}
#[reducer]
pub fn lookup_user_name(ctx: &ReducerContext, id: i32) {
if let Some(u) = ctx.db.user().id().find(id) {
ctx.db.result().insert(ResultRow { id: u.id, name: u.name });
}
}Error: Explanation of Difference:
Root Cause:
Recommendation:
Additional Recommendations for All Failures
This structured approach will assist developers in quickly diagnosing and resolving their issues when working with SpacetimeDB. |
# Conflicts: # docs/llms/docs-benchmark-analysis.md # docs/llms/docs-benchmark-comment.md # docs/llms/docs-benchmark-details.json # docs/llms/docs-benchmark-summary.json
…ement for devs to add procedures header manually to match the rest of the architecture (single header)
…ype to hold the error string as std::variant doesn't allow duplicate types
…an just Rust; as well as fixed bugs with the framework from running tests
# Conflicts: # sdks/rust/tests/test.rs
| #URL "https://www.spacetimedb.com/cpp/spacetimedb-cpp-sdk-1.11.2.zip" | ||
| URL "https://www.rodentgames.com/spacetimedb/spacetimedb-cpp-sdk-1.11.2.zip" | ||
| DOWNLOAD_EXTRACT_TIMESTAMP TRUE | ||
| #URL_HASH SHA256=E10503F57AA3ADB10ADD82ECF2E0F3C1107B5C141FA5E157D174C30B71071434 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Must be addressed before merging.
# Conflicts: # templates/templates-list.json
crates/bindings-cpp/tests/type-isolation-test/test_modules/test.o
Outdated
Show resolved
Hide resolved
crates/bindings-cpp/include/spacetimedb/bsatn/algebraic_type.h.backup
Outdated
Show resolved
Hide resolved
Thanks! Co-authored-by: Ryan <r.ekhoff@clockworklabs.io> Signed-off-by: Jason Larabie <jason@clockworklabs.io>
jdetter
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments/questions to get started here. There is a lot to review here so I'll do another pass later today.
The main thing I would bring up is that we are referring to this as the "C++ SDK" which I think we should rebrand to the "C++ bindings". My reason is that the other bindings libraries all refer to themselves as bindings, not an SDK. We typically use the nomenclature "SDK" to mean the client SDKs, not the module side bindings.
I fear that if we start referring to this as our C++ SDK this will both confuse users and confuse the LLM training especially if we add a C++ client SDK in the future. If you want feedback from the team on this it might be a good topic to bring up during standup.
Let me know when you're ready for another pass, I'm really excited that this seems like it's working so far and I'm excited for the future with C++26! 🙂
| @@ -0,0 +1,731 @@ | |||
| SPACETIMEDB BUSINESS SOURCE LICENSE AGREEMENT | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a symlink to the base license, as an example:
boppy@geralt:~/clockwork/SpacetimeDB$ ls -al crates/client-api/LICENSE
lrwxrwxrwx 1 boppy boppy 22 Jan 14 17:12 crates/client-api/LICENSE -> ../../licenses/BSL.txt
| git clone https://github.com/emscripten-core/emsdk.git /opt/emsdk | ||
| cd /opt/emsdk | ||
| ./emsdk install latest | ||
| ./emsdk activate latest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by cloning the repo we're just going to be testing against the latest master all the time - is that fine or should we pin to a known working version? I fear this test could start failing based on whatever is on emsdk master.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds 29 seconds to the CI time - might be worth caching this step eventually. It depends on how fast Tyler gets the new smoktests running. Probably leave a TODO on this.
| ```cpp | ||
| #include <spacetimedb.h> | ||
| using namespace SpacetimeDb; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's probably too late to change this, but how much work would it be to make this SpacetimeDB instead of SpacetimeDb?
|
|
||
| **Build errors**: Ensure you have the latest Emscripten SDK and are using `emcmake cmake` | ||
|
|
||
| **Module not found**: Check that SpacetimeDB is running with `spacetime server status` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spacetime server status is not a command
| ## License | ||
| Apache License 2.0 - See LICENSE file in the root directory. No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What license is this referring to? Certainly the license for this crate is BSL right? Why does this say Apache2?
| @@ -0,0 +1,1290 @@ | |||
| # SpacetimeDB C++ Module Reference | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this become our API reference doc?
| @@ -0,0 +1,293 @@ | |||
| # SpacetimeDB C++ Module Quickstart | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This becomes our quickstart chat example in the docs, right?
|
|
||
| SpacetimeDB C++ uses a unique accessor pattern: | ||
| - `ctx.db[table_name]` - Access table for iteration and basic operations | ||
| - `ctx.db[table_field]` - Access indexed fields for optimized operations (generated symbol named `tableName_fieldName`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a bit weird, shouldn't it be something like this instead:
ctx.db[table_name].table_field
What if 2 tables have the same indexed field name?
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com> Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com> Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Description of Changes
This adds C++ server bindings (/crate/bindings-cpp) to allow writing C++ 20 modules.
API and ABI breaking changes
None
Expected complexity level and risk
2 - Doesn't heavily impact any other areas but is complex macro C++ structure to support a similar developer experience, did have a small impact on init command
Testing