Fix custom inspector action context and NSView sender; reproduce disabled controls and pass 1046 regressions
这个提交包含在:
1 父节点
3bb33818ea
当前提交
53ce88dd15
15 个文件已更改
+149
-39
没有与搜索条件相匹配的文件
@@ -1,6 +1,6 @@
|
||||
# 大鱼人像美化 FCP 效果模板
|
||||
|
||||
版本:1.1.0。滤镜 UUID:`FB14B0E6-59B2-4836-916F-CD0C559E9241`。需配套同版大鱼人像美化 FxPlug APP。
|
||||
版本:1.1.1。滤镜 UUID:`FB14B0E6-59B2-4836-916F-CD0C559E9241`。需配套同版大鱼人像美化 FxPlug APP。
|
||||
|
||||
## 三卡片与自动跟随
|
||||
|
||||
|
||||
+12
-22
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"sha256": "e1c0cff1dd3541ed97cab2cb39a76ad4f28dc659b3be7991cc7ac92dd8ea090b",
|
||||
"version": "1.1.1",
|
||||
"sha256": "7090c1fbe0d8310c0b092f7c56f72e9c3fe6503aa38753f3fd8d7adcbd9a27b3",
|
||||
"filterUUID": "FB14B0E6-59B2-4836-916F-CD0C559E9241",
|
||||
"publishedFunctionalControls": 1,
|
||||
"informationalControls": 2,
|
||||
@@ -58,10 +58,10 @@
|
||||
"legacyValuesPreserved": true,
|
||||
"publishOSC": 0,
|
||||
"currentHostValidation": {
|
||||
"version": "1.1.0",
|
||||
"Motion": "pending user",
|
||||
"FCP": "pending user",
|
||||
"scope": "No Motion/FCP launch, quit, activation, UI operation or native save was performed. XML structure and standalone archive checks do not establish custom inspector loading."
|
||||
"version": "1.1.1",
|
||||
"Motion": "pending native retest",
|
||||
"FCP": "1.1.0 reproduced: all parameter controls disabled and status waiting for host connection; 1.1.1 retest pending",
|
||||
"scope": "User authorized Motion/FCP interaction for this regression investigation."
|
||||
},
|
||||
"customParameter": {
|
||||
"id": 210,
|
||||
@@ -156,14 +156,14 @@
|
||||
},
|
||||
"automatedInspectorValidation": {
|
||||
"scope": "offscreen AppKit inspector, real production controller and mocked host callbacks; no Motion/FCP UI",
|
||||
"fullChecks": 1039,
|
||||
"fullChecks": 1046,
|
||||
"counts": {
|
||||
"beauty": 49,
|
||||
"face": 116,
|
||||
"thinChin": 394,
|
||||
"hostAdapterASan": 248,
|
||||
"oscASan": 98,
|
||||
"inspectorASan": 134
|
||||
"inspectorASan": 141
|
||||
},
|
||||
"nativeVisualQA": "pending user",
|
||||
"manualAnalysisUI": "removed; legacy IDs hidden and buttons disabled",
|
||||
@@ -188,19 +188,9 @@
|
||||
"archives": "Own PGInspectorState secure payload; Foundation outer and inner decode and Motion alphabet roundtrip tested"
|
||||
},
|
||||
"installation": {
|
||||
"version": "1.1.0",
|
||||
"build": "9",
|
||||
"status": "installed",
|
||||
"appPath": "/Library/Plug-Ins/FxPlug/beatygril.app",
|
||||
"templateAndSourceResourceByteVerified": true,
|
||||
"signatureVerified": true,
|
||||
"notarization": "Accepted",
|
||||
"stapleValidated": true,
|
||||
"gatekeeperAccepted": true,
|
||||
"formalPluginKitPathVerified": true,
|
||||
"UIOperated": false,
|
||||
"hostTerminationPerformed": false,
|
||||
"nativeLoadAndVisualQA": "pending user",
|
||||
"receipt": "../../docs/verification/v1.1.0/installed-verification.json"
|
||||
"version": "1.1.1",
|
||||
"build": "10",
|
||||
"status": "pending",
|
||||
"previousInstalledVersion": "1.1.0"
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@
|
||||
<flags>1</flags>
|
||||
</template>
|
||||
<build />
|
||||
<description>大鱼人像美化 1.1.0:磨皮、美白、瘦脸三卡片自定义面板,自动选择主体并实时跟随。模板局部磨皮默认为50%。</description>
|
||||
<description>大鱼人像美化 1.1.1:磨皮、美白、瘦脸三卡片自定义面板,自动选择主体并实时跟随。模板局部磨皮默认为50%。</description>
|
||||
<scene>
|
||||
<sceneSettings>
|
||||
<width>1920</width>
|
||||
@@ -253,7 +253,7 @@
|
||||
<parameter name="Width" id="313" flags="8589934610" default="1" value="1920" />
|
||||
<parameter name="Height" id="314" flags="8589934610" default="1" value="1080" />
|
||||
</parameter>
|
||||
<filter name="大鱼人像美化" id="510000005" factoryID="6" pluginUUID="FB14B0E6-59B2-4836-916F-CD0C559E9241" pluginVersion="1.1.0" pluginName="大鱼人像美化" pluginDynamicParams="0">
|
||||
<filter name="大鱼人像美化" id="510000005" factoryID="6" pluginUUID="FB14B0E6-59B2-4836-916F-CD0C559E9241" pluginVersion="1.1.1" pluginName="大鱼人像美化" pluginDynamicParams="0">
|
||||
<timing in="0 1 1 0" out="299 30 1 0" offset="0 1 1 0" />
|
||||
<baseFlags>8589934608</baseFlags>
|
||||
<parameter name="" id="210" flags="12901679104">
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.1.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>9</string>
|
||||
<string>10</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
<key>PlugInKit</key>
|
||||
@@ -72,7 +72,7 @@
|
||||
<key>uuid</key>
|
||||
<string>FB14B0E6-59B2-4836-916F-CD0C559E9241</string>
|
||||
<key>version</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.1.1</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>className</key>
|
||||
@@ -84,7 +84,7 @@
|
||||
<key>uuid</key>
|
||||
<string>E0E432C8-3D71-4ABA-B006-E7F519E06C87</string>
|
||||
<key>version</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.1.1</string>
|
||||
<key>protocolNames</key>
|
||||
<array>
|
||||
<string>FxOnScreenControl</string>
|
||||
|
||||
@@ -30,6 +30,8 @@ FOUNDATION_EXPORT PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings
|
||||
@property (nonatomic, strong, readonly) PGInspectorState *state;
|
||||
@property (nonatomic, readonly) BOOL available;
|
||||
@property (nonatomic, copy, readonly) NSString *statusMessage;
|
||||
/// The actual custom inspector view identifies the action to the native host.
|
||||
@property (nonatomic, weak, nullable) NSView *actionSender;
|
||||
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager;
|
||||
- (void)refresh;
|
||||
- (void)documentDidChange;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#import "PGInspectorState.h"
|
||||
#import <math.h>
|
||||
#import <stddef.h>
|
||||
#import <os/log.h>
|
||||
|
||||
NSArray<NSDictionary *> *PGInspectorControls(void) {
|
||||
static NSArray *controls; static dispatch_once_t once;
|
||||
@@ -129,6 +130,9 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
|
||||
@property (nonatomic) BOOL interacting;
|
||||
@property (nonatomic) NSTimeInterval pendingUntil;
|
||||
@property (nonatomic) CMTime pendingTime;
|
||||
@property (nonatomic, strong) id activeSender;
|
||||
@property (nonatomic) BOOL reportedConnection;
|
||||
@property (nonatomic) BOOL reportedMissingAction;
|
||||
@end
|
||||
@implementation PGInspectorController
|
||||
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager {
|
||||
@@ -138,13 +142,34 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
|
||||
- (BOOL)start {
|
||||
if(_interacting)return YES;
|
||||
_action=[_manager apiForProtocol:@protocol(FxCustomParameterActionAPI_v4)];
|
||||
if(!_action){
|
||||
_available=NO;_statusMessage=@"等待宿主连接";
|
||||
if(!_reportedMissingAction){os_log(OS_LOG_DEFAULT,"PGInspector action API unavailable manager=%{public}d viewSender=%{public}d onMain=%{public}d",_manager!=nil,_actionSender!=nil,NSThread.isMainThread);_reportedMissingAction=YES;}
|
||||
return NO;
|
||||
}
|
||||
// A native host can expose parameter APIs only after the custom view's
|
||||
// action has established its document context. Never gate startAction on
|
||||
// those APIs being available before entering the action.
|
||||
BOOL readBefore=NO,writeBefore=NO;
|
||||
if(!_reportedConnection){
|
||||
readBefore=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)]!=nil;
|
||||
writeBefore=[_manager apiForProtocol:@protocol(FxParameterSettingAPI_v5)]!=nil;
|
||||
}
|
||||
_activeSender=_actionSender ?: self;
|
||||
[_action startAction:_activeSender];_interacting=YES;
|
||||
@try {
|
||||
id retrieval=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)];
|
||||
id setting=[_manager apiForProtocol:@protocol(FxParameterSettingAPI_v5)];
|
||||
_available=_action && retrieval && setting;
|
||||
if(!_available){_statusMessage=@"等待宿主连接";return NO;}
|
||||
[_action startAction:self];_interacting=YES;return YES;
|
||||
_available=retrieval && setting;
|
||||
if(!_reportedConnection){
|
||||
os_log(OS_LOG_DEFAULT,"PGInspector connection readBefore=%{public}d writeBefore=%{public}d readInAction=%{public}d writeInAction=%{public}d viewSender=%{public}d onMain=%{public}d",readBefore,writeBefore,retrieval!=nil,setting!=nil,[_activeSender isKindOfClass:NSView.class],NSThread.isMainThread);
|
||||
_reportedConnection=YES;
|
||||
}
|
||||
- (void)finish {if(_interacting){_interacting=NO;[_action endAction:self];_action=nil;}}
|
||||
if(!_available){_statusMessage=@"等待宿主连接";[self finish];return NO;}
|
||||
} @catch(NSException *exception) {[self finish];@throw exception;}
|
||||
return YES;
|
||||
}
|
||||
- (void)finish {if(_interacting){_interacting=NO;[_action endAction:_activeSender];_action=nil;_activeSender=nil;}}
|
||||
- (void)readAtTime:(CMTime)time {
|
||||
if(_pendingUntil && CMTimeCompare(time,_pendingTime)!=0)_pendingUntil=0;
|
||||
id<FxParameterRetrievalAPI_v6> api=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)];
|
||||
@@ -241,5 +266,5 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
|
||||
ok=[self commit:[PGInspectorState stateWithValues:values disabledParameters:disabled hasEdits:YES]];
|
||||
} @finally {if(owned)[self finish];}return ok;
|
||||
}
|
||||
- (void)dealloc {if(_interacting)[_action endAction:self];}
|
||||
- (void)dealloc {if(_interacting)[_action endAction:_activeSender];}
|
||||
@end
|
||||
@@ -293,7 +293,7 @@ static PGInspectorGlyphButton *PGUIButton(NSString *glyph, NSColor *accent, id t
|
||||
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager { return [self initWithController:[[PGInspectorController alloc]initWithAPIManager:manager]]; }
|
||||
- (instancetype)initWithController:(PGInspectorController *)controller {
|
||||
if((self=[super initWithFrame:NSMakeRect(0,0,320,100)])){
|
||||
_controller=controller;self.appearance=[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
|
||||
_controller=controller;_controller.actionSender=self;self.appearance=[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
|
||||
NSArray *sections=@[@"smooth",@"color",@"shape",@"more"],*headings=@[@"磨皮",@"美白",@"瘦脸",@"更多设置"];
|
||||
NSArray *colors=@[PGUIColor(.28,.83,.96,1),PGUIColor(.34,.89,.84,1),PGUIColor(.59,.69,.98,1),PGUIColor(.54,.64,.76,1)];
|
||||
NSMutableArray *cards=[NSMutableArray new];
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.1.0</string>
|
||||
<string>1.1.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>9</string>
|
||||
<string>10</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Beauty renderer: 49 checks, 0 failures (Metal).
|
||||
2026-10-21 23:20:16.950 face-tests[22007:5696503] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
Face processing: 116 checks passed
|
||||
2026-10-21 23:20:21.817 slim-tests[22045:5696731] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
PASS: 394 slim alignment checks; maximum UV oracle error 1.09828022e-05
|
||||
@@ -0,0 +1,21 @@
|
||||
2026-10-21 23:20:18.015 host-tests[22024:5696629] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
Default IOSurface maximum byte difference: 0
|
||||
Alternate destination tag maximum byte difference: 0
|
||||
Anatomy default 0/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy default 0/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy default 1/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy default 1/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy big-eye 0/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy big-eye 0/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy big-eye 1/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy big-eye 1/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy chin-positive 0/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-positive 0/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-positive 1/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-positive 1/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-negative 0/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy chin-negative 0/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy chin-negative 1/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy chin-negative 1/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Legacy fallback upright comparison: max=2 mean=0.0010357
|
||||
Host adapter: 248 checks, 0 failures
|
||||
@@ -0,0 +1,6 @@
|
||||
FAIL: an action-scoped host connects and reads the actual template values
|
||||
FAIL: custom parameter actions identify their actual inspector NSView
|
||||
FAIL: action-scoped parameter APIs do not leave the whole native panel disabled
|
||||
FAIL: a connected native control writes through the action-scoped setting API
|
||||
FAIL: a later host connection restores controls after a transient API failure
|
||||
Inspector: 141 checks, 5 failures
|
||||
@@ -0,0 +1 @@
|
||||
Inspector: 141 checks, 0 failures
|
||||
@@ -0,0 +1,21 @@
|
||||
2026-10-21 23:20:17.783 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
|
||||
2026-10-21 23:20:17.791 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,180) surface=320x240 origin=0
|
||||
2026-10-21 23:20:18.509 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.8,0.3) setter=(1152,-432) readback=(0.8,0.3) mode=centered-pixels verified=1
|
||||
2026-10-21 23:20:18.509 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.7,0.4) objectBounds=(-1920,-1080,3840,2160) canvas=(152,78) surface=320x240 origin=0
|
||||
2026-10-21 23:20:18.607 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.8,0.3) setter=(0.8,0.3) readback=(0.12345,0.87654) mode=normalized verified=0
|
||||
2026-10-21 23:20:18.607 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.75,0.25) setter=(0.75,0.25) readback=(0.75,0.25) mode=normalized verified=1
|
||||
2026-10-21 23:20:18.607 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.75,0.25) objectBounds=(-100,-50,200,100) canvas=(160,60) surface=320x240 origin=0
|
||||
2026-10-21 23:20:18.684 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.625,0.375) setter=(0.625,0.375) readback=(0.625,0.375) mode=normalized verified=1
|
||||
2026-10-21 23:20:18.684 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.625,0.375) objectBounds=(-100,-50,200,100) canvas=(240,60) surface=320x240 origin=0
|
||||
2026-10-21 23:20:18.765 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
|
||||
2026-10-21 23:20:18.765 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(144,180) surface=320x240 origin=0
|
||||
2026-10-21 23:20:18.864 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-21 23:20:18.864 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0,1) objectBounds=(-100,-50,200,100) canvas=(100,140) surface=320x240 origin=0
|
||||
2026-10-21 23:20:18.947 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(nan,nan) surface=320x240 origin=0
|
||||
2026-10-21 23:20:19.044 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-21 23:20:19.044 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(inf,nan) surface=320x240 origin=0
|
||||
2026-10-21 23:20:19.123 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-21 23:20:19.123 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,nan) surface=320x240 origin=0
|
||||
2026-10-21 23:20:19.203 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-21 23:20:19.203 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
OSC adapter: 98 checks, 0 failures
|
||||
+8
@@ -101,3 +101,11 @@ Motion:独立普通视频项目,源PTS0、1920×1080/25fps/10秒,媒体通
|
||||
配套卡片版模板和Drop Zone.tiff已在宿主关闭时同步并逐字节核对,moef SHA256为`e1c0cff1dd3541ed97cab2cb39a76ad4f28dc659b3be7991cc7ac92dd8ea090b`。FCP发布入口为面板210及两项版权信息;旧参数定义隐藏保留,手动分析不再显示,输出保持实时自动跟随。自定义面板的真实嵌入、滚动、键盘/VoiceOver、保存重开及视觉均待用户自测。
|
||||
|
||||
临时APP、旧APP备份、公证ZIP已清理。项目、Codex工作树、DerivedData、桌面、下载、Applications、系统/用户FxPlug及paintfcp临时目录的有界扫描仅发现正式外层APP,扫描错误0;不将该范围扩张为全部挂载卷搜索。完整回执和扫描范围见`verification/v1.1.0/installed-verification.json`。最终恢复标签`v1.1.0`包含交付文档,签名产品源码保持f79d24eb0185f31feaae58b83b632f92dcb3ca91。
|
||||
|
||||
## 1.1.1 面板交互修复(原生验收进行中)
|
||||
|
||||
用户报告1.1.0界面无法交互并授权接手Motion/FCP测试。FCP中“大鱼人像美化验收-20261021”独立测试时间线复现:所有PG参数控件被禁用,页脚“等待宿主连接”;“更多设置”可展开,说明视图事件仍正常,故不是整张面板无法命中。失败AX与截图保留本机build/native-111,不上传用户测试画面或资源库内容。
|
||||
|
||||
连接代码原先在开启自定义参数action之前就要求读写API存在,且action sender传NSObject控制器;现先用真实NSView sender开启action,再在其上下文里取得API,缺API时配对结束。新增action-scoped模拟宿主及sender校验用例:修改前141项中5项失败,修改后全通过,包含临时接口失败后重新连接。接口前后布尔日志保留为原生诊断,根因的实际宿主确认仍待新版加载。
|
||||
|
||||
1.1.1(10)完整1046项回归通过(49美化、116人脸、394瘦脸/下巴、248宿主、98 OSC、141检查器),后三套启用ASan。正式编译、公证与原生Motion/FCP交互验收进行中,尚未把自动检查等同于原生通过。
|
||||
+33
-2
@@ -9,10 +9,24 @@
|
||||
@property NSUInteger scalarWrites;
|
||||
@property (strong) NSDictionary *actionBefore;
|
||||
@property (strong) NSDictionary *undoValues;
|
||||
@property BOOL parameterAPIsRequireAction;
|
||||
@property BOOL actionRequiresView;
|
||||
@property NSUInteger invalidActionSenders;
|
||||
@property (weak) id lastActionSender;
|
||||
@end
|
||||
@implementation PGInspectorTestAPI
|
||||
- (id)apiForProtocol:(Protocol *)protocol {
|
||||
NSString *name=NSStringFromProtocol(protocol);
|
||||
if(_parameterAPIsRequireAction && !self.actionDepth &&
|
||||
([name isEqual:@"FxParameterRetrievalAPI_v6"] || [name isEqual:@"FxParameterSettingAPI_v5"]))return nil;
|
||||
return [super apiForProtocol:protocol];
|
||||
}
|
||||
- (void)guard {if(!self.actionDepth)_accessViolations++;}
|
||||
- (void)startAction:(id)sender {if(!self.actionDepth)_actionBefore=[self.values copy];[super startAction:sender];}
|
||||
- (void)startAction:(id)sender {
|
||||
_lastActionSender=sender;
|
||||
if(_actionRequiresView && ![sender isKindOfClass:NSView.class]){_invalidActionSenders++;return;}
|
||||
if(!self.actionDepth)_actionBefore=[self.values copy];[super startAction:sender];
|
||||
}
|
||||
- (void)endAction:(id)sender {if(self.actionDepth==1 && ![self.values isEqual:_actionBefore])_undoValues=_actionBefore;[super endAction:sender];}
|
||||
- (CMTime)currentTime {[self guard];return [super currentTime];}
|
||||
- (BOOL)getCustomParameterValue:(NSObject **)v fromParameter:(UInt32)i atTime:(CMTime)t {[self guard];return [super getCustomParameterValue:v fromParameter:i atTime:t];}
|
||||
@@ -143,9 +157,26 @@ static void ViewInteractionTests(void) {
|
||||
for(NSView *card in view.subviews)if(!card.hidden)Check(NSMaxY(card.frame)<=NSHeight(view.bounds)+1 && NSMaxX(card.frame)<=NSWidth(view.bounds)+1,@"every visible card and footer remains inside the panel at all inspector widths");
|
||||
}
|
||||
}
|
||||
static void HostHandshakeTests(void) {
|
||||
PGInspectorTestAPI *api=[PGInspectorTestAPI new];beatygrilPlugIn *plugin=[[beatygrilPlugIn alloc]initWithAPIManager:api];[plugin addParametersWithError:nil];
|
||||
api.values[@(PGMidtone)]=@.5;
|
||||
api.parameterAPIsRequireAction=YES;api.actionRequiresView=YES;
|
||||
PGInspectorView *view=(PGInspectorView *)[plugin createViewForParameterID:PGInspectorPanel];[view refreshFromHost];
|
||||
Check(view.controller.available && Near([view.controller.state valueForParameter:PGMidtone],.5),@"an action-scoped host connects and reads the actual template values");
|
||||
Check(api.lastActionSender==view && api.invalidActionSenders==0,@"custom parameter actions identify their actual inspector NSView");
|
||||
NSSlider *brightness=(NSSlider *)FindControl(view,NSSlider.class,@"肤色亮度");
|
||||
Check(brightness.enabled,@"action-scoped parameter APIs do not leave the whole native panel disabled");
|
||||
brightness.doubleValue=.42;Fire(brightness);PGInspectorState *saved=api.values[@(PGInspectorPanel)];
|
||||
Check(saved.hasEdits && Near([saved valueForParameter:PGBrightness],.42),@"a connected native control writes through the action-scoped setting API");
|
||||
[api.disabledAPIs addObject:@"FxParameterSettingAPI_v5"];[view refreshFromHost];
|
||||
Check(!view.controller.available && api.actionDepth==0 && api.actionStarts==api.actionEnds,@"a genuinely missing setting API closes the already-started host action");
|
||||
[api.disabledAPIs removeObject:@"FxParameterSettingAPI_v5"];[view refreshFromHost];
|
||||
Check(view.controller.available && brightness.enabled,@"a later host connection restores controls after a transient API failure");
|
||||
Check(api.accessViolations==0 && api.actionDepth==0 && api.actionStarts==api.actionEnds,@"action-scoped connection, edits, failure and reconnection remain balanced");
|
||||
}
|
||||
int main(int argc,const char **argv) {@autoreleasepool {
|
||||
[NSApplication sharedApplication];[NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
|
||||
RegistrationTests();ModelTests();ControllerTests();ViewInteractionTests();
|
||||
RegistrationTests();ModelTests();ControllerTests();ViewInteractionTests();HostHandshakeTests();
|
||||
if(argc>2) {
|
||||
NSData *inner=[NSData dataWithContentsOfFile:@(argv[1])],*outer=[NSData dataWithContentsOfFile:@(argv[2])];NSError *error=nil;
|
||||
NSKeyedUnarchiver *reader=[[NSKeyedUnarchiver alloc]initForReadingFromData:inner error:&error];reader.requiresSecureCoding=YES;
|
||||
|
||||
在新工单中引用
屏蔽一个用户