Add caretta-sync-bevy and remove async from Runnable::run() for bevy
This commit is contained in:
parent
347ef56d56
commit
ff5256eadd
35 changed files with 182 additions and 73 deletions
18
Cargo.toml
18
Cargo.toml
|
@ -8,13 +8,15 @@ repository.workspace = true
|
|||
|
||||
[features]
|
||||
default = ["macros"]
|
||||
bevy = ["dep:caretta-sync-bevy"]
|
||||
mobile = ["dep:caretta-sync-mobile"]
|
||||
cli = ["dep:caretta-sync-cli"]
|
||||
desktop = ["cli"]
|
||||
desktop = ["cli", "bevy"]
|
||||
macros = ["dep:caretta-sync-macros"]
|
||||
test = ["caretta-sync-core/test"]
|
||||
|
||||
[dependencies]
|
||||
caretta-sync-bevy = { path = "bevy", optional = true }
|
||||
caretta-sync-core.workspace = true
|
||||
caretta-sync-cli = { path="cli", optional = true }
|
||||
caretta-sync-mobile = { path = "mobile", optional = true }
|
||||
|
@ -24,7 +26,7 @@ caretta-sync-macros = { path="macros", optional = true}
|
|||
caretta-sync-core = {workspace = true, features = ["test"]}
|
||||
|
||||
[workspace]
|
||||
members = [ ".", "core", "macros", "cli", "mobile", "examples/demo/*" ]
|
||||
members = [ ".", "core", "macros", "cli", "mobile", "examples/demo/*" , "bevy"]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
|
@ -35,11 +37,12 @@ license = "MIT OR Apache-2.0"
|
|||
repository = "https://forgejo.fireturlte.net/lazy-supplements"
|
||||
|
||||
[workspace.dependencies]
|
||||
bevy = "0.16.1"
|
||||
chrono = "0.4.41"
|
||||
ciborium = "0.2.2"
|
||||
clap = { version = "4.5.38", features = ["derive"] }
|
||||
dioxus = { version = "0.6.0", features = [] }
|
||||
caretta-sync-core.path = "core"
|
||||
futures = { version = "0.3.31", features = ["executor"] }
|
||||
libp2p = { version = "0.55.0", features = ["macros", "mdns", "noise", "ping", "tcp", "tokio", "yamux" ] }
|
||||
sea-orm = { version = "1.1.11", features = ["sqlx-sqlite", "runtime-tokio-native-tls", "macros", "with-chrono", "with-uuid"] }
|
||||
sea-orm-migration = { version = "1.1.0", features = ["runtime-tokio-rustls", "sqlx-postgres"] }
|
||||
|
@ -49,3 +52,12 @@ tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] }
|
|||
tonic = "0.14.0"
|
||||
uuid = { version = "1.17.0", features = ["v7"] }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = "thin"
|
||||
|
|
15
bevy/Cargo.toml
Normal file
15
bevy/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "caretta-sync-bevy"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
description.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bevy.workspace = true
|
||||
caretta-sync-core.workspace = true
|
||||
futures.workspace = true
|
||||
sea-orm.workspace = true
|
||||
tokio.workspace = true
|
||||
tonic.workspace = true
|
4
bevy/src/global.rs
Normal file
4
bevy/src/global.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
use bevy::{asset::uuid::Uuid, ecs::component::Component};
|
||||
|
||||
#[derive(Component)]
|
||||
struct Id(Uuid);
|
2
bevy/src/lib.rs
Normal file
2
bevy/src/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod global;
|
||||
pub mod peer;
|
47
bevy/src/peer.rs
Normal file
47
bevy/src/peer.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use bevy::{app::{App, Plugin, Startup, Update}, ecs::{component::Component, query::With, system::{Commands, Query}}, tasks::TaskPool};
|
||||
use caretta_sync_core::{cache::entity::{CachedPeerEntity, CachedPeerModel}, global::{CONFIG, DATABASE_CONNECTIONS}};
|
||||
use caretta_sync_core::{
|
||||
proto::*,
|
||||
};
|
||||
use sea_orm::EntityTrait;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Peer;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct PeerId(String);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct PeerAddress(String);
|
||||
|
||||
#[tokio::main]
|
||||
async fn add_cached_peers(mut commands: Commands) {
|
||||
let config = CONFIG.get_unchecked();
|
||||
let path = String::from("unix://") + config.rpc.socket_path.as_os_str().to_str().expect("Invalid string");
|
||||
let mut client = caretta_sync_core::proto::cached_peer_service_client::CachedPeerServiceClient::connect(path).await.expect("Unix socket should be accessible");
|
||||
let request = tonic::Request::new(CachedPeerListRequest {});
|
||||
let response = client.list(request).await.expect("Faild to request/response");
|
||||
let peers = response.into_inner().peers;
|
||||
for model in peers.into_iter() {
|
||||
commands.spawn((Peer, PeerId(model.peer_id.to_string())));
|
||||
}
|
||||
}
|
||||
|
||||
fn print_peer(query: Query<&PeerId, With<Peer>>) {
|
||||
for peer_id in &query {
|
||||
println!("Hello {}!", peer_id.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn hello_world() {
|
||||
println!("hello world!");
|
||||
}
|
||||
|
||||
pub struct PeerPlugin;
|
||||
|
||||
impl Plugin for PeerPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, add_cached_peers);
|
||||
app.add_systems(Update, (hello_world, print_peer));
|
||||
}
|
||||
}
|
|
@ -26,4 +26,3 @@ uuid.workspace = true
|
|||
|
||||
[dev-dependencies]
|
||||
caretta-sync-core = {workspace = true, features = ["test"]}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ pub struct ConfigCheckCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for ConfigCheckCommandArgs {
|
||||
#[tokio::main]
|
||||
async fn run(self, app_name: &'static str) {
|
||||
let _ = self.config.into_config(app_name).await;
|
||||
println!("Ok");
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct ConfigListCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for ConfigListCommandArgs {
|
||||
#[tokio::main]
|
||||
async fn run(self, app_name: &'static str) {
|
||||
let config: PartialConfig = if self.all {
|
||||
self.config.into_config(app_name).await.into()
|
||||
|
|
|
@ -15,8 +15,8 @@ pub struct ConfigCommandArgs {
|
|||
}
|
||||
|
||||
impl Runnable for ConfigCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
self.command.run(app_name).await
|
||||
fn run(self, app_name: &'static str) {
|
||||
self.command.run(app_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,10 @@ pub enum ConfigSubcommand {
|
|||
}
|
||||
|
||||
impl Runnable for ConfigSubcommand {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
match self {
|
||||
Self::Check(x) => x.run(app_name).await,
|
||||
Self::List(x) => x.run(app_name).await,
|
||||
Self::Check(x) => x.run(app_name),
|
||||
Self::List(x) => x.run(app_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ pub struct DeviceAddCommandArgs {
|
|||
}
|
||||
|
||||
impl Runnable for DeviceAddCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ pub struct DeviceListCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for DeviceListCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -22,8 +22,8 @@ pub struct DeviceCommandArgs {
|
|||
}
|
||||
|
||||
impl Runnable for DeviceCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
self.command.run(app_name).await
|
||||
fn run(self, app_name: &'static str) {
|
||||
self.command.run(app_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,13 +37,13 @@ pub enum DeviceSubcommand {
|
|||
}
|
||||
|
||||
impl Runnable for DeviceSubcommand {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
match self {
|
||||
Self::Add(x) => x.run(app_name).await,
|
||||
Self::List(x) => x.run(app_name).await,
|
||||
Self::Ping(x) => x.run(app_name).await,
|
||||
Self::Remove(x) => x.run(app_name).await,
|
||||
Self::Scan(x) => x.run(app_name).await,
|
||||
Self::Add(x) => x.run(app_name),
|
||||
Self::List(x) => x.run(app_name),
|
||||
Self::Ping(x) => x.run(app_name),
|
||||
Self::Remove(x) => x.run(app_name),
|
||||
Self::Scan(x) => x.run(app_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ pub struct DevicePingCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for DevicePingCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ pub struct DeviceRemoveCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for DeviceRemoveCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ pub struct DeviceScanCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for DeviceScanCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
use caretta_sync_core::utils::runnable::Runnable;
|
||||
use clap::Args;
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
pub struct LogsCommandArgs {
|
||||
#[arg(short='n', long)]
|
||||
lines: Option<u32>,
|
||||
}
|
||||
|
||||
impl Runnable for LogsCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -3,13 +3,11 @@ use std::path::PathBuf;
|
|||
mod args;
|
||||
mod config;
|
||||
mod device;
|
||||
mod logs;
|
||||
mod peer;
|
||||
mod serve;
|
||||
|
||||
pub use args::*;
|
||||
pub use config::*;
|
||||
pub use device::*;
|
||||
pub use logs::*;
|
||||
pub use peer::*;
|
||||
pub use serve::*;
|
|
@ -11,7 +11,7 @@ pub struct PeerInfoCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for PeerInfoCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ pub struct PeerListCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for PeerListCommandArgs {
|
||||
#[tokio::main]
|
||||
async fn run(self, app_name: &'static str) {
|
||||
let config = self.config.into_config(app_name).await;
|
||||
let path = String::from("unix://") + config.rpc.socket_path.as_os_str().to_str().expect("Invalid string");
|
||||
|
|
|
@ -17,8 +17,8 @@ pub struct PeerCommandArgs {
|
|||
}
|
||||
|
||||
impl Runnable for PeerCommandArgs {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
self.command.run(app_name).await
|
||||
fn run(self, app_name: &'static str) {
|
||||
self.command.run(app_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,11 @@ pub enum PeerSubcommand {
|
|||
}
|
||||
|
||||
impl Runnable for PeerSubcommand {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
match self {
|
||||
Self::Info(x) => x.run(app_name).await,
|
||||
Self::List(x) => x.run(app_name).await,
|
||||
Self::Ping(x) => x.run(app_name).await,
|
||||
Self::Info(x) => x.run(app_name),
|
||||
Self::List(x) => x.run(app_name),
|
||||
Self::Ping(x) => x.run(app_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct PeerPingCommandArgs{
|
|||
}
|
||||
|
||||
impl Runnable for PeerPingCommandArgs {
|
||||
#[tokio::main]
|
||||
async fn run(self, app_name: &'static str) {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ impl<T> Runnable for ServeCommandArgs<T>
|
|||
where
|
||||
T: ServerTrait
|
||||
{
|
||||
#[tokio::main]
|
||||
async fn run(self, app_name: &'static str) {
|
||||
let config = CONFIG.get_or_init::<Config>(self.config.into_config(app_name).await).await;
|
||||
let _ = DATABASE_CONNECTIONS.get_or_init_unchecked(&config, DataMigrator).await;
|
||||
|
|
|
@ -18,7 +18,7 @@ chrono-tz = "0.10.3"
|
|||
ciborium.workspace = true
|
||||
clap = {workspace = true, optional = true}
|
||||
dirs = "6.0.0"
|
||||
futures = "0.3.31"
|
||||
futures.workspace = true
|
||||
libp2p.workspace = true
|
||||
libp2p-core = { version = "0.43.0", features = ["serde"] }
|
||||
libp2p-identity = { version = "0.2.11", features = ["ed25519", "peerid", "rand", "serde"] }
|
||||
|
|
|
@ -32,4 +32,7 @@ impl GlobalConfig {
|
|||
pub fn get(&'static self) -> Option<&'static Config> {
|
||||
self.inner.get()
|
||||
}
|
||||
pub fn get_unchecked(&'static self) -> &'static Config {
|
||||
self.get().expect("Config must be initialized before use!")
|
||||
}
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
#[cfg(feature="macros")]
|
||||
pub use caretta_sync_macros::Runnable;
|
||||
|
||||
pub trait Runnable {
|
||||
async fn run(self, app_name: &'static str);
|
||||
fn run(self, app_name: &'static str);
|
||||
}
|
|
@ -7,7 +7,8 @@ license.workspace = true
|
|||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
caretta-sync.path = "../../.."
|
||||
bevy.workspace = true
|
||||
caretta-sync = { path = "../../..", features = ["bevy"] }
|
||||
libp2p.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio-stream = { version = "0.1.17", features = ["net"] }
|
||||
|
|
13
examples/demo/core/src/gui.rs
Normal file
13
examples/demo/core/src/gui.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use caretta_sync::{bevy::peer::PeerPlugin, utils::Runnable};
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub struct Gui {}
|
||||
|
||||
impl Runnable for Gui {
|
||||
fn run(self, app_name: &'static str) {
|
||||
App::new()
|
||||
//.add_plugins(DefaultPlugins)
|
||||
.add_plugins(PeerPlugin)
|
||||
.run();
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod global;
|
||||
pub mod gui;
|
||||
pub mod rpc;
|
||||
pub mod server;
|
||||
|
|
|
@ -10,8 +10,7 @@ repository.workspace = true
|
|||
|
||||
[dependencies]
|
||||
clap.workspace = true
|
||||
caretta-sync = { path = "../../..", features = ["desktop", "test"] }
|
||||
caretta-sync = { path = "../../..", features = ["cli", "bevy", "test"] }
|
||||
caretta-sync-demo-core.path = "../core"
|
||||
libp2p.workspace = true
|
||||
tokio.workspace = true
|
||||
|
||||
|
|
|
@ -1,20 +1,39 @@
|
|||
use caretta_sync_demo_core::server::Server;
|
||||
use caretta_sync_demo_core::{gui::Gui, server::Server};
|
||||
use clap::{Parser, Subcommand};
|
||||
use caretta_sync::{cli::*, utils::runnable::Runnable};
|
||||
use caretta_sync::{cli::*, config::Config, data::migration::DataMigrator, global::{CONFIG, DATABASE_CONNECTIONS}, utils::Runnable};
|
||||
|
||||
|
||||
#[derive(Debug, Parser, Runnable)]
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
#[runnable]
|
||||
command: CliCommand
|
||||
command: Option<CliCommand>,
|
||||
#[command(flatten)]
|
||||
config: ConfigArgs,
|
||||
}
|
||||
|
||||
impl Runnable for Cli {
|
||||
fn run(self, app_name: &'static str) {
|
||||
if let Some(x) = self.command {
|
||||
x.run(app_name)
|
||||
} else {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap()
|
||||
.block_on(async {
|
||||
let config: caretta_sync::config::Config = self.config.into_config(app_name).await;
|
||||
let _ = CONFIG.get_or_init::<Config>(config).await;
|
||||
});
|
||||
//let _ = DATABASE_CONNECTIONS.get_or_init_unchecked(&config, DataMigrator).await;
|
||||
Gui{}.run(app_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand, Runnable)]
|
||||
pub enum CliCommand {
|
||||
Config(ConfigCommandArgs),
|
||||
Device(DeviceCommandArgs),
|
||||
Logs(LogsCommandArgs),
|
||||
Peer(PeerCommandArgs),
|
||||
Serve(ServeCommandArgs<Server>),
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use caretta_sync::utils::runnable::Runnable;
|
||||
use caretta_sync::utils::Runnable;
|
||||
use caretta_sync_demo_core::global::APP_NAME;
|
||||
use clap::Parser;
|
||||
|
||||
|
@ -7,8 +7,7 @@ use crate::cli::Cli;
|
|||
mod cli;
|
||||
mod ipc;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
fn main() {
|
||||
let args = Cli::parse();
|
||||
args.run(APP_NAME).await;
|
||||
args.run(APP_NAME);
|
||||
}
|
||||
|
|
|
@ -206,8 +206,8 @@ pub fn runnable(input: TokenStream) -> TokenStream {
|
|||
|
||||
quote!{
|
||||
impl Runnable for #type_ident {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
<#field_type as Runnable>::run(self.#field_ident, app_name).await
|
||||
fn run(self, app_name: &'static str) {
|
||||
<#field_type as Runnable>::run(self.#field_ident, app_name)
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
|
@ -216,12 +216,12 @@ pub fn runnable(input: TokenStream) -> TokenStream {
|
|||
let quote_vec = extract_idents_and_types_from_enum_struct(&variants);
|
||||
let quote_iter = quote_vec.iter().map(|(variant_ident, variant_type)|{
|
||||
quote!{
|
||||
Self::#variant_ident(x) => <#variant_type as Runnable>::run(x, app_name).await,
|
||||
Self::#variant_ident(x) => <#variant_type as Runnable>::run(x, app_name),
|
||||
}
|
||||
});
|
||||
quote!{
|
||||
impl Runnable for #type_ident {
|
||||
async fn run(self, app_name: &'static str) {
|
||||
fn run(self, app_name: &'static str) {
|
||||
match self {
|
||||
#(#quote_iter)*
|
||||
}
|
||||
|
|
17
src/lib.rs
17
src/lib.rs
|
@ -1,4 +1,7 @@
|
|||
pub use caretta_sync_core::*;
|
||||
|
||||
#[cfg(feature = "bevy")]
|
||||
pub use caretta_sync_bevy as bevy;
|
||||
#[cfg(feature = "cli")]
|
||||
pub use caretta_sync_cli::*;
|
||||
#[cfg(feature = "mobile")]
|
||||
|
@ -6,8 +9,14 @@ pub use caretta_sync_mobile::*;
|
|||
|
||||
#[cfg(feature = "macros")]
|
||||
pub mod utils {
|
||||
pub mod runnable {
|
||||
pub use caretta_sync_core::utils::runnable::Runnable;
|
||||
pub use caretta_sync_macros::Runnable;
|
||||
}
|
||||
pub use caretta_sync_core::utils::{
|
||||
runnable::Runnable,
|
||||
emptiable::Emptiable,
|
||||
mergeable::Mergeable,
|
||||
};
|
||||
pub use caretta_sync_macros::{
|
||||
Runnable,
|
||||
Emptiable,
|
||||
Mergeable,
|
||||
};
|
||||
}
|
Loading…
Add table
Reference in a new issue