initial commit
This commit is contained in:
commit
e8c63a120e
|
@ -0,0 +1 @@
|
|||
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "mastodon-export"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
bevy = { version = "0.8", default-features = false, features = ["bevy_winit", "png", "x11"] }
|
||||
bevy_egui = "0.15.1"
|
||||
egui = "0.18"
|
||||
egui_extras = "0.18"
|
||||
bevy-inspector-egui = "0.12.1"
|
||||
tokio = { version = "1.12.0", features = ["full"] }
|
||||
rfd = "0.8"
|
||||
reqwest = "0.11"
|
|
@ -0,0 +1,8 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_inspector_egui::Inspectable;
|
||||
|
||||
|
||||
#[derive(Component, Inspectable)]
|
||||
pub struct FailedRetrieving {
|
||||
pub message: String
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
pub mod retrievable;
|
||||
pub mod retrieving;
|
||||
pub mod retrieved;
|
||||
pub mod failed_retrieving;
|
|
@ -0,0 +1,14 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_inspector_egui::Inspectable;
|
||||
|
||||
|
||||
#[derive(Component, Inspectable)]
|
||||
pub struct Retrievable {
|
||||
pub target: Target
|
||||
|
||||
}
|
||||
|
||||
#[derive(Inspectable, Debug, Clone)]
|
||||
pub enum Target {
|
||||
Url(String)
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_inspector_egui::Inspectable;
|
||||
|
||||
|
||||
#[derive(Component, Inspectable)]
|
||||
pub struct Retrieved {
|
||||
pub asset: Asset
|
||||
}
|
||||
|
||||
#[derive(Inspectable, Debug)]
|
||||
pub enum Asset {
|
||||
Text(String),
|
||||
Bytes(Vec<u8>)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_inspector_egui::Inspectable;
|
||||
use reqwest::Response;
|
||||
|
||||
use super::retrieved::Asset;
|
||||
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Retrieving {
|
||||
pub response_recv: tokio::sync::oneshot::Receiver::<Retriever>
|
||||
}
|
||||
|
||||
pub enum Retriever {
|
||||
HttpRequest(reqwest::Result<Asset>)
|
||||
}
|
||||
|
||||
impl Inspectable for Retrieving {
|
||||
type Attributes = ();
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, options: Self::Attributes, context: &mut bevy_inspector_egui::Context) -> bool {
|
||||
ui.label("downloading...");
|
||||
false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
use bevy::{
|
||||
prelude::*, tasks::TaskPoolBuilder,
|
||||
};
|
||||
use bevy_egui::EguiPlugin;
|
||||
use bevy_inspector_egui::{WorldInspectorPlugin, RegisterInspectable};
|
||||
use components::{retrieved::Retrieved, retrieving::Retrieving, failed_retrieving::FailedRetrieving};
|
||||
use systems::ui::UiState;
|
||||
pub mod systems;
|
||||
pub mod components;
|
||||
use crate::components::retrievable::Retrievable;
|
||||
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugin(EguiPlugin)
|
||||
.add_plugin(WorldInspectorPlugin::new())
|
||||
.insert_resource(tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap()
|
||||
)
|
||||
.insert_resource(UiState{ url_input: "".to_string() })
|
||||
.add_system(systems::ui::main_ui)
|
||||
.add_system(systems::start_retrieving::start_retrieving)
|
||||
.add_system(systems::unpack_retrieved::unpack_retrieved)
|
||||
.add_startup_system(setup)
|
||||
.register_inspectable::<Retrievable>()
|
||||
.register_inspectable::<Retrieving>()
|
||||
.register_inspectable::<Retrieved>()
|
||||
.register_inspectable::<FailedRetrieving>()
|
||||
.run();
|
||||
}
|
||||
|
||||
fn setup(
|
||||
mut commands: Commands,
|
||||
) {
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub mod ui;
|
||||
pub mod start_retrieving;
|
||||
pub mod unpack_retrieved;
|
|
@ -0,0 +1,46 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use reqwest::Response;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use crate::components::{retrievable::Retrievable, retrieving::{Retrieving, Retriever}, retrieved::{Retrieved, Asset}};
|
||||
|
||||
|
||||
pub fn start_retrieving(
|
||||
mut commands: Commands,
|
||||
runtime: Res<Runtime>,
|
||||
mut target_query: Query<(&mut Retrievable, Entity), (Without<Retrieving>, Without<Retrieved>)>,
|
||||
){
|
||||
for (retrievable, entity) in target_query.iter_mut(){
|
||||
let target = retrievable.target.clone();
|
||||
let (response_send, response_recv) = tokio::sync::oneshot::channel::<Retriever>();
|
||||
runtime.spawn(async move {
|
||||
match target {
|
||||
crate::components::retrievable::Target::Url(url) => {
|
||||
let response = reqwest::get(url).await;
|
||||
match response {
|
||||
Ok(r) => {
|
||||
match r.bytes().await {
|
||||
Ok(b) => {
|
||||
response_send.send(Retriever::HttpRequest(Ok(Asset::Bytes(b.to_vec()))));
|
||||
},
|
||||
Err(e) => {
|
||||
response_send.send(Retriever::HttpRequest(Err(e)));
|
||||
},
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
response_send.send(Retriever::HttpRequest(Err(e)));
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
commands.entity(entity).insert(Retrieving {
|
||||
response_recv
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_egui::EguiContext;
|
||||
|
||||
use crate::components::retrievable::{Retrievable, Target};
|
||||
|
||||
pub fn main_ui(
|
||||
mut commands: Commands,
|
||||
mut egui_context: ResMut<EguiContext>,
|
||||
mut ui_state: ResMut<UiState>,
|
||||
) {
|
||||
egui::TopBottomPanel::bottom("bottom").show(egui_context.ctx_mut(), |ui| {
|
||||
let layout = egui::Layout::top_down(egui::Align::Center).with_main_justify(true);
|
||||
ui.allocate_ui_with_layout(ui.available_size(), layout, |ui|{
|
||||
|
||||
ui.horizontal(|ui|{
|
||||
ui.text_edit_singleline(&mut ui_state.url_input);
|
||||
if ui.button("fetch").clicked() {
|
||||
commands.spawn().insert(Retrievable {
|
||||
target: Target::Url(ui_state.url_input.clone())
|
||||
});
|
||||
ui_state.url_input = "".to_string();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
pub struct UiState {
|
||||
pub url_input: String
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
use std::{borrow::Cow, fmt::format};
|
||||
|
||||
use bevy::prelude::*;
|
||||
use reqwest::Response;
|
||||
use tokio::{runtime::Runtime, sync::oneshot::error::TryRecvError};
|
||||
|
||||
use crate::components::{retrievable::Retrievable, retrieving::{Retrieving, Retriever}, retrieved::{Retrieved, Asset}, failed_retrieving::FailedRetrieving};
|
||||
|
||||
|
||||
pub fn unpack_retrieved(
|
||||
mut commands: Commands,
|
||||
mut target_query: Query<(&mut Retrieving, Entity), (Without<Retrieved>, Without<FailedRetrieving>)>,
|
||||
){
|
||||
for (mut retrieving, entity) in target_query.iter_mut(){
|
||||
match retrieving.response_recv.try_recv(){
|
||||
Ok(Retriever::HttpRequest(response)) => match response {
|
||||
Ok(asset) => {
|
||||
commands.entity(entity).insert(Retrieved {
|
||||
asset,
|
||||
});
|
||||
commands.entity(entity).remove::<Retrieving>();
|
||||
},
|
||||
Err(e) => {
|
||||
commands.entity(entity).insert(FailedRetrieving {
|
||||
message: format!("retrieval failed: {:?}", e)
|
||||
});
|
||||
commands.entity(entity).remove::<Retrieving>();
|
||||
}
|
||||
},
|
||||
Err(TryRecvError::Empty) => (),
|
||||
Err(TryRecvError::Closed) => panic!("wat"),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue