Files
oak-editor/crates/oakplugin/tests/handle_test.rs
T
Mike-Solar b36cbd6b6f refactor: purge CHandle from module internals (M14 R5)
Module-internal object references are Rust types now (values, Arc,
Mutex); CHandle remains only at the oakengine C-ABI boundary:

- oakundo: the global stack holds UndoStack/UndoCommand values
  directly (stack token is the static's address)
- oaktimeline: marker/workarea boxes carry Arc<Mutex<T>>; commands
  share the same allocation through Arc clones (readers in oakengine
  stubs and the app's graphops updated to lock)
- oaktask/oakstorage: sessions, write-through bindings and the
  database backend pass ProjectArc; the Session drops its manual
  release bookkeeping; nodeutil keeps the CHandle<->Arc boundary
  conversion (release_project restored for the app)
- oakcodec: handle.rs deleted outright (no facade entry needed it);
  texture/block placeholders are unit structs
- oakrender: copier's project handle is an identity u64; alive-count
  machinery removed; handle.rs is make_owned/get/get_mut only
- oakplugin: the instance registry is gone (its unregister key never
  matched, leaking weak entries); handle.rs is the RefBox boundary type
- oaknode/oakcommon: only dead guard/borrow helpers removed; external
  payload handles (texture/processor) documented as the boundary

Flake hunts landed along the way: the audio recording test serializes
on the shared manager lock with a normalized state; the autocacher
cancel test uses a slow producer so cancellation is deterministic.
2026-08-17 16:40:15 +08:00

72 lines
2.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Oak Video Editor - Non-Linear Video Editor
// Copyright (C) 2026 Oak Team
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//! handle.rs 的契约测试:`RefBox` 容器。
//!
//! 单库化(M14 R5)后 crate 内部不再传 CHandle——原 CHandle 装拆
//! `make_owned`/`make_borrowed`/`get`)、panic 兜底(`guard`/
//! `guard_handle`/`guard_void`)与身份注册表(`Registry`)均已删除。
//! [`oakplugin::handle::RefBox`] 仅作为 `Host::create_instance` 的
//! 边界返回类型保留(`Arc<RefBox<Instance>>`oakengine test_support
//! 消费);此处验证其基本契约。每个测试只验一条规则,命名即规约。
mod common;
use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering};
use std::sync::Arc;
use oakplugin::handle::RefBox;
/// 析构标志:以"被析构次数"断言对象的销毁时机(Arc 生命周期语义的
/// 行为探针)。
struct DropFlag(Arc<AtomicUsize>);
impl Drop for DropFlag {
fn drop(&mut self) {
self.0.fetch_add(1, Ordering::Relaxed);
}
}
/// 值可经 `.value` 字段取回(create_instance 返回后调用方的访问方式)。
#[test]
fn refbox_exposes_value_by_field() {
let boxed = RefBox {
refs: AtomicU32::new(1),
value: 7u32,
};
assert_eq!(boxed.value, 7);
}
/// 生命周期完全由外层 Arc 管理:`refs` 只以固定值 1 构造(无 thunk
/// 增减),Arc 归零时内含对象恰好析构一次;弱引用在 Arc 存活期间
/// 有效、归零后失效(host 的活跃实例表即 Weak 列表)。
#[test]
fn refbox_value_drops_exactly_once_when_arc_reaches_zero() {
let drops = Arc::new(AtomicUsize::new(0));
let boxed = Arc::new(RefBox {
refs: AtomicU32::new(1),
value: DropFlag(drops.clone()),
});
let weak = Arc::downgrade(&boxed);
assert!(weak.upgrade().is_some());
assert_eq!(drops.load(Ordering::Relaxed), 0);
drop(boxed);
assert_eq!(drops.load(Ordering::Relaxed), 1);
assert!(weak.upgrade().is_none());
}