Skip to content

Commit

Permalink
add scoreboards api (closes #45)
Browse files Browse the repository at this point in the history
  • Loading branch information
boozook committed Sep 30, 2023
1 parent d08454c commit 95f4200
Show file tree
Hide file tree
Showing 10 changed files with 861 additions and 4 deletions.
18 changes: 17 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ display = { version = "0.3", path = "api/display", package = "playdate-display",
fs = { version = "0.2", path = "api/fs", package = "playdate-fs", default-features = false }
gfx = { version = "0.3", path = "api/gfx", package = "playdate-graphics", default-features = false }
menu = { version = "0.2", path = "api/menu", package = "playdate-menu", default-features = false }
scoreboards = { version = "0.1", path = "api/scoreboards", package = "playdate-scoreboards", default-features = false }
sound = { version = "0.2", path = "api/sound", package = "playdate-sound", default-features = false }
sprite = { version = "0.2", path = "api/sprite", package = "playdate-sprite", default-features = false }
system = { version = "0.3", path = "api/system", package = "playdate-system", default-features = false }
Expand Down
9 changes: 7 additions & 2 deletions api/playdate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "playdate"
version = "0.1.10"
version = "0.1.11"
readme = "README.md"
description = "High-level Playdate API"
keywords = ["playdate", "sdk", "api", "gamedev"]
Expand All @@ -18,6 +18,7 @@ display = { workspace = true, default-features = false }
fs = { workspace = true, default-features = false }
gfx = { workspace = true, default-features = false }
menu = { workspace = true, default-features = false }
scoreboards = { workspace = true, default-features = false }
sound = { workspace = true, default-features = false }
sprite = { workspace = true, default-features = false }
system = { workspace = true, default-features = false }
Expand All @@ -33,14 +34,15 @@ default = [
"fs/default",
"gfx/default",
"menu/default",
"scoreboards/default",
"sound/default",
"sprite/default",
"system/default",
"entry-point",
]

# SDK v2.1 compatibility
sdk_2_1= ["gfx/sdk_2_1", "sprite/sdk_2_1"]
sdk_2_1 = ["gfx/sdk_2_1", "sprite/sdk_2_1"]

lang-items = ["sys/lang-items"]
allocator = ["sys/allocator"]
Expand All @@ -58,6 +60,7 @@ bindgen-runtime = [
"fs/bindgen-runtime",
"gfx/bindgen-runtime",
"menu/bindgen-runtime",
"scoreboards/bindgen-runtime",
"sound/bindgen-runtime",
"sprite/bindgen-runtime",
"system/bindgen-runtime",
Expand All @@ -69,6 +72,7 @@ bindgen-static = [
"fs/bindgen-static",
"gfx/bindgen-static",
"menu/bindgen-static",
"scoreboards/bindgen-static",
"sound/bindgen-static",
"sprite/bindgen-static",
"system/bindgen-static",
Expand All @@ -83,6 +87,7 @@ bindings-derive-debug = [
"fs/bindings-derive-debug",
"gfx/bindings-derive-debug",
"menu/bindings-derive-debug",
"scoreboards/bindings-derive-debug",
"sound/bindings-derive-debug",
"sprite/bindings-derive-debug",
"system/bindings-derive-debug",
Expand Down
12 changes: 11 additions & 1 deletion api/playdate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ pub mod ext {

// fn lua() -> lua::Lua;
// fn json() -> json::Json;
// fn scoreboards() -> scoreboards::Scoreboards;

fn scoreboards(&self) -> scoreboards::Scoreboards<scoreboards::api::Cache>;
}


Expand Down Expand Up @@ -92,6 +93,10 @@ pub mod ext {
fn sound(&self) -> sound::Sound<sound::api::Cache> {
sound::Sound::new_with(sound::api::Cache::from(unsafe { self.as_ref() }.sound))
}

fn scoreboards(&self) -> scoreboards::Scoreboards<scoreboards::api::Cache> {
scoreboards::Scoreboards::new_with(scoreboards::api::Cache::from(unsafe { self.as_ref() }.scoreboards))
}
}

impl PlaydateAPIExt for *const sys::ffi::PlaydateAPI {
Expand Down Expand Up @@ -119,5 +124,10 @@ pub mod ext {
fn sound(&self) -> sound::Sound<sound::api::Cache> {
sound::Sound::new_with(sound::api::Cache::from(unsafe { self.as_ref() }.expect("api").sound))
}

fn scoreboards(&self) -> scoreboards::Scoreboards<scoreboards::api::Cache> {
let api = scoreboards::api::Cache::from(unsafe { self.as_ref() }.expect("api").scoreboards);
scoreboards::Scoreboards::new_with(api)
}
}
}
62 changes: 62 additions & 0 deletions api/scoreboards/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
[package]
name = "playdate-scoreboards"
version = "0.1.0"
readme = "README.md"
description = "High-level Scoreboards API built on-top of Playdate API"
keywords = ["playdate", "sdk", "api", "gamedev"]
categories = ["game-development", "api-bindings", "no-std"]
edition.workspace = true
license.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true


[features]
default = ["sys/default"]

# playdate-sys features, should be shared because it's build configuration:

bindgen-runtime = ["sys/bindgen-runtime"]
bindgen-static = ["sys/bindgen-static"]
bindings-derive-debug = ["sys/bindings-derive-debug"]


[dependencies]
sys = { workspace = true, default-features = false }
erased_set = "0.7.0"


[dev-dependencies]
system = { workspace = true, default-features = false, features = [ "try-trait-v2" ] }


[[example]]
name = "boards"
crate-type = ["dylib", "staticlib"]
path = "examples/boards.rs"
required-features = ["sys/lang-items", "sys/entry-point"]

[package.metadata.playdate]
bundle-id = "rs.playdate.scoreboards"


[package.metadata.docs.rs]
all-features = false
features = [
"bindings-derive-default",
"bindings-derive-eq",
"bindings-derive-copy",
"bindings-derive-debug",
"bindings-derive-hash",
"bindings-derive-ord",
"bindings-derive-partialeq",
"bindings-derive-partialord",
]
rustdoc-args = ["--cfg", "docsrs", "--show-type-layout"]
default-target = "thumbv7em-none-eabihf"
cargo-args = [
"-Zunstable-options",
"-Zrustdoc-scrape-examples",
"-Zbuild-std=core,alloc",
]
26 changes: 26 additions & 0 deletions api/scoreboards/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Scoreboards API for PlayDate

High-level scoreboards API built on-top of [playdate-sys][].


## Usage

```rust
use playdate_scoreboards::*;
use playdate_sys::println;

let scoreboards = Scoreboards::Cached();

scoreboards.get_scoreboards(|boards| {
println!("{boards:?}");
});
```


[playdate-sys]: https://crates.io/crates/playdate-sys



- - -

This software is not sponsored or supported by Panic.
83 changes: 83 additions & 0 deletions api/scoreboards/examples/boards.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#![no_std]
extern crate alloc;
use core::ptr::NonNull;

#[macro_use]
extern crate sys;
extern crate playdate_scoreboards as scoreboards;

use sys::EventLoopCtrl;
use sys::ffi::*;
use system::prelude::*;

use scoreboards::ScoresResult;
use scoreboards::Scoreboards;


/// Entry point
#[no_mangle]
fn event_handler(_: NonNull<PlaydateAPI>, event: SystemEvent, _: u32) -> EventLoopCtrl {
// Ignore any other events, just for this minimalistic example
if !matches!(event, SystemEvent::Init) {
return EventLoopCtrl::Continue;
}

const BOARD_ID: &str = "ID101";

let scoreboards = Scoreboards::Cached();

let res = scoreboards.add_score(BOARD_ID, 42, |res| {
println!("Add score callback");
match res {
Ok(_) => println!("scores added"),
Err(err) => println!("{err}"),
}
});
match res {
Ok(_) => println!("add_score res: F"),
Err(err) => println!("add_score res: ERR: {err}"),
}


scoreboards.get_scoreboards(|boards| {
println!("1: Get boards callback");
println!("{boards:?}");
});
scoreboards.get_scoreboards(|boards| {
println!("2: Get boards callback");
println!("{boards:?}");
});


fn get_scores(scores: ScoresResult<scoreboards::Scores>) {
println!("1: Get scores callback");
println!("{scores:?}");
}

scoreboards.get_scores(BOARD_ID, get_scores).ok();
scoreboards.get_scores(BOARD_ID, |res| {
println!("2: Get scores callback");
println!("{res:?}");
})
.ok();


scoreboards.get_personal_best(BOARD_ID, |res| {
println!("Get personal best callback");
match res {
Ok(_) => todo!("scores received"),
Err(err) => println!("{err}"),
}
})
.ok();


// Set no-op update callback
system::System::Default().set_update_callback_boxed(|_| UpdateCtrl::Continue, ());

EventLoopCtrl::Continue
}


// Needed for debug build
ll_symbols!();
43 changes: 43 additions & 0 deletions api/scoreboards/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use core::ffi::c_char;
use alloc::borrow::Cow;
use sys::ffi::CStr;


pub type ApiError = sys::error::Error<self::Error>;


#[derive(Debug, Clone)]
#[must_use = "Error message doesn’t live long enough"]
pub enum Error {
Response(Cow<'static, str>),

/// Unknown error.
/// Usually means invalid input or something not found.
Unknown,
}

impl Error {
pub fn from_ptr(ptr: *const c_char) -> Option<Self> {
if ptr.is_null() {
None
} else {
let s = unsafe { CStr::from_ptr(ptr as _) }.to_string_lossy();
Self::Response(s).into()
}
}
}

impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Error::Response(s) => write!(f, "{s}"),
Error::Unknown => write!(f, "Unknown"),
}
}
}

impl core::error::Error for Error {}

impl Into<ApiError> for Error {
fn into(self) -> ApiError { ApiError::Api(self) }
}
Loading

0 comments on commit 95f4200

Please sign in to comment.