mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
wallet: fix all the warnings
This commit is contained in:
@@ -17,15 +17,11 @@
|
||||
*/
|
||||
|
||||
use async_recursion::async_recursion;
|
||||
use chrono::{NaiveDate, NaiveDateTime};
|
||||
use darkfi::event_graph;
|
||||
use darkfi_serial::Encodable;
|
||||
use futures::{stream::FuturesUnordered, StreamExt};
|
||||
use smol::Task;
|
||||
use std::{
|
||||
sync::{Arc, Mutex as SyncMutex},
|
||||
thread,
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -39,7 +35,7 @@ use crate::{
|
||||
SceneNodeType, Slot,
|
||||
},
|
||||
text::TextShaperPtr,
|
||||
ui::{chatview, Button, ChatView, EditBox, Image, Mesh, RenderLayer, Stoppable, Text, Window},
|
||||
ui::{Button, ChatView, EditBox, Image, Mesh, RenderLayer, Stoppable, Text, Window},
|
||||
ExecutorPtr,
|
||||
};
|
||||
|
||||
@@ -59,13 +55,6 @@ const KING_PATH: &str = "assets/king.png";
|
||||
|
||||
const LIGHTMODE: bool = false;
|
||||
|
||||
fn get_systime() -> u64 {
|
||||
match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
|
||||
Ok(n) => n.as_secs(),
|
||||
Err(_) => panic!("SystemTime before UNIX EPOCH!"),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsyncRuntime {
|
||||
signal: async_channel::Sender<()>,
|
||||
shutdown: async_channel::Receiver<()>,
|
||||
@@ -821,6 +810,7 @@ impl Drop for App {
|
||||
}
|
||||
|
||||
// Just for testing
|
||||
/*
|
||||
fn populate_tree(tree: &sled::Tree) {
|
||||
let chat_txt = include_str!("../chat.txt");
|
||||
for line in chat_txt.lines() {
|
||||
@@ -834,7 +824,6 @@ fn populate_tree(tree: &sled::Tree) {
|
||||
NaiveDate::from_ymd_opt(2024, 8, 6).unwrap().and_hms_opt(hour, min, 0).unwrap();
|
||||
let timest = dt.and_utc().timestamp() as u64;
|
||||
|
||||
let message_id = [0u8; 32];
|
||||
let nick = parts[1].to_string();
|
||||
let text = parts[2].to_string();
|
||||
|
||||
@@ -853,6 +842,7 @@ fn populate_tree(tree: &sled::Tree) {
|
||||
// O(n)
|
||||
debug!(target: "app", "populated db with {} lines", tree.len());
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn create_layer(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
|
||||
debug!(target: "app", "create_layer({name})");
|
||||
@@ -968,7 +958,7 @@ fn create_editbox(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
|
||||
prop.allow_exprs();
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
|
||||
let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("scroll", PropertyType::Float32, PropertySubType::Pixel);
|
||||
@@ -979,10 +969,10 @@ fn create_editbox(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
|
||||
prop.set_range_u32(0, u32::MAX);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("font_size", PropertyType::Float32, PropertySubType::Pixel);
|
||||
let prop = Property::new("font_size", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("text", PropertyType::Str, PropertySubType::Null);
|
||||
let prop = Property::new("text", PropertyType::Str, PropertySubType::Null);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("text_color", PropertyType::Float32, PropertySubType::Color);
|
||||
@@ -1005,10 +995,10 @@ fn create_editbox(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
|
||||
prop.allow_null_values();
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
|
||||
let prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("debug", PropertyType::Bool, PropertySubType::Null);
|
||||
let prop = Property::new("debug", PropertyType::Bool, PropertySubType::Null);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
node.id
|
||||
@@ -1055,10 +1045,10 @@ fn create_chatview(
|
||||
let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
|
||||
let prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("debug", PropertyType::Bool, PropertySubType::Null);
|
||||
let prop = Property::new("debug", PropertyType::Bool, PropertySubType::Null);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop =
|
||||
|
||||
@@ -16,32 +16,19 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use async_lock::Mutex as AsyncMutex;
|
||||
use std::sync::{mpsc, Arc, Mutex as SyncMutex};
|
||||
use std::sync::{Arc, Mutex as SyncMutex};
|
||||
|
||||
use darkfi::{
|
||||
async_daemonize, cli_desc,
|
||||
event_graph::{self, proto::ProtocolEventGraph, EventGraph, EventGraphPtr},
|
||||
net::{session::SESSION_DEFAULT, settings::Settings as NetSettings, P2p, P2pPtr},
|
||||
rpc::{
|
||||
jsonrpc::JsonSubscriber,
|
||||
server::{listen_and_serve, RequestHandler},
|
||||
},
|
||||
system::{sleep, sleep_forever, CondVar, StoppableTask, StoppableTaskPtr, Subscription},
|
||||
util::path::{expand_path, get_config_path},
|
||||
Error, Result,
|
||||
system::{sleep, Subscription},
|
||||
Error,
|
||||
};
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize_async, serialize_async, AsyncDecodable, Encodable, SerialDecodable,
|
||||
SerialEncodable,
|
||||
async_trait, deserialize_async, serialize_async, Encodable, SerialDecodable, SerialEncodable,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
net::ZeroMQAdapter,
|
||||
scene::{SceneGraph, SceneGraphPtr2},
|
||||
text::TextShaper,
|
||||
ExecutorPtr,
|
||||
};
|
||||
use crate::{scene::SceneGraphPtr2, ExecutorPtr};
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
const EVGRDB_PATH: &str = "/data/data/darkfi.darkwallet/evgrdb/";
|
||||
@@ -60,7 +47,7 @@ async fn relay_darkirc_events(sg: SceneGraphPtr2, ev_sub: Subscription<event_gra
|
||||
let ev = ev_sub.receive().await;
|
||||
|
||||
// Try to deserialize the `Event`'s content into a `Privmsg`
|
||||
let mut privmsg: Privmsg = match deserialize_async(ev.content()).await {
|
||||
let privmsg: Privmsg = match deserialize_async(ev.content()).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("[IRC CLIENT] Failed deserializing incoming Privmsg event: {}", e);
|
||||
@@ -80,10 +67,10 @@ async fn relay_darkirc_events(sg: SceneGraphPtr2, ev_sub: Subscription<event_gra
|
||||
let response_fn = Box::new(|_| {});
|
||||
|
||||
let mut arg_data = vec![];
|
||||
ev.timestamp.encode(&mut arg_data);
|
||||
ev.id().as_bytes().encode(&mut arg_data);
|
||||
privmsg.nick.encode(&mut arg_data);
|
||||
privmsg.msg.encode(&mut arg_data);
|
||||
ev.timestamp.encode(&mut arg_data).unwrap();
|
||||
ev.id().as_bytes().encode(&mut arg_data).unwrap();
|
||||
privmsg.nick.encode(&mut arg_data).unwrap();
|
||||
privmsg.msg.encode(&mut arg_data).unwrap();
|
||||
|
||||
let mut sg = sg.lock().await;
|
||||
let chatview_node = sg.lookup_node_mut("/window/view/chatty").unwrap();
|
||||
@@ -97,6 +84,7 @@ pub type DarkIrcBackendPtr = Arc<DarkIrcBackend>;
|
||||
struct DarkIrcData {
|
||||
p2p: P2pPtr,
|
||||
event_graph: EventGraphPtr,
|
||||
#[allow(dead_code)]
|
||||
ev_task: smol::Task<()>,
|
||||
db: sled::Db,
|
||||
}
|
||||
|
||||
@@ -42,9 +42,6 @@ pub enum Error {
|
||||
#[error("Property has wrong type")]
|
||||
PropertyWrongType = 7,
|
||||
|
||||
#[error("Property has wrong subtype")]
|
||||
PropertyWrongSubType = 8,
|
||||
|
||||
#[error("Property value has the wrong length")]
|
||||
PropertyWrongLen = 9,
|
||||
|
||||
@@ -102,18 +99,6 @@ pub enum Error {
|
||||
#[error("Node has a sibling with this name")]
|
||||
NodeSiblingNameConflict = 27,
|
||||
|
||||
#[error("File not found")]
|
||||
FileNotFound = 28,
|
||||
|
||||
#[error("Resource is not found")]
|
||||
ResourceNotFound = 29,
|
||||
|
||||
#[error("Python expr eval error")]
|
||||
PyEvalErr = 30,
|
||||
|
||||
#[error("Empty S-expr")]
|
||||
SExprEmpty = 31,
|
||||
|
||||
#[error("S-expr global not found")]
|
||||
SExprGlobalNotFound = 32,
|
||||
|
||||
@@ -123,9 +108,6 @@ pub enum Error {
|
||||
#[error("Publisher was destroyed")]
|
||||
PublisherDestroyed = 34,
|
||||
|
||||
#[error("Empty atlas")]
|
||||
AtlasIsEmpty = 35,
|
||||
|
||||
#[error("Channel closed")]
|
||||
ChannelClosed = 36,
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ pub enum SExprVal {
|
||||
}
|
||||
|
||||
impl SExprVal {
|
||||
#[allow(dead_code)]
|
||||
fn is_null(&self) -> bool {
|
||||
match self {
|
||||
Self::Null => true,
|
||||
@@ -42,6 +43,7 @@ impl SExprVal {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn is_bool(&self) -> bool {
|
||||
match self {
|
||||
Self::Bool(_) => true,
|
||||
@@ -56,6 +58,7 @@ impl SExprVal {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn is_f32(&self) -> bool {
|
||||
match self {
|
||||
Self::Float32(_) => true,
|
||||
@@ -63,6 +66,7 @@ impl SExprVal {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn is_str(&self) -> bool {
|
||||
match self {
|
||||
Self::Str(_) => true,
|
||||
@@ -70,6 +74,7 @@ impl SExprVal {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn as_bool(&self) -> Result<bool> {
|
||||
match self {
|
||||
Self::Bool(v) => Ok(*v),
|
||||
@@ -91,6 +96,7 @@ impl SExprVal {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn as_str(&self) -> Result<String> {
|
||||
match self {
|
||||
Self::Str(v) => Ok(v.clone()),
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use darkfi_serial::{
|
||||
async_trait, Decodable, Encodable, FutAsyncWriteExt, ReadExt, SerialDecodable, SerialEncodable,
|
||||
};
|
||||
use darkfi_serial::{async_trait, SerialDecodable, SerialEncodable};
|
||||
use log::debug;
|
||||
use miniquad::{
|
||||
conf, window, Backend, Bindings, BlendFactor, BlendState, BlendValue, BufferId, BufferLayout,
|
||||
@@ -38,7 +36,6 @@ use crate::{
|
||||
app::{AppPtr, AsyncRuntime},
|
||||
error::{Error, Result},
|
||||
pubsub::{Publisher, PublisherPtr, Subscription, SubscriptionId},
|
||||
util::ansi_texture,
|
||||
};
|
||||
|
||||
// This is very noisy so suppress output by default
|
||||
@@ -439,6 +436,7 @@ impl GraphicsEventPublisher {
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
fn lock_resize(&self, sub_id: SubscriptionId) {
|
||||
*self.lock_resize.lock().unwrap() = Some(sub_id);
|
||||
}
|
||||
@@ -501,6 +499,7 @@ impl GraphicsEventPublisher {
|
||||
fn unlock_touch(&self) {
|
||||
*self.lock_touch.lock().unwrap() = None;
|
||||
}
|
||||
*/
|
||||
|
||||
fn notify_resize(&self, w: f32, h: f32) {
|
||||
let ev = (w, h);
|
||||
@@ -627,7 +626,9 @@ impl GraphicsEventPublisher {
|
||||
}
|
||||
|
||||
struct Stage {
|
||||
#[allow(dead_code)]
|
||||
app: AppPtr,
|
||||
#[allow(dead_code)]
|
||||
async_runtime: AsyncRuntime,
|
||||
|
||||
ctx: Box<dyn RenderingBackend>,
|
||||
@@ -831,9 +832,6 @@ impl EventHandler for Stage {
|
||||
//uniforms_data[64..].copy_from_slice(&data);
|
||||
assert_eq!(128, 2 * UniformType::Mat4.size());
|
||||
|
||||
let (screen_width, screen_height) = window::screen_size();
|
||||
let default_view = Rectangle { x: 0., y: 0., w: screen_width, h: screen_height };
|
||||
|
||||
let mut render_ctx = RenderContext {
|
||||
ctx: &mut self.ctx,
|
||||
draw_calls: &self.draw_calls,
|
||||
|
||||
@@ -19,30 +19,14 @@
|
||||
#![feature(deadline_api)]
|
||||
#![feature(str_split_whitespace_remainder)]
|
||||
#![feature(duration_millis_float)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
||||
// Use these to incrementally fix warnings with cargo fix
|
||||
//#![allow(warnings, unused)]
|
||||
//#![deny(unused_imports)]
|
||||
|
||||
use async_lock::Mutex as AsyncMutex;
|
||||
use std::sync::{mpsc, Arc, Mutex as SyncMutex};
|
||||
|
||||
use darkfi::{
|
||||
async_daemonize, cli_desc,
|
||||
event_graph::{self, proto::ProtocolEventGraph, EventGraph, EventGraphPtr},
|
||||
net::{session::SESSION_DEFAULT, settings::Settings as NetSettings, P2p, P2pPtr},
|
||||
rpc::{
|
||||
jsonrpc::JsonSubscriber,
|
||||
server::{listen_and_serve, RequestHandler},
|
||||
},
|
||||
system::{sleep, sleep_forever, CondVar, StoppableTask, StoppableTaskPtr, Subscription},
|
||||
util::path::{expand_path, get_config_path},
|
||||
Error, Result,
|
||||
};
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize_async, serialize_async, AsyncDecodable, Encodable, SerialDecodable,
|
||||
SerialEncodable,
|
||||
};
|
||||
use std::sync::{mpsc, Arc};
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
@@ -65,12 +49,7 @@ mod text;
|
||||
mod ui;
|
||||
mod util;
|
||||
|
||||
use crate::{
|
||||
darkirc::DarkIrcBackend,
|
||||
net::ZeroMQAdapter,
|
||||
scene::{SceneGraph, SceneGraphPtr2},
|
||||
text::TextShaper,
|
||||
};
|
||||
use crate::{darkirc::DarkIrcBackend, net::ZeroMQAdapter, scene::SceneGraph, text::TextShaper};
|
||||
|
||||
pub type ExecutorPtr = Arc<smol::Executor<'static>>;
|
||||
|
||||
@@ -141,7 +120,6 @@ fn main() {
|
||||
text_shaper,
|
||||
darkirc_backend,
|
||||
);
|
||||
let app2 = app.clone();
|
||||
let app_task = ex.spawn(app.clone().start());
|
||||
async_runtime.push_task(app_task);
|
||||
|
||||
|
||||
@@ -18,19 +18,24 @@
|
||||
|
||||
use crate::{
|
||||
error::Result,
|
||||
gfx::{DrawMesh, Point, Rectangle, RenderApi, Vertex},
|
||||
gfx::{DrawMesh, Rectangle, RenderApi, Vertex},
|
||||
};
|
||||
use miniquad::{BufferId, TextureId};
|
||||
|
||||
pub type Color = [f32; 4];
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const COLOR_RED: Color = [1., 0., 0., 1.];
|
||||
#[allow(dead_code)]
|
||||
pub const COLOR_DARKGREY: Color = [0.2, 0.2, 0.2, 1.];
|
||||
#[allow(dead_code)]
|
||||
pub const COLOR_LIGHTGREY: Color = [0.7, 0.7, 0.7, 1.];
|
||||
pub const COLOR_GREEN: Color = [0., 1., 0., 1.];
|
||||
pub const COLOR_BLUE: Color = [0., 0., 1., 1.];
|
||||
pub const COLOR_WHITE: Color = [1., 1., 1., 1.];
|
||||
#[allow(dead_code)]
|
||||
pub const COLOR_BLACK: Color = [1., 1., 1., 1.];
|
||||
#[allow(dead_code)]
|
||||
pub const COLOR_GREY: Color = [0.5, 0.5, 0.5, 1.];
|
||||
|
||||
#[derive(Clone)]
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
*/
|
||||
|
||||
use async_lock::Mutex;
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize, Decodable, Encodable, FutAsyncWriteExt, ReadExt, SerialDecodable,
|
||||
SerialEncodable, VarInt,
|
||||
};
|
||||
use darkfi_serial::{async_trait, deserialize, Decodable, Encodable, SerialDecodable, VarInt};
|
||||
use std::{
|
||||
io::Cursor,
|
||||
sync::{mpsc, Arc},
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
*/
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize, Decodable, Encodable, FutAsyncWriteExt, ReadExt, SerialDecodable,
|
||||
SerialEncodable, VarInt,
|
||||
};
|
||||
use darkfi_serial::{async_trait, Encodable, FutAsyncWriteExt, SerialDecodable, SerialEncodable};
|
||||
use std::{
|
||||
io::Write,
|
||||
sync::{Arc, Mutex},
|
||||
@@ -206,7 +203,9 @@ impl Encodable for PropertyValue {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ModifyAction {
|
||||
Clear,
|
||||
#[allow(dead_code)]
|
||||
Set(usize),
|
||||
#[allow(dead_code)]
|
||||
Push(usize),
|
||||
}
|
||||
|
||||
@@ -373,7 +372,7 @@ impl Property {
|
||||
return Err(Error::PropertyNullNotAllowed)
|
||||
}
|
||||
|
||||
let vals = &mut self.vals.lock().unwrap();
|
||||
let mut vals = self.vals.lock().unwrap();
|
||||
if i >= vals.len() {
|
||||
return Err(Error::PropertyWrongIndex)
|
||||
}
|
||||
@@ -475,7 +474,7 @@ impl Property {
|
||||
return Err(Error::PropertyIsBounded)
|
||||
}
|
||||
|
||||
let vals = &mut self.vals.lock().unwrap();
|
||||
let mut vals = self.vals.lock().unwrap();
|
||||
let i = vals.len();
|
||||
vals.push(value);
|
||||
drop(vals);
|
||||
@@ -663,13 +662,13 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_getset() {
|
||||
let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
assert!(prop.set_f32(1, 4.).is_err());
|
||||
let prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
assert!(prop.set_f32(Role::App, 1, 4.).is_err());
|
||||
assert!(prop.is_unset(0).unwrap());
|
||||
assert!(prop.set_f32(0, 4.).is_ok());
|
||||
assert!(prop.set_f32(Role::App, 0, 4.).is_ok());
|
||||
assert_eq!(prop.get_f32(0).unwrap(), 4.);
|
||||
assert!(!prop.is_unset(0).unwrap());
|
||||
prop.unset(0).unwrap();
|
||||
prop.unset(Role::App, 0).unwrap();
|
||||
assert!(prop.is_unset(0).unwrap());
|
||||
assert_eq!(prop.get_f32(0).unwrap(), 0.);
|
||||
}
|
||||
@@ -681,13 +680,13 @@ mod tests {
|
||||
assert!(prop.set_defaults_f32(vec![1.0, 0.0]).is_err());
|
||||
assert!(prop.set_defaults_f32(vec![2.0]).is_ok());
|
||||
prop.allow_null_values();
|
||||
prop.set_null(0).unwrap();
|
||||
prop.set_null(Role::App, 0).unwrap();
|
||||
|
||||
assert!(prop.get_f32_opt(1).is_err());
|
||||
assert!(prop.get_f32_opt(0).is_ok());
|
||||
assert!(prop.get_f32_opt(0).unwrap().is_none());
|
||||
|
||||
prop.clear_values();
|
||||
prop.clear_values(Role::App);
|
||||
assert!(prop.get_f32(0).is_ok());
|
||||
assert!(prop.get_f32_opt(0).unwrap().is_some());
|
||||
assert_eq!(prop.get_f32(0).unwrap(), 2.0);
|
||||
@@ -695,8 +694,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_nonnullable() {
|
||||
let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
assert!(prop.set_null(0).is_err());
|
||||
let prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
assert!(prop.set_null(Role::App, 0).is_err());
|
||||
assert!(prop.is_unset(0).unwrap());
|
||||
}
|
||||
|
||||
@@ -705,24 +704,24 @@ mod tests {
|
||||
let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
prop.set_unbounded();
|
||||
assert_eq!(prop.get_len(), 0);
|
||||
prop.push_f32(2.0).unwrap();
|
||||
prop.push_f32(3.0).unwrap();
|
||||
prop.push_f32(Role::App, 2.0).unwrap();
|
||||
prop.push_f32(Role::App, 3.0).unwrap();
|
||||
assert_eq!(prop.get_len(), 2);
|
||||
|
||||
prop.clear_values();
|
||||
prop.clear_values(Role::App);
|
||||
assert_eq!(prop.get_len(), 0);
|
||||
prop.allow_null_values();
|
||||
prop.push_null().unwrap();
|
||||
prop.push_f32(4.0).unwrap();
|
||||
prop.push_f32(5.0).unwrap();
|
||||
prop.push_null(Role::App).unwrap();
|
||||
prop.push_f32(Role::App, 4.0).unwrap();
|
||||
prop.push_f32(Role::App, 5.0).unwrap();
|
||||
assert_eq!(prop.get_len(), 3);
|
||||
assert!(prop.get_f32_opt(0).unwrap().is_none());
|
||||
assert!(prop.get_f32_opt(1).unwrap().is_some());
|
||||
assert!(prop.get_f32_opt(2).unwrap().is_some());
|
||||
assert!(prop.get_f32_opt(3).is_err());
|
||||
|
||||
let mut prop2 = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
assert!(prop2.push_f32(4.0).is_err());
|
||||
let prop2 = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
assert!(prop2.push_f32(Role::App, 4.0).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -730,16 +729,16 @@ mod tests {
|
||||
let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
|
||||
let half_pi = 3.1415926535 / 2.;
|
||||
prop.set_range_f32(-half_pi, half_pi);
|
||||
assert!(prop.set_f32(0, 6.).is_err());
|
||||
assert!(prop.set_f32(0, 1.).is_ok());
|
||||
assert!(prop.set_f32(Role::App, 0, 6.).is_err());
|
||||
assert!(prop.set_f32(Role::App, 0, 1.).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enum() {
|
||||
let mut prop = Property::new("foo", PropertyType::Enum, PropertySubType::Null);
|
||||
prop.set_enum_items(vec!["ABC", "XYZ", "FOO"]).unwrap();
|
||||
assert!(prop.set_enum(0, "ABC").is_ok());
|
||||
assert!(prop.set_enum(0, "BAR").is_err());
|
||||
assert!(prop.set_enum(Role::App, 0, "ABC").is_ok());
|
||||
assert!(prop.set_enum(Role::App, 0, "BAR").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -748,7 +747,7 @@ mod tests {
|
||||
prop.allow_exprs();
|
||||
assert_eq!(prop.get_f32(0).unwrap(), 0.);
|
||||
let code = vec![Op::ConstFloat32(4.)];
|
||||
prop.set_expr(0, code).unwrap();
|
||||
prop.set_expr(Role::App, 0, code).unwrap();
|
||||
let val = prop.get_cached(0).unwrap();
|
||||
assert!(val.is_null());
|
||||
prop.set_cache_f32(0, 4.).unwrap();
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{Property, PropertyPtr, Role};
|
||||
use super::{PropertyPtr, Role};
|
||||
use crate::{
|
||||
error::{Error, Result},
|
||||
scene::SceneNode,
|
||||
|
||||
@@ -83,7 +83,7 @@ impl<T: Piped> Publisher<T> {
|
||||
}
|
||||
|
||||
/// Publish a message to subscriptions in the include list
|
||||
pub async fn notify_with_include(&self, message_result: T, include_list: &[SubscriptionId]) {
|
||||
pub fn notify_with_include(&self, message_result: T, include_list: &[SubscriptionId]) {
|
||||
// Maybe we should just provide a method to get all IDs
|
||||
// Then people can call notify_with_exclude() instead.
|
||||
// TODO: just collect and clone directly into a Vec
|
||||
@@ -93,7 +93,7 @@ impl<T: Piped> Publisher<T> {
|
||||
continue
|
||||
}
|
||||
|
||||
if let Err(e) = sub.send(message_result.clone()).await {
|
||||
if let Err(e) = sub.try_send(message_result.clone()) {
|
||||
panic!("[system::publisher] Error returned sending message in notify_with_include() call! {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,13 @@
|
||||
|
||||
use async_channel::Sender;
|
||||
use async_lock::Mutex;
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize, Decodable, Encodable, FutAsyncWriteExt, ReadExt, SerialDecodable,
|
||||
SerialEncodable, VarInt,
|
||||
};
|
||||
use darkfi_serial::{async_trait, FutAsyncWriteExt, SerialDecodable, SerialEncodable};
|
||||
use futures::{stream::FuturesUnordered, StreamExt};
|
||||
use std::{fmt, str::FromStr, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
error::{Error, Result},
|
||||
prop::{Property, PropertyPtr, PropertyType, Role},
|
||||
prop::{Property, PropertyPtr, Role},
|
||||
ui,
|
||||
};
|
||||
|
||||
@@ -106,7 +103,6 @@ impl FromStr for ScenePath {
|
||||
}
|
||||
}
|
||||
|
||||
pub type SceneGraphPtr = Arc<std::sync::Mutex<SceneGraph>>;
|
||||
pub type SceneGraphPtr2 = Arc<Mutex<SceneGraph>>;
|
||||
|
||||
pub struct SceneGraph {
|
||||
@@ -176,9 +172,11 @@ impl SceneGraph {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn root(&self) -> &SceneNode {
|
||||
&self.nodes[0]
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
fn root_mut(&mut self) -> &mut SceneNode {
|
||||
&mut self.nodes[0]
|
||||
}
|
||||
@@ -574,9 +572,6 @@ impl SceneNode {
|
||||
pub fn get_method(&self, name: &str) -> Option<&Method> {
|
||||
self.methods.iter().find(|method| method.name == name)
|
||||
}
|
||||
fn get_method_mut(&mut self, name: &str) -> Option<&mut Method> {
|
||||
self.methods.iter_mut().find(|method| method.name == name)
|
||||
}
|
||||
|
||||
pub fn call_method(
|
||||
&mut self,
|
||||
@@ -606,7 +601,6 @@ pub struct CallArg {
|
||||
pub typ: CallArgType,
|
||||
}
|
||||
|
||||
type SlotFn = Box<dyn Fn(Vec<u8>) + Send>;
|
||||
pub type SlotId = u32;
|
||||
|
||||
pub struct Slot {
|
||||
@@ -616,7 +610,9 @@ pub struct Slot {
|
||||
|
||||
pub struct Signal {
|
||||
pub name: String,
|
||||
#[allow(dead_code)]
|
||||
pub desc: String,
|
||||
#[allow(dead_code)]
|
||||
pub fmt: Vec<CallArg>,
|
||||
slots: Vec<Slot>,
|
||||
freed: Vec<SlotId>,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use miniquad::TextureId;
|
||||
|
||||
use crate::{
|
||||
error::{Error, Result},
|
||||
gfx::{Rectangle, RenderApi, RenderApiPtr},
|
||||
util::{ansi_texture, zip3},
|
||||
error::Result,
|
||||
gfx::{Rectangle, RenderApi},
|
||||
};
|
||||
|
||||
use super::{Glyph, Sprite, SpritePtr};
|
||||
|
||||
@@ -22,21 +22,16 @@ use harfbuzz_sys::{
|
||||
freetype::hb_ft_font_create_referenced, hb_buffer_add_utf8, hb_buffer_create,
|
||||
hb_buffer_destroy, hb_buffer_get_glyph_infos, hb_buffer_get_glyph_positions,
|
||||
hb_buffer_guess_segment_properties, hb_buffer_set_cluster_level, hb_buffer_set_content_type,
|
||||
hb_feature_t, hb_font_destroy, hb_glyph_info_t, hb_glyph_position_t, hb_shape,
|
||||
hb_font_destroy, hb_glyph_info_t, hb_glyph_position_t, hb_shape,
|
||||
HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS, HB_BUFFER_CONTENT_TYPE_UNICODE,
|
||||
};
|
||||
use miniquad::TextureId;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
os,
|
||||
sync::{Arc, Weak},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::Result,
|
||||
gfx::{Rectangle, RenderApi, RenderApiPtr},
|
||||
util::ansi_texture,
|
||||
};
|
||||
use crate::gfx::Rectangle;
|
||||
|
||||
mod atlas;
|
||||
pub use atlas::{make_texture_atlas, Atlas, RenderedAtlas};
|
||||
@@ -168,7 +163,6 @@ impl TextShaper {
|
||||
break 'get_idx i
|
||||
}
|
||||
}
|
||||
drop(font_faces);
|
||||
|
||||
warn!(target: "text", "no font fallback for char: '{}'", chr);
|
||||
// Skip this char
|
||||
@@ -203,9 +197,6 @@ impl TextShaper {
|
||||
|
||||
let mut glyphs: Vec<Glyph> = vec![];
|
||||
|
||||
let mut current_x = 0.;
|
||||
let mut current_y = 0.;
|
||||
|
||||
for (face_idx, text) in substrs {
|
||||
//debug!("substr {}", text);
|
||||
let face = &mut faces.0[face_idx];
|
||||
@@ -230,7 +221,7 @@ impl TextShaper {
|
||||
|
||||
let utf8_ptr = text.as_ptr() as *const _;
|
||||
// https://harfbuzz.github.io/a-simple-shaping-example.html
|
||||
let (hb_font, buf, glyph_infos, glyph_pos, glyph_infos_iter, glyph_pos_iter) = unsafe {
|
||||
let (hb_font, buf, _glyph_infos, _glyph_pos, glyph_infos_iter, glyph_pos_iter) = unsafe {
|
||||
let ft_face_ptr: freetype::freetype_sys::FT_Face = face.raw_mut();
|
||||
let hb_font = hb_ft_font_create_referenced(ft_face_ptr);
|
||||
let buf = hb_buffer_create();
|
||||
@@ -255,6 +246,7 @@ impl TextShaper {
|
||||
let glyph_pos_iter: &[hb_glyph_position_t] =
|
||||
std::slice::from_raw_parts(glyph_pos as *const _, length as usize);
|
||||
|
||||
// Return glyph_(infos|pos) since iters depend on it
|
||||
(hb_font, buf, glyph_infos, glyph_pos, glyph_infos_iter, glyph_pos_iter)
|
||||
};
|
||||
|
||||
@@ -326,7 +318,7 @@ impl TextShaper {
|
||||
|
||||
//debug!("load_glyph {}", glyph_id);
|
||||
if let Err(err) = face.load_glyph(glyph_id, flags) {
|
||||
error!(target: "text", "error loading glyph: {}", glyph_id);
|
||||
error!(target: "text", "error loading glyph {glyph_id}: {err}");
|
||||
continue
|
||||
}
|
||||
//debug!("load_glyph {} [done]", glyph_id);
|
||||
|
||||
@@ -16,13 +16,14 @@ struct Token {
|
||||
}
|
||||
|
||||
impl Token {
|
||||
#[allow(dead_code)]
|
||||
fn as_str(&self) -> String {
|
||||
glyph_str(&self.glyphs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the string represented by a vec of glyphs. Useful for debugging.
|
||||
fn glyph_str(glyphs: &Vec<Glyph>) -> String {
|
||||
pub fn glyph_str(glyphs: &Vec<Glyph>) -> String {
|
||||
glyphs.iter().map(|g| g.substr.as_str()).collect::<Vec<_>>().join("")
|
||||
}
|
||||
|
||||
@@ -58,6 +59,7 @@ fn tokenize(font_size: f32, glyphs: &Vec<Glyph>) -> Vec<Token> {
|
||||
|
||||
// Reset ruler
|
||||
lhs = -1.;
|
||||
#[allow(unused_assignments)]
|
||||
rhs = 0.;
|
||||
// take() blanked token_glyphs above
|
||||
|
||||
@@ -91,7 +93,7 @@ fn apply_wrap(line_width: f32, tokens: Vec<Token>) -> Vec<Vec<Glyph>> {
|
||||
let mut line = vec![];
|
||||
let mut start = 0.;
|
||||
|
||||
for (i, mut token) in tokens.into_iter().enumerate() {
|
||||
for mut token in tokens {
|
||||
assert!(token.token_type != TokenType::Null);
|
||||
|
||||
// Triggered by if below
|
||||
|
||||
@@ -16,30 +16,27 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use miniquad::{window, BufferId, KeyCode, KeyMods, MouseButton, TextureId, TouchPhase};
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
use miniquad::{MouseButton, TouchPhase};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Weak,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
gfx::{
|
||||
DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, Point, Rectangle,
|
||||
RenderApiPtr, Vertex,
|
||||
},
|
||||
prop::{PropertyBool, PropertyPtr, PropertyUint32, Role},
|
||||
gfx::{GraphicsEventPublisherPtr, Point, Rectangle},
|
||||
prop::{PropertyBool, PropertyPtr, Role},
|
||||
pubsub::Subscription,
|
||||
scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId, Signal},
|
||||
scene::{Pimpl, SceneGraphPtr2, SceneNodeId},
|
||||
ExecutorPtr,
|
||||
};
|
||||
|
||||
use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable};
|
||||
use super::{eval_rect, read_rect};
|
||||
|
||||
pub type ButtonPtr = Arc<Button>;
|
||||
|
||||
pub struct Button {
|
||||
node_id: SceneNodeId,
|
||||
#[allow(dead_code)]
|
||||
tasks: Vec<smol::Task<()>>,
|
||||
sg: SceneGraphPtr2,
|
||||
|
||||
|
||||
@@ -21,39 +21,30 @@ use atomic_float::AtomicF32;
|
||||
use chrono::{Local, TimeZone};
|
||||
use darkfi::system::{msleep, CondVar};
|
||||
use darkfi_serial::{
|
||||
async_trait, deserialize, Decodable, Encodable, FutAsyncWriteExt, ReadExt, SerialDecodable,
|
||||
SerialEncodable, VarInt,
|
||||
async_trait, deserialize, Decodable, Encodable, SerialDecodable, SerialEncodable,
|
||||
};
|
||||
use miniquad::{KeyCode, KeyMods, TouchPhase};
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
hash::{DefaultHasher, Hash, Hasher},
|
||||
io::Cursor,
|
||||
sync::{atomic::Ordering, Arc, Mutex as SyncMutex, Weak},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::Result,
|
||||
gfx::{
|
||||
DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, Point, Rectangle,
|
||||
RenderApi, RenderApiPtr, Vertex,
|
||||
},
|
||||
mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_GREEN, COLOR_GREY, COLOR_WHITE},
|
||||
prop::{
|
||||
PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
|
||||
Role,
|
||||
RenderApi, RenderApiPtr,
|
||||
},
|
||||
mesh::{Color, MeshBuilder, COLOR_BLUE, COLOR_GREEN},
|
||||
prop::{PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyUint32, Role},
|
||||
pubsub::Subscription,
|
||||
scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
|
||||
text::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
|
||||
util::zip3,
|
||||
text::{self, Glyph, GlyphPositionIter, TextShaperPtr},
|
||||
ExecutorPtr,
|
||||
};
|
||||
|
||||
use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable};
|
||||
|
||||
const DEBUG_RENDER: bool = false;
|
||||
use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify};
|
||||
|
||||
const EPSILON: f32 = 0.001;
|
||||
const BIG_EPSILON: f32 = 0.05;
|
||||
@@ -71,7 +62,7 @@ fn replace_vec_item<T>(vec: &mut Vec<T>, idx: usize, mut items: Vec<T>) {
|
||||
assert!(idx < vec.len());
|
||||
if items.len() == 1 {
|
||||
let item = items.remove(0);
|
||||
std::mem::replace(&mut vec[idx], item);
|
||||
let _ = std::mem::replace(&mut vec[idx], item);
|
||||
return
|
||||
}
|
||||
|
||||
@@ -96,6 +87,7 @@ type MessageId = [u8; 32];
|
||||
#[derive(Clone)]
|
||||
struct Message {
|
||||
timest: Timestamp,
|
||||
#[allow(dead_code)]
|
||||
id: MessageId,
|
||||
chatmsg: ChatMsg,
|
||||
glyphs: Vec<Glyph>,
|
||||
@@ -104,21 +96,15 @@ struct Message {
|
||||
const PAGE_SIZE: usize = 10;
|
||||
const PRELOAD_PAGES: usize = 10;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Page {
|
||||
msgs: Vec<Message>,
|
||||
atlas: text::RenderedAtlas,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct PageMeshInfo {
|
||||
px_height: f32,
|
||||
mesh: DrawMesh,
|
||||
}
|
||||
|
||||
type Page2Ptr = Arc<Page2>;
|
||||
type PagePtr = Arc<Page>;
|
||||
|
||||
struct Page2 {
|
||||
struct Page {
|
||||
msgs: Vec<Message>,
|
||||
atlas: SyncMutex<text::RenderedAtlas>,
|
||||
// One draw call per page.
|
||||
@@ -126,7 +112,7 @@ struct Page2 {
|
||||
mesh_inf: SyncMutex<Option<PageMeshInfo>>,
|
||||
}
|
||||
|
||||
impl Page2 {
|
||||
impl Page {
|
||||
async fn new(msgs: Vec<Message>, render_api: &RenderApi) -> Arc<Self> {
|
||||
let mut atlas = text::Atlas::new(render_api);
|
||||
for msg in &msgs {
|
||||
@@ -190,7 +176,7 @@ impl Page2 {
|
||||
}
|
||||
|
||||
// Render line
|
||||
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &line, baseline);
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, &line, baseline);
|
||||
for (mut glyph_rect, glyph) in glyph_pos_iter.zip(line.iter()) {
|
||||
let uv_rect = atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
|
||||
glyph_rect.y -= off_y;
|
||||
@@ -263,15 +249,14 @@ pub type ChatViewPtr = Arc<ChatView>;
|
||||
|
||||
pub struct ChatView {
|
||||
node_id: SceneNodeId,
|
||||
#[allow(dead_code)]
|
||||
tasks: Vec<smol::Task<()>>,
|
||||
sg: SceneGraphPtr2,
|
||||
render_api: RenderApiPtr,
|
||||
text_shaper: TextShaperPtr,
|
||||
tree: sled::Tree,
|
||||
|
||||
pages: SyncMutex<Vec<Page>>,
|
||||
pages2: AsyncMutex<Vec<Page2Ptr>>,
|
||||
drawcalls: SyncMutex<Vec<DrawMesh>>,
|
||||
pages: AsyncMutex<Vec<PagePtr>>,
|
||||
dc_key: u64,
|
||||
|
||||
/// Used for detecting when scrolling view
|
||||
@@ -408,9 +393,7 @@ impl ChatView {
|
||||
text_shaper,
|
||||
tree,
|
||||
|
||||
pages: SyncMutex::new(Vec::new()),
|
||||
pages2: AsyncMutex::new(Vec::new()),
|
||||
drawcalls: SyncMutex::new(Vec::new()),
|
||||
pages: AsyncMutex::new(Vec::new()),
|
||||
dc_key: OsRng.gen(),
|
||||
|
||||
mouse_pos: SyncMutex::new(Point::from([0., 0.])),
|
||||
@@ -496,7 +479,7 @@ impl ChatView {
|
||||
me: &Weak<Self>,
|
||||
ev_sub: &Subscription<(KeyCode, KeyMods, bool)>,
|
||||
) -> bool {
|
||||
let Ok((key, mods, repeat)) = ev_sub.receive().await else {
|
||||
let Ok((key, _mods, repeat)) = ev_sub.receive().await else {
|
||||
debug!(target: "ui::editbox", "Event relayer closed");
|
||||
return false
|
||||
};
|
||||
@@ -689,7 +672,7 @@ impl ChatView {
|
||||
|
||||
// Now add message to page
|
||||
|
||||
let mut pages = self.pages2.lock().await;
|
||||
let mut pages = self.pages.lock().await;
|
||||
let mut idx = None;
|
||||
for (i, page) in pages.iter_mut().enumerate() {
|
||||
let first_timest = page.msgs.last().unwrap().timest;
|
||||
@@ -713,11 +696,11 @@ impl ChatView {
|
||||
// Maybe we can write this code below better
|
||||
if pages.is_empty() {
|
||||
let msgs = vec![Message { timest, id: message_id, chatmsg, glyphs }];
|
||||
let page = Page2::new(msgs, &self.render_api).await;
|
||||
let page = Page::new(msgs, &self.render_api).await;
|
||||
pages.push(page);
|
||||
drop(pages);
|
||||
|
||||
let mut scroll = self.scroll.get();
|
||||
let scroll = self.scroll.get();
|
||||
self.scrollview(scroll).await;
|
||||
return;
|
||||
}
|
||||
@@ -744,7 +727,7 @@ impl ChatView {
|
||||
}
|
||||
debug!(target: "ui::chatview", "===============================");
|
||||
|
||||
let new_page = Page2::new(page_msgs, &self.render_api).await;
|
||||
let new_page = Page::new(page_msgs, &self.render_api).await;
|
||||
new_pages.push(new_page);
|
||||
}
|
||||
|
||||
@@ -753,7 +736,7 @@ impl ChatView {
|
||||
drop(pages);
|
||||
|
||||
// This will refresh the view, so we just use this
|
||||
let mut scroll = self.scroll.get();
|
||||
let scroll = self.scroll.get();
|
||||
self.scrollview(scroll).await;
|
||||
}
|
||||
|
||||
@@ -868,7 +851,7 @@ impl ChatView {
|
||||
/// Load extra pages
|
||||
async fn preload_pages(&self) -> usize {
|
||||
// Get last page
|
||||
let last_page = self.pages2.lock().await.last().unwrap().clone();
|
||||
let last_page = self.pages.lock().await.last().unwrap().clone();
|
||||
// get the current earliest timestamp
|
||||
let last_timest = last_page.msgs.last().unwrap().timest;
|
||||
|
||||
@@ -908,9 +891,9 @@ impl ChatView {
|
||||
if msgs.len() >= PAGE_SIZE {
|
||||
debug!(target: "ui::chatview", "added new page. page_len={pages_len}");
|
||||
let msgs = std::mem::take(&mut msgs);
|
||||
let page = Page2::new(msgs, &self.render_api).await;
|
||||
let page = Page::new(msgs, &self.render_api).await;
|
||||
|
||||
self.pages2.lock().await.push(page);
|
||||
self.pages.lock().await.push(page);
|
||||
pages_len += 1;
|
||||
|
||||
if pages_len >= n {
|
||||
@@ -922,9 +905,9 @@ impl ChatView {
|
||||
// Any remaining messages added to a short page
|
||||
if !msgs.is_empty() {
|
||||
debug!(target: "ui::chatview", "added final page. page_len={pages_len}");
|
||||
let page = Page2::new(msgs, &self.render_api).await;
|
||||
let page = Page::new(msgs, &self.render_api).await;
|
||||
|
||||
self.pages2.lock().await.push(page);
|
||||
self.pages.lock().await.push(page);
|
||||
pages_len += 1;
|
||||
}
|
||||
|
||||
@@ -933,7 +916,7 @@ impl ChatView {
|
||||
pages_len
|
||||
}
|
||||
|
||||
async fn get_total_height(&self, rect: &Rectangle, pages: &Vec<Page2Ptr>) -> f32 {
|
||||
async fn get_total_height(&self, rect: &Rectangle, pages: &Vec<PagePtr>) -> f32 {
|
||||
let font_size = self.font_size.get();
|
||||
let line_height = self.line_height.get();
|
||||
let baseline = self.baseline.get();
|
||||
@@ -975,7 +958,7 @@ impl ChatView {
|
||||
current_height
|
||||
}
|
||||
|
||||
async fn draw_cached(&self, mut rect: Rectangle, scroll: &mut f32) -> Vec<DrawInstruction> {
|
||||
async fn draw_cached(&self, rect: Rectangle, scroll: &mut f32) -> Vec<DrawInstruction> {
|
||||
let mut instrs = vec![];
|
||||
|
||||
// When scrolling it can go negative so clamp it here
|
||||
@@ -985,7 +968,7 @@ impl ChatView {
|
||||
|
||||
// Make sure we have enough pages loaded.
|
||||
// If there's no more to load then adjust the scroll.
|
||||
let mut pages = self.pages2.lock().await.clone();
|
||||
let mut pages = self.pages.lock().await.clone();
|
||||
let mut total_height = self.get_total_height(&rect, &pages).await;
|
||||
while total_height < *scroll + rect.h {
|
||||
debug!(target: "ui::chatview", "draw_cached() loading more pages");
|
||||
@@ -1000,7 +983,7 @@ impl ChatView {
|
||||
break
|
||||
}
|
||||
|
||||
pages = self.pages2.lock().await.clone();
|
||||
pages = self.pages.lock().await.clone();
|
||||
}
|
||||
|
||||
// If lines aren't enough to fill the available buffer then start from the top
|
||||
@@ -1054,7 +1037,7 @@ impl ChatView {
|
||||
panic!("Node {:?} bad rect property: {}", node, err);
|
||||
}
|
||||
|
||||
let Ok(mut rect) = read_rect(self.rect.clone()) else {
|
||||
let Ok(rect) = read_rect(self.rect.clone()) else {
|
||||
panic!("Node {:?} bad rect property", node);
|
||||
};
|
||||
|
||||
@@ -1094,7 +1077,7 @@ impl ChatView {
|
||||
}
|
||||
}
|
||||
|
||||
async fn regen_mesh(&self, mut rect: Rectangle) -> (Vec<DrawInstruction>, Vec<DrawMesh>) {
|
||||
async fn regen_mesh(&self, rect: Rectangle) -> (Vec<DrawInstruction>, Vec<DrawMesh>) {
|
||||
let font_size = self.font_size.get();
|
||||
let line_height = self.line_height.get();
|
||||
let baseline = self.baseline.get();
|
||||
@@ -1107,7 +1090,7 @@ impl ChatView {
|
||||
let text_color = self.text_color.get();
|
||||
let nick_colors = self.read_nick_colors();
|
||||
|
||||
let pages = self.pages2.lock().await.clone();
|
||||
let pages = self.pages.lock().await.clone();
|
||||
|
||||
let mut mesh_infs = vec![];
|
||||
// First pass is to measure the height and generate the meshes
|
||||
@@ -1189,14 +1172,6 @@ impl ChatView {
|
||||
colors
|
||||
}
|
||||
|
||||
fn select_nick_color(&self, nick: &str, nick_colors: &[Color]) -> Color {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
nick.hash(&mut hasher);
|
||||
let i = hasher.finish() as usize;
|
||||
let color = nick_colors[i % nick_colors.len()];
|
||||
color
|
||||
}
|
||||
|
||||
pub async fn draw(&self, sg: &SceneGraph, parent_rect: &Rectangle) -> Option<DrawUpdate> {
|
||||
debug!(target: "ui::chatview", "ChatView::draw()");
|
||||
// Only used for debug messages
|
||||
@@ -1206,15 +1181,15 @@ impl ChatView {
|
||||
panic!("Node {:?} bad rect property: {}", node, err);
|
||||
}
|
||||
|
||||
let Ok(mut rect) = read_rect(self.rect.clone()) else {
|
||||
let Ok(rect) = read_rect(self.rect.clone()) else {
|
||||
panic!("Node {:?} bad rect property", node);
|
||||
};
|
||||
|
||||
let timer = std::time::Instant::now();
|
||||
let (mut mesh_instrs, mut old_drawmesh) = self.regen_mesh(rect.clone()).await;
|
||||
let (mut mesh_instrs, old_drawmesh) = self.regen_mesh(rect.clone()).await;
|
||||
debug!(target: "ui::chatview", "regen_mesh() took {:?}", timer.elapsed());
|
||||
|
||||
let mut freed_textures = vec![];
|
||||
let freed_textures = vec![];
|
||||
let mut freed_buffers = vec![];
|
||||
for old_mesh in old_drawmesh {
|
||||
freed_buffers.push(old_mesh.vertex_buffer);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use miniquad::{window, BufferId, KeyCode, KeyMods, MouseButton, TextureId, TouchPhase};
|
||||
use miniquad::{window, KeyCode, KeyMods, MouseButton, TextureId, TouchPhase};
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@@ -31,17 +31,16 @@ use crate::{
|
||||
error::Result,
|
||||
gfx::{
|
||||
DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, Point, Rectangle,
|
||||
RenderApi, RenderApiPtr, Vertex,
|
||||
RenderApiPtr,
|
||||
},
|
||||
mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
|
||||
mesh::{MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
|
||||
prop::{
|
||||
PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
|
||||
Role,
|
||||
},
|
||||
pubsub::Subscription,
|
||||
scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
|
||||
text::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
|
||||
util::zip3,
|
||||
text::{self, Glyph, GlyphPositionIter, TextShaperPtr},
|
||||
ExecutorPtr,
|
||||
};
|
||||
|
||||
@@ -136,11 +135,10 @@ pub type EditBoxPtr = Arc<EditBox>;
|
||||
|
||||
pub struct EditBox {
|
||||
node_id: SceneNodeId,
|
||||
#[allow(dead_code)]
|
||||
tasks: Vec<smol::Task<()>>,
|
||||
sg: SceneGraphPtr2,
|
||||
render_api: RenderApiPtr,
|
||||
// So we can lock the event stream when we gain focus
|
||||
event_pub: GraphicsEventPublisherPtr,
|
||||
text_shaper: TextShaperPtr,
|
||||
key_repeat: SyncMutex<PressedKeysSmoothRepeat>,
|
||||
|
||||
@@ -305,7 +303,6 @@ impl EditBox {
|
||||
tasks,
|
||||
sg,
|
||||
render_api,
|
||||
event_pub,
|
||||
text_shaper,
|
||||
key_repeat: SyncMutex::new(PressedKeysSmoothRepeat::new(400, 50)),
|
||||
|
||||
@@ -366,7 +363,7 @@ impl EditBox {
|
||||
let mut mesh = MeshBuilder::with_clip(clip.clone());
|
||||
self.draw_selected(&mut mesh, &glyphs, clip.h).unwrap();
|
||||
|
||||
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
// Used for drawing the cursor when it's at the end of the line.
|
||||
let mut rhs = 0.;
|
||||
|
||||
@@ -434,7 +431,7 @@ impl EditBox {
|
||||
let baseline = self.baseline.get();
|
||||
let scroll = self.scroll.get();
|
||||
let hi_bg_color = self.hi_bg_color.get();
|
||||
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
|
||||
let mut start_x = 0.;
|
||||
let mut end_x = 0.;
|
||||
@@ -468,13 +465,6 @@ impl EditBox {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn do_key_action(&self, key: char, mods: &KeyMods) {
|
||||
match key {
|
||||
//KeyCode::Left => {}
|
||||
_ => self.insert_char(key).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_char(me: &Weak<Self>, ev_sub: &Subscription<(char, KeyMods, bool)>) -> bool {
|
||||
let Ok((key, mods, repeat)) = ev_sub.receive().await else {
|
||||
debug!(target: "ui::editbox", "Event relayer closed");
|
||||
@@ -643,8 +633,6 @@ impl EditBox {
|
||||
}
|
||||
debug!(target: "ui::editbox", "Focus changed");
|
||||
|
||||
let is_focused = self.is_focused.get();
|
||||
|
||||
// Cursor visibility will change so just redraw everything lol
|
||||
self.redraw().await;
|
||||
}
|
||||
@@ -703,7 +691,7 @@ impl EditBox {
|
||||
// releasing mouse button will end selection
|
||||
self.mouse_btn_held.store(false, Ordering::Relaxed);
|
||||
}
|
||||
async fn handle_mouse_move(&self, mouse_x: f32, mouse_y: f32) {
|
||||
async fn handle_mouse_move(&self, mouse_x: f32, _mouse_y: f32) {
|
||||
if !self.mouse_btn_held.load(Ordering::Relaxed) {
|
||||
return;
|
||||
}
|
||||
@@ -763,7 +751,7 @@ impl EditBox {
|
||||
let lhs = 0.;
|
||||
let mut last_d = (lhs - mouse_x).abs();
|
||||
|
||||
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
let mut rhs = 0.;
|
||||
|
||||
for (i, glyph_rect) in glyph_pos_iter.skip(1).enumerate() {
|
||||
@@ -1221,7 +1209,7 @@ impl EditBox {
|
||||
panic!("Node {:?} bad rect property: {}", node, err);
|
||||
}
|
||||
|
||||
let Ok(mut rect) = read_rect(self.rect.clone()) else {
|
||||
let Ok(rect) = read_rect(self.rect.clone()) else {
|
||||
panic!("Node {:?} bad rect property", node);
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
//use async_lock::Mutex;
|
||||
use image::ImageReader;
|
||||
use miniquad::{BufferId, TextureId};
|
||||
use miniquad::TextureId;
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
use std::{
|
||||
io::Cursor,
|
||||
@@ -26,25 +26,21 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
gfx::{DrawCall, DrawInstruction, DrawMesh, Rectangle, RenderApi, RenderApiPtr, Vertex},
|
||||
mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
|
||||
prop::{
|
||||
PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
|
||||
Role,
|
||||
},
|
||||
gfx::{DrawCall, DrawInstruction, DrawMesh, Rectangle, RenderApiPtr},
|
||||
mesh::{MeshBuilder, MeshInfo, COLOR_WHITE},
|
||||
prop::{PropertyPtr, PropertyStr, PropertyUint32, Role},
|
||||
scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
|
||||
text::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
|
||||
util::zip3,
|
||||
ExecutorPtr,
|
||||
};
|
||||
|
||||
use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable};
|
||||
use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify};
|
||||
|
||||
pub type ImagePtr = Arc<Image>;
|
||||
|
||||
pub struct Image {
|
||||
sg: SceneGraphPtr2,
|
||||
render_api: RenderApiPtr,
|
||||
#[allow(dead_code)]
|
||||
tasks: Vec<smol::Task<()>>,
|
||||
|
||||
mesh: SyncMutex<Option<MeshInfo>>,
|
||||
@@ -149,7 +145,7 @@ impl Image {
|
||||
}
|
||||
|
||||
/// Called whenever any property changes.
|
||||
async fn regen_mesh(&self, clip: Rectangle) -> MeshInfo {
|
||||
async fn regen_mesh(&self, _clip: Rectangle) -> MeshInfo {
|
||||
let basic = Rectangle { x: 0., y: 0., w: 1., h: 1. };
|
||||
|
||||
let mut mesh = MeshBuilder::new();
|
||||
@@ -166,7 +162,7 @@ impl Image {
|
||||
panic!("Node {:?} bad rect property: {}", node, err);
|
||||
}
|
||||
|
||||
let Ok(mut rect) = read_rect(self.rect.clone()) else {
|
||||
let Ok(rect) = read_rect(self.rect.clone()) else {
|
||||
panic!("Node {:?} bad rect property", node);
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ pub type MeshPtr = Arc<Mesh>;
|
||||
pub struct Mesh {
|
||||
sg: SceneGraphPtr2,
|
||||
render_api: RenderApiPtr,
|
||||
tasks: Vec<smol::Task<()>>,
|
||||
_tasks: Vec<smol::Task<()>>,
|
||||
|
||||
vertex_buffer: miniquad::BufferId,
|
||||
index_buffer: miniquad::BufferId,
|
||||
@@ -75,7 +75,7 @@ impl Mesh {
|
||||
Self {
|
||||
sg,
|
||||
render_api,
|
||||
tasks: on_modify.tasks,
|
||||
_tasks: on_modify.tasks,
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
num_elements,
|
||||
|
||||
@@ -17,20 +17,19 @@
|
||||
*/
|
||||
|
||||
//use async_lock::Mutex;
|
||||
use miniquad::{BufferId, TextureId};
|
||||
use miniquad::TextureId;
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
use std::sync::{Arc, Mutex as SyncMutex, Weak};
|
||||
|
||||
use crate::{
|
||||
gfx::{DrawCall, DrawInstruction, DrawMesh, Rectangle, RenderApi, RenderApiPtr, Vertex},
|
||||
gfx::{DrawCall, DrawInstruction, DrawMesh, Rectangle, RenderApi, RenderApiPtr},
|
||||
mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
|
||||
prop::{
|
||||
PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
|
||||
Role,
|
||||
},
|
||||
scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
|
||||
text::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
|
||||
util::zip3,
|
||||
text::{self, GlyphPositionIter, TextShaper, TextShaperPtr},
|
||||
ExecutorPtr,
|
||||
};
|
||||
|
||||
@@ -40,7 +39,6 @@ pub type TextPtr = Arc<Text>;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TextRenderInfo {
|
||||
glyph_sprites: Vec<SpritePtr>,
|
||||
mesh: MeshInfo,
|
||||
texture_id: TextureId,
|
||||
}
|
||||
@@ -49,7 +47,7 @@ pub struct Text {
|
||||
sg: SceneGraphPtr2,
|
||||
render_api: RenderApiPtr,
|
||||
text_shaper: TextShaperPtr,
|
||||
tasks: Vec<smol::Task<()>>,
|
||||
_tasks: Vec<smol::Task<()>>,
|
||||
|
||||
render_info: SyncMutex<TextRenderInfo>,
|
||||
dc_key: u64,
|
||||
@@ -109,7 +107,7 @@ impl Text {
|
||||
sg,
|
||||
render_api,
|
||||
text_shaper,
|
||||
tasks: on_modify.tasks,
|
||||
_tasks: on_modify.tasks,
|
||||
render_info: SyncMutex::new(render_info),
|
||||
dc_key: OsRng.gen(),
|
||||
node_id,
|
||||
@@ -140,11 +138,14 @@ impl Text {
|
||||
let atlas = text::make_texture_atlas(render_api, &glyphs).await.unwrap();
|
||||
|
||||
let mut mesh = MeshBuilder::new();
|
||||
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, &glyphs, baseline);
|
||||
for (glyph_rect, glyph) in glyph_pos_iter.zip(glyphs.iter()) {
|
||||
let uv_rect = atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
|
||||
|
||||
//mesh.draw_outline(&glyph_rect, COLOR_BLUE, 2.);
|
||||
if debug {
|
||||
mesh.draw_outline(&glyph_rect, COLOR_BLUE, 2.);
|
||||
}
|
||||
|
||||
let mut color = text_color.clone();
|
||||
if glyph.sprite.has_color {
|
||||
color = COLOR_WHITE;
|
||||
@@ -154,9 +155,7 @@ impl Text {
|
||||
|
||||
let mesh = mesh.alloc(&render_api).await.unwrap();
|
||||
|
||||
let glyph_sprites = glyphs.into_iter().map(|glyph| glyph.sprite).collect();
|
||||
|
||||
TextRenderInfo { glyph_sprites, mesh, texture_id: atlas.texture_id }
|
||||
TextRenderInfo { mesh, texture_id: atlas.texture_id }
|
||||
}
|
||||
|
||||
async fn redraw(self: Arc<Self>) {
|
||||
@@ -213,7 +212,7 @@ impl Text {
|
||||
panic!("Node {:?} bad rect property: {}", node, err);
|
||||
}
|
||||
|
||||
let Ok(mut rect) = read_rect(self.rect.clone()) else {
|
||||
let Ok(rect) = read_rect(self.rect.clone()) else {
|
||||
panic!("Node {:?} bad rect property", node);
|
||||
};
|
||||
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
|
||||
use colored::Colorize;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn ansi_texture(width: usize, height: usize, data: &Vec<u8>) -> String {
|
||||
let mut out = String::new();
|
||||
|
||||
out.push('┌');
|
||||
for j in 0..width {
|
||||
for _ in 0..width {
|
||||
out.push('─');
|
||||
}
|
||||
out.push('┐');
|
||||
@@ -68,7 +69,7 @@ pub fn ansi_texture(width: usize, height: usize, data: &Vec<u8>) -> String {
|
||||
}
|
||||
|
||||
out.push('└');
|
||||
for j in 0..width {
|
||||
for _ in 0..width {
|
||||
out.push('─');
|
||||
}
|
||||
out.push('┘');
|
||||
@@ -104,6 +105,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn zip3<X1, X2, X3, I1, I2, I3>(i1: I1, i2: I2, i3: I3) -> TupleIterStruct3<I1, I2, I3>
|
||||
where
|
||||
I1: Iterator<Item = X1>,
|
||||
|
||||
Reference in New Issue
Block a user