team: 组建产品和需求团队
新增产品和需求团队: - 张婉琳 - 产品总监(前字节抖音产品总监) - 李明哲 - 需求分析师(前腾讯微信需求分析师) - 王思远 - 架构师(前阿里淘宝资深架构师) 更新管理架构: - 产品线:产品总监 → 需求分析师 → PRD/需求文档 - 技术线:PM + 架构师 → 开发团队 → QA 团队 - 工作流程:产品规划 → 需求分析 → 架构设计 → 需求评审 → 开发实现 → 质量保证 团队职责: - 产品总监:制定产品战略和路线图 - 需求分析师:细化需求,编写需求规格说明 - 架构师:设计技术方案,编写技术设计文档
This commit is contained in:
@@ -31,6 +31,12 @@ impl BlePlugin {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BlePlugin {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for BlePlugin {
|
||||
fn id(&self) -> &'static str {
|
||||
"ble"
|
||||
|
||||
@@ -111,6 +111,12 @@ impl HttpPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HttpPlugin {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for HttpPlugin {
|
||||
fn id(&self) -> &'static str { "http" }
|
||||
|
||||
|
||||
@@ -771,9 +771,7 @@ fn list_video_files(dir: &Path) -> Vec<VideoFileInfo> {
|
||||
}
|
||||
|
||||
fn sanitize_filename(name: &str) -> String {
|
||||
name.replace('/', "_")
|
||||
.replace('\\', "_")
|
||||
.replace("..", "_")
|
||||
name.replace(['/', '\\'], "_").replace("..", "_")
|
||||
}
|
||||
|
||||
fn video_dir(config: &AppConfig) -> PathBuf {
|
||||
|
||||
@@ -98,6 +98,12 @@ impl ScreenPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ScreenPlugin {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for ScreenPlugin {
|
||||
fn id(&self) -> &'static str {
|
||||
"screen"
|
||||
|
||||
@@ -82,6 +82,12 @@ impl VideoPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for VideoPlugin {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for VideoPlugin {
|
||||
fn id(&self) -> &'static str {
|
||||
"video"
|
||||
@@ -142,7 +148,7 @@ impl Plugin for VideoPlugin {
|
||||
processor.pause();
|
||||
}
|
||||
PlayerCommand::Next => {
|
||||
processor.next()?;
|
||||
processor.next_video()?;
|
||||
}
|
||||
PlayerCommand::Previous => {
|
||||
processor.previous()?;
|
||||
|
||||
@@ -16,6 +16,9 @@ use std::collections::HashSet;
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use std::time::Instant;
|
||||
|
||||
type WindowRectKey = (String, i32, i32, i32, i32);
|
||||
type LoggedSizes = ((i32, i32), (i32, i32), (i32, i32));
|
||||
|
||||
fn log_mat_size(label: &str, frame: &Mat) {
|
||||
use std::sync::Mutex;
|
||||
|
||||
@@ -31,7 +34,7 @@ fn log_mat_size(label: &str, frame: &Mat) {
|
||||
fn log_window_image_rect(window_name: &str) {
|
||||
use std::sync::Mutex;
|
||||
|
||||
static SEEN: Mutex<Option<HashSet<(String, i32, i32, i32, i32)>>> = Mutex::new(None);
|
||||
static SEEN: Mutex<Option<HashSet<WindowRectKey>>> = Mutex::new(None);
|
||||
match highgui::get_window_image_rect(window_name) {
|
||||
Ok(rect) => {
|
||||
let key = (
|
||||
@@ -464,7 +467,7 @@ pub struct VideoProcessor {
|
||||
config: AppConfig,
|
||||
transformer: VideoTransformer,
|
||||
output_size: Size,
|
||||
last_logged_sizes: Option<((i32, i32), (i32, i32), (i32, i32))>,
|
||||
last_logged_sizes: Option<LoggedSizes>,
|
||||
transition_enabled: bool,
|
||||
transition: TransitionEffect,
|
||||
playlist: Vec<VideoItem>,
|
||||
@@ -623,7 +626,7 @@ impl VideoProcessor {
|
||||
self.paused = false;
|
||||
}
|
||||
|
||||
pub fn next(&mut self) -> Result<()> {
|
||||
pub fn next_video(&mut self) -> Result<()> {
|
||||
if self.playlist.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -1240,7 +1243,7 @@ impl VideoProcessor {
|
||||
Ok(true)
|
||||
}
|
||||
110 | 78 => {
|
||||
self.next()?;
|
||||
self.next_video()?;
|
||||
Ok(self.running)
|
||||
}
|
||||
112 | 80 => {
|
||||
|
||||
@@ -112,16 +112,12 @@ impl StateMachine {
|
||||
let target_state = state
|
||||
.transitions
|
||||
.iter()
|
||||
.filter_map(|transition| match &transition.trigger {
|
||||
.filter(|transition| match &transition.trigger {
|
||||
TriggerType::Random { probability } => {
|
||||
let probability = probability.clamp(0.0, 1.0);
|
||||
if rng.gen_bool(probability) {
|
||||
Some(transition)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
rng.gen_bool(probability)
|
||||
}
|
||||
_ => None,
|
||||
_ => false,
|
||||
})
|
||||
.max_by_key(|transition| transition.priority)
|
||||
.map(|transition| transition.target_state.clone());
|
||||
|
||||
@@ -214,6 +214,12 @@ impl WifiPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for WifiPlugin {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Plugin for WifiPlugin {
|
||||
fn id(&self) -> &'static str {
|
||||
"wifi"
|
||||
|
||||
Reference in New Issue
Block a user