diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs index 330dca949..e3c2c6f9e 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs @@ -334,6 +334,7 @@ fn begin_design_turn(session: &mut DesignSession, id: &str) { pending: true, request_index: 0, attempt: 0, + model_selection: None, }); session.last_error = None; session.updated_at = unix_timestamp(); @@ -444,6 +445,45 @@ fn prepare_design_decision( Ok(approved) } +fn select_design_turn_model( + session: &mut DesignSession, + config: &GameCreatorAppConfig, +) -> Result<(), String> { + let turn = session.turn.as_mut().ok_or("缺少当前回合")?; + session.model_id = if config.selected_model_id.trim().is_empty() { + config.llm.model.clone() + } else { + config.selected_model_id.clone() + }; + turn.model_selection = Some(DesignModelSelection { + model: session.model_id.clone(), + reasoning_effort: config.llm.reasoning_effort.clone(), + }); + Ok(()) +} + +fn resolve_design_turn_llm_config( + session: &mut DesignSession, + config: &GameCreatorAppConfig, +) -> Result { + let turn = session.turn.as_mut().ok_or("缺少当前回合")?; + // 旧活动回合恢复时保留已知模型;缺失的推理档只能从当前配置补齐一次。 + let selection = turn + .model_selection + .get_or_insert_with(|| DesignModelSelection { + model: if session.model_id.trim().is_empty() { + config.llm.model.clone() + } else { + session.model_id.clone() + }, + reasoning_effort: config.llm.reasoning_effort.clone(), + }); + let mut llm = resolve_game_creator_llm_config_for_agent(config, "design-agent"); + llm.model = selection.model.clone(); + llm.reasoning_effort = selection.reasoning_effort.clone(); + Ok(llm) +} + fn checkpoint_design(root: &Path, session: &DesignSession) -> Result<(), String> { let _write = acquire_game_creator_agent_runtime_project_write_lock_with_wait(root, "design.session")?; @@ -696,10 +736,7 @@ async fn request_design_provider( return request_scripted_design_provider(root, session, emit).await; } let config = load_game_creator_app_config()?; - let mut llm = resolve_game_creator_llm_config_for_agent(&config, "design-agent"); - if !session.model_id.trim().is_empty() { - llm.model = session.model_id.clone(); - } + let mut llm = resolve_design_turn_llm_config(session, &config)?; // 此循环统一处理流中断与 HTTP 瞬态错误,避免与传输重试相乘。 let max_retries = llm.max_retries; llm.max_retries = 0; @@ -1003,6 +1040,14 @@ async fn finish_design_command( run: bool, mut emit: impl FnMut(DesignEvent) + Send, ) -> Result { + if run + && session + .turn + .as_ref() + .is_some_and(|turn| turn.model_selection.is_none()) + { + resolve_design_turn_llm_config(&mut session, &load_game_creator_app_config()?)?; + } checkpoint_design(root, &session)?; let turn_id = session .turn @@ -1071,15 +1116,15 @@ pub(crate) async fn continue_design_agent_at( .ok_or("策划 Agent 当前正在工作")?; let mut session = match read_design_session(root)? { Some(session) => session, - None => new_design_session( - &project_id, - &load_game_creator_app_config()?.selected_model_id, - ), + None => new_design_session(&project_id, ""), }; if session.project_id != project_id { return Err("策划会话与当前项目不匹配".into()); } let run = prepare_design_input(&mut session, id, input)?; + if run { + select_design_turn_model(&mut session, &load_game_creator_app_config()?)?; + } finish_design_command(root, resources, session, active, run, emit).await } @@ -1110,6 +1155,9 @@ pub(crate) async fn decide_design_phase_at( return Err("策划会话与当前项目不匹配".into()); } let run = prepare_design_decision(&mut session, id, request_id, approved)?; + if run { + select_design_turn_model(&mut session, &load_game_creator_app_config()?)?; + } finish_design_command(root, resources, session, active, run, emit).await } @@ -1541,6 +1589,223 @@ mod tests { fs::write(root.join("design_artifacts/project/速览卡.md"), "速览").expect("write"); } + #[test] + fn design_turn_selection_survives_config_changes_and_legacy_recovery() { + let mut config = GameCreatorAppConfig::default(); + config.selected_model_id = "chosen-model".into(); + config.llm.reasoning_effort = "max".into(); + config.agent_llm.insert( + "design-agent".into(), + serde_json::from_value(json!({ + "model": "agent-override", "reasoningEffort": "low" + })) + .unwrap(), + ); + let mut session = new_design_session("project", "old-model"); + begin_design_turn(&mut session, "new-turn"); + select_design_turn_model(&mut session, &config).unwrap(); + let saved = serde_json::to_value(&session).unwrap(); + assert_eq!( + saved["turn"]["modelSelection"], + json!({ + "model": "chosen-model", "reasoningEffort": "max" + }) + ); + config.selected_model_id = "later-model".into(); + config.llm.model = "later-model".into(); + config.llm.reasoning_effort = "medium".into(); + let mut restored: DesignSession = serde_json::from_value(saved.clone()).unwrap(); + let llm = resolve_design_turn_llm_config(&mut restored, &config).unwrap(); + assert_eq!(llm.model, "chosen-model"); + let request = build_design_request(&restored, &pack(), &llm).unwrap(); + assert_eq!( + request.response_reasoning_effort, + Some(platform_llm::LlmResponseReasoningEffort::Max) + ); + + let mut legacy = saved; + legacy["turn"] + .as_object_mut() + .unwrap() + .remove("modelSelection"); + let mut restored: DesignSession = serde_json::from_value(legacy).unwrap(); + let llm = resolve_design_turn_llm_config(&mut restored, &config).unwrap(); + assert_eq!(llm.model, "chosen-model"); + assert_eq!(llm.reasoning_effort, "medium"); + config.llm.reasoning_effort = "low".into(); + assert_eq!( + resolve_design_turn_llm_config(&mut restored, &config) + .unwrap() + .reasoning_effort, + "medium" + ); + } + + #[tokio::test(flavor = "current_thread")] + async fn design_user_actions_apply_selection_and_tool_requests_keep_the_turn_snapshot() { + let (_temp, root, resources) = init_design_project(); + let config_dir = tempfile::tempdir().unwrap(); + let _config_guard = crate::tests::use_test_runtime_config_dir(config_dir.path().into()); + let (sender, receiver) = std::sync::mpsc::channel(); + let tool_response = json!({"id":"tool-response", "status":"completed", "output":[{ + "type":"function_call", "id":"tool-item", "call_id":"status-call", + "name":"get_workflow_status", "arguments":"{}" + }]}); + let final_response = json!({"id":"final-response", "status":"completed", "output":[{ + "type":"message", "id":"reply", "role":"assistant", "status":"completed", + "content":[{"type":"output_text", "text":"完成", "annotations":[]}] + }]}); + let base_url = crate::tests::spawn_mock_llm_raw_responses_with_capture( + vec![ + tool_response, + final_response.clone(), + final_response.clone(), + final_response.clone(), + final_response.clone(), + final_response, + ], + Some(sender), + ); + let save_selection = |model: &str, effort: &str| { + fs::write( + config_dir.path().join(GAME_CREATOR_CONFIG_FILE_NAME), + serde_json::to_vec(&json!({ + "selectedModelId": model, "selectedModelIsDefault": false, + "llm": {"customEnabled":true, "visibleModels":["model-a","model-b"], + "apiKey":"test-design-key", "baseUrl":base_url, "model":model, + "apiKind":"openai_responses", "reasoningEffort":effort, + "stream":false, "maxRetries":0, "requestTimeoutMs":10000} + })) + .unwrap(), + ) + .unwrap(); + }; + let expect_request = |model: &str, effort: Option<&str>| { + let raw = receiver.recv_timeout(Duration::from_secs(2)).unwrap(); + let body: Value = serde_json::from_str(raw.split_once("\r\n\r\n").unwrap().1).unwrap(); + assert_eq!(body["model"], model); + assert_eq!(body["reasoning"]["effort"].as_str(), effort); + }; + save_selection("model-a", "high"); + let mut changed = false; + let first = continue_design_agent_at( + &root, + &resources, + "first", + DesignInput::Message { + text: "需求".into(), + }, + |event| { + if !changed && event.text.as_deref() == Some("正在请求 Provider…") { + save_selection("model-b", "low"); + changed = true; + } + }, + ) + .await + .unwrap(); + assert!(first.session.last_error.is_none()); + assert!(changed); + expect_request("model-a", Some("high")); + expect_request("model-a", Some("high")); + + let second = continue_design_agent_at( + &root, + &resources, + "second", + DesignInput::Message { + text: "继续".into(), + }, + |_| {}, + ) + .await + .unwrap(); + assert!(second.session.last_error.is_none()); + expect_request("model-b", Some("low")); + let mut session = read_design_session(&root).unwrap().unwrap(); + let session_id = session.session_id.clone(); + session.pending_clarification = Some(DesignClarificationRequest { + request_id: "question".into(), + question: "平台?".into(), + options: vec!["PC".into()], + created_at: 1, + }); + write_design_session(&root, &session).unwrap(); + save_selection("model-a", "medium"); + let answered = continue_design_agent_at( + &root, + &resources, + "answer", + DesignInput::Clarification { + request_id: "question".into(), + option_index: Some(0), + text: None, + }, + |_| {}, + ) + .await + .unwrap(); + assert!(answered.session.last_error.is_none()); + expect_request("model-a", Some("medium")); + + let mut session = read_design_session(&root).unwrap().unwrap(); + session.turn.as_mut().unwrap().pending = true; + session.last_error = Some("provider failure".into()); + write_design_session(&root, &session).unwrap(); + save_selection("model-b", "max"); + let retried = + continue_design_agent_at(&root, &resources, "retry", DesignInput::Retry, |_| {}) + .await + .unwrap(); + assert!(retried.session.last_error.is_none()); + expect_request("model-b", Some("max")); + + let mut session = read_design_session(&root).unwrap().unwrap(); + concept_artifacts(&root); + let approval = submit_design_phase_for_approval(&root, &mut session).unwrap(); + write_design_session(&root, &session).unwrap(); + save_selection("model-a", "default"); + let approved = decide_design_phase_at( + &root, + &resources, + "approve", + &approval.request_id, + true, + |_| {}, + ) + .await + .unwrap(); + assert!(approved.session.last_error.is_none()); + assert_eq!(approved.session.current_phase, "top_design"); + assert_eq!(approved.session.session_id, session_id); + expect_request("model-a", None); + let saved = read_design_session(&root).unwrap().unwrap(); + assert!(saved + .history + .iter() + .any(|item| item["call_id"] == "status-call")); + assert!(!serde_json::to_string(&saved) + .unwrap() + .contains("test-design-key")); + + // 已处理的审批命令不采样新配置,也不重新请求 Provider。 + save_selection("model-b", "low"); + decide_design_phase_at( + &root, + &resources, + "approve", + &approval.request_id, + true, + |_| {}, + ) + .await + .unwrap(); + assert_eq!( + read_design_session(&root).unwrap().unwrap().turn, + saved.turn + ); + } + #[test] fn approval_submission_skips_remaining_tools() { let temp = tempfile::tempdir().expect("tempdir"); @@ -1552,6 +1817,7 @@ mod tests { pending: true, request_index: 0, attempt: 0, + model_selection: None, }); session.pending_batch = Some(DesignToolBatch { calls: vec![ @@ -2202,6 +2468,7 @@ mod tests { pending: true, request_index: 0, attempt: 0, + model_selection: None, }); session.pending_batch = Some(DesignToolBatch { calls: vec![call], diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/design_session.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/design_session.rs index 7d6b8f147..10f26a650 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/design_session.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/design_session.rs @@ -81,7 +81,7 @@ pub(crate) struct DesignSession { pub(crate) engine: String, pub(crate) session_id: String, pub(crate) project_id: String, - /// 入口选择的 AGC 模型目录 ID;同一会话内保持稳定,不保存上游真实模型名。 + /// 最近一次用户执行采用的模型标识;旧活动回合缺快照时也据此恢复。 #[serde(default)] pub(crate) model_id: String, pub(crate) current_phase: String, @@ -124,6 +124,16 @@ pub(crate) struct DesignTurn { pub(crate) pending: bool, pub(crate) request_index: u64, pub(crate) attempt: u32, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub(crate) model_selection: Option, +} + +/// 仅保存恢复所需的用户选择,不包含连接配置或凭据。 +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct DesignModelSelection { + pub(crate) model: String, + pub(crate) reasoning_effort: String, } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs index e01062cdc..4035d98a2 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/mod.rs @@ -280,7 +280,7 @@ pub(crate) struct TestConfigGuard { previous: Option>, } -struct TestRuntimeConfigDirGuard { +pub(crate) struct TestRuntimeConfigDirGuard { _lock: StdMutexGuard<'static, ()>, previous: Option, } @@ -1325,7 +1325,7 @@ fn test_local_config_defaults_mock_provider_to_non_streaming_and_preserves_expli assert_eq!(defaulted["llm"]["stream"], false); } -fn use_test_runtime_config_dir(path: PathBuf) -> TestRuntimeConfigDirGuard { +pub(crate) fn use_test_runtime_config_dir(path: PathBuf) -> TestRuntimeConfigDirGuard { let lock = TEST_CONFIG_LOCK .lock() .unwrap_or_else(|poisoned| poisoned.into_inner()); @@ -2477,7 +2477,7 @@ fn spawn_mock_llm_tool_plan_then_transient_final_compaction( (base_url, handle) } -fn spawn_mock_llm_raw_responses_with_capture( +pub(crate) fn spawn_mock_llm_raw_responses_with_capture( response_bodies: Vec, request_sender: Option>, ) -> String { diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx index be5429c8d..72658093c 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx @@ -267,6 +267,7 @@ export function ProjectSupervisorView({ ...runtimePanelProps }: ProjectSupervisorViewProps) { const designAgentActive = Boolean(designView || onDesignApprove); + const showModelControls = directCodex || designAgentActive; const [settingsOpen, setSettingsOpen] = useState(false); // 语音输入的降级/失败提示:不支持时按钮本身就带提示,这里只承载启动失败与权限类错误。 const [voiceNotice, setVoiceNotice] = useState(''); @@ -772,44 +773,46 @@ export function ProjectSupervisorView({ } onChange={onChatInputChange} /> - {directCodex ? ( + {showModelControls ? (
-
- -
+ {directCodex ? ( +
+ +
+ ) : null}
- {/* 推理档放在模型选择器旁边(Codex 的「高」那个位置):写回的是客户端 - 配置,只影响后续回合;当前回合的行为不受影响。 */} + {/* 两种对话共用客户端配置控件;运行时何时采用选择由各自入口负责。 */} - - composerRef?.current?.insertText(text) - } - onNotice={setVoiceNotice} - /> - {submitting && onCancelTurn ? ( + {directCodex ? ( + + composerRef?.current?.insertText(text) + } + onNotice={setVoiceNotice} + /> + ) : null} + {directCodex && submitting && onCancelTurn ? ( , +) { + window.__TAURI__ = { + core: { invoke: harness.invoke }, + event: { listen: harness.listen }, + }; + window.history.pushState({}, '', '/'); + return render( + React.createElement(App, { + initialProjectPath: harness.projectPath, + orchestrationMode: 'single-supervisor', + planningStartMode: true, + projectSupervisorOnly: true, + }), + ); +} + +async function expectDesignModelReady() { + await waitFor(() => { + expect( + screen.getByRole('button', { name: '对话模型' }).textContent, + ).toContain('高质量'); + }); +} + function designApprovalView() { return { session: { @@ -97,6 +123,105 @@ function designHistoryView() { } export function registerDesignAgentSurfaceTests() { + it('persists Design Agent model and reasoning controls and reads them on reentry', async () => { + const harness = createProjectSupervisorRuntimeHarness({ + designAgentView: designConversationView(), + }); + const first = renderDesignAgent(harness); + await expectDesignModelReady(); + const reasoning = screen.getByRole('button', { name: '推理档' }); + expect( + reasoning.closest('.project-supervisor-composer-controls'), + ).not.toBeNull(); + fireEvent.click(reasoning); + fireEvent.click(screen.getByRole('option', { name: '低' })); + await waitFor(() => { + expect(harness.invoke).toHaveBeenCalledWith( + 'select_game_creator_reasoning_effort', + { effort: 'low' }, + ); + expect( + screen.getByRole('button', { name: '推理档' }).textContent, + ).toContain('低'); + }); + fireEvent.click(screen.getByRole('button', { name: '对话模型' })); + fireEvent.click(await screen.findByRole('option', { name: '快速' })); + await waitFor(() => { + expect(harness.invoke).toHaveBeenCalledWith('select_game_creator_model', { + modelId: 'fast', + isDefault: false, + }); + expect( + screen.getByRole('button', { name: '对话模型' }).textContent, + ).toContain('快速'); + }); + first.unmount(); + renderDesignAgent(harness); + await waitFor(() => { + expect( + screen.getByRole('button', { name: '推理档' }).textContent, + ).toContain('低'); + expect( + screen.getByRole('button', { name: '对话模型' }).textContent, + ).toContain('快速'); + }); + expect( + harness.invoke.mock.calls.some( + ([command]) => command === 'continue_design_agent_session', + ), + ).toBe(false); + }); + + it('allows Design Agent model changes while running without submitting a new turn', async () => { + const harness = createProjectSupervisorRuntimeHarness({ + designAgentView: { ...designConversationView(), running: true }, + }); + renderDesignAgent(harness); + await expectDesignModelReady(); + expect( + (screen.getByRole('button', { name: '推理档' }) as HTMLButtonElement) + .disabled, + ).toBe(false); + fireEvent.click(screen.getByRole('button', { name: '对话模型' })); + fireEvent.click(await screen.findByRole('option', { name: '快速' })); + await waitFor(() => { + expect( + screen.getByRole('button', { name: '对话模型' }).textContent, + ).toContain('快速'); + }); + const input = screen.getByLabelText('项目需求'); + expect(input.closest('[data-disabled="true"]')).not.toBeNull(); + const send = screen.getByRole('button', { name: '思考中' }); + expect(send).toHaveProperty('disabled', true); + fireEvent.click(send); + expect( + harness.invoke.mock.calls.some( + ([command]) => command === 'continue_design_agent_session', + ), + ).toBe(false); + }); + + it('shows Design Agent reasoning save failures and preserves the saved selection', async () => { + const harness = createProjectSupervisorRuntimeHarness({ + designAgentView: designConversationView(), + }); + const invoke = harness.invoke.getMockImplementation()!; + harness.invoke.mockImplementation(async (command, args) => { + if (command === 'select_game_creator_reasoning_effort') { + throw new Error('save failed'); + } + return invoke(command, args); + }); + renderDesignAgent(harness); + await expectDesignModelReady(); + const reasoning = screen.getByRole('button', { name: '推理档' }); + await waitFor(() => expect(reasoning.textContent).toContain('高')); + fireEvent.click(reasoning); + fireEvent.click(screen.getByRole('option', { name: '低' })); + await screen.findByText('推理档保存失败'); + expect(reasoning.textContent).toContain('高'); + }); + it('resumes following Design Agent messages when sending after scrolling up', async () => { const harness = createProjectSupervisorRuntimeHarness({ designAgentView: designHistoryView(), diff --git a/apps/ai-game-creator-shell/tests/appSurface/harness.ts b/apps/ai-game-creator-shell/tests/appSurface/harness.ts index 3b38bd2fe..25f28895e 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/harness.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/harness.ts @@ -534,6 +534,8 @@ function createProjectSupervisorRuntimeHarness({ ); let messageSequence = 0; let selectedModelId = 'quality'; + let selectedModelIsDefault = false; + let reasoningEffort = 'high'; let steerSequence = 0; let sessionExists = initialSessionExists; let currentProjectRevision = initialProjectRevision; @@ -605,9 +607,11 @@ function createProjectSupervisorRuntimeHarness({ }) => void) | null = null; let designAgentUpdateHandler: - ((event: { payload: Record }) => void) | null = null; + | ((event: { payload: Record }) => void) + | null = null; let directThreadNotifyHandler: - ((event: { payload: { subscriptionId: string } }) => void) | null = null; + | ((event: { payload: { subscriptionId: string } }) => void) + | null = null; let directThreadSubscriptionId: string | null = null; let directThreadSubscriptionSequence = 0; // 未消费的运行态事件队列:`subscribe` 的 bootstrap 与 `consume` 都从这里取, @@ -672,22 +676,29 @@ function createProjectSupervisorRuntimeHarness({ async (command: string, args?: Record) => { if ( command === 'read_game_creator_app_config' || - command === 'select_game_creator_model' + command === 'select_game_creator_model' || + command === 'select_game_creator_reasoning_effort' ) { - if (command === 'select_game_creator_model') + if (command === 'select_game_creator_model') { selectedModelId = String(args?.modelId); + selectedModelIsDefault = args?.isDefault === true; + } + if (command === 'select_game_creator_reasoning_effort') { + reasoningEffort = String(args?.effort); + } return { path: '/tmp/test-game-creator-config.json', config: { schemaVersion: 'game-creator-config.v2', agentMode: 'codex_app_server', selectedModelId, + selectedModelIsDefault, llm: { apiKey: '', baseUrl: '', model: 'quality', apiKind: 'openai_responses', - reasoningEffort: 'high', + reasoningEffort, stream: true, webSearchEnabled: true, contextWindowTokens: 128000, diff --git a/docs/project-memory/plans/【实施计划】策划Agent回合模型选择生效-2026-09-20.md b/docs/project-memory/plans/【实施计划】策划Agent回合模型选择生效-2026-09-20.md new file mode 100644 index 000000000..c357c46ad --- /dev/null +++ b/docs/project-memory/plans/【实施计划】策划Agent回合模型选择生效-2026-09-20.md @@ -0,0 +1,45 @@ +# 策划 Agent 回合模型选择生效实施计划 + +| 字段 | 值 | +| --- | --- | +| Milestone | [回合模型选择生效里程碑](./【里程碑】策划Agent回合模型选择生效-2026-09-20.md) | +| Status | implemented(待验收) | +| Owner | 当前任务 Agent | + +## 修改边界与顺序 + +1. 在本地 `DesignTurn` 中追加可缺省的模型/推理档选择快照,仅存两个非敏感字段。现有 UI 只投影会话摘要,无需扩展前端 DTO。 +2. 策划普通发送、澄清回答、用户重试和批准阶段实际开始执行时,从现有配置加载结果获取全局模型和推理档,覆盖上一轮选择;重复命令、拒绝审批和纯读取不重新采样。 +3. Provider 请求使用当前回合快照,工具循环与自动重试期间不随全局选择变化。保留其它连接配置的原解析,策划专属配置不能覆盖这两个用户选择字段。 +4. 自动恢复沿用活动回合快照;旧记录缺快照时保留已有会话模型,并从当前全局配置补推理档,再由原检查点保存。保持工具幂等和审批流程。 +5. 补充既有 Rust 测试,验证请求字段、新旧会话、重试、审批/澄清和恢复;更新主规范与稳定项目记忆。 + +## 非目标 + +不改两个前端控件、GameAgent、模型目录、默认值、供应商适配;不新增模型可用性检查、自动换模型或提交门禁。不保存凭据或完整配置,不引入通用快照框架。 + +## 验证 + +- `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml design_runtime::tests -- --test-threads=1` +- `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml design_session -- --test-threads=1` +- 改动文件 Rust 格式检查;文档索引、编码检查和 `git diff --check`。 +- 优先本地 HTTP fixture 核对发送给 Provider 的模型与推理档,真实 Provider 未运行时明确记录。 + +## 风险与回滚 + +模型选择快照必须在首个副作用前持久化,配置读取失败不能改变既有持久状态;旧记录自动恢复不推断历史推理档。新增可缺省字段支持现有会话读取,回滚不删除会话或产物。 + +时间盒:先完成最小采样/请求闭环和定向测试,再核对恢复与文档。仅在影响本里程碑判据时扩大范围。 + +## 验证记录 + +| 验证 | 结果 | +| --- | --- | +| 改动文件 Rust 格式检查、diff 检查 | 通过 | +| 文档索引、编码检查 | 通过 | +| Rust 定向测试 | 已尝试编译,未执行测试用例;不记为通过 | +| 本地 HTTP fixture | 已补充真实请求字段断言,尚未执行 | +| 桌面/真实 Provider smoke | 未运行 | +| 独立静态审查 | 已检查采样入口、重放/恢复边界、请求循环和测试辅助函数可见性,无可操作发现 | + +新增用例验证回合快照与旧数据读取,以及普通消息、跨工具请求、澄清回答、用户重试、审批批准、重复审批的配置生效边界。已有恢复用例继续覆盖不确定文件操作不重复执行。控件和 GameAgent 无本步修改。 diff --git a/docs/project-memory/plans/【实施计划】策划Agent模型与推理档控件接入-2026-09-20.md b/docs/project-memory/plans/【实施计划】策划Agent模型与推理档控件接入-2026-09-20.md new file mode 100644 index 000000000..43edb6f30 --- /dev/null +++ b/docs/project-memory/plans/【实施计划】策划Agent模型与推理档控件接入-2026-09-20.md @@ -0,0 +1,49 @@ +# 策划 Agent 模型与推理档控件接入实施计划 + +| 字段 | 值 | +| --- | --- | +| Milestone | [控件接入里程碑](./【里程碑】策划Agent模型与推理档控件接入-2026-09-20.md) | +| Status | accepted | +| Owner | 当前任务 Agent | + +## 修改边界 + +- 在 `ProjectSupervisorView.tsx` 扩展既有控件排的适用范围,直接复用 `ConversationModelSelect` 与 `ComposerReasoningEffortSelect`。素材引用、语音、消息队列和停止按钮仍按原 GameAgent 条件显示。 +- 策划发送、澄清、审批和重试回调保持原样,不新增模型校验和提交门禁;GameAgent 的原校验保持不变。 +- 必要时局部调整策划宿主 CSS,避免控件换行或弹层裁切。组件内部逻辑保持不变。 +- 在现有前端测试体系补齐策划集成场景,回归已有 GameAgent 控件用例。 +- 不修改 Rust、模型生效逻辑、配置默认值、Provider 或 GameAgent 组件算法。 + +## 实现顺序 + +1. 核对共享对话容器,接入同一组控件,保留原提交路径。 +2. 补充策划控件读写、保存失败和忙态测试,回归原策划和 GameAgent 行为。 +3. 运行定向测试和类型检查,检查宽窄布局,回写证据与未验证项。 + +## 验证命令 + +- `npm test -- apps/ai-game-creator-shell/tests/appSurface.test.ts`,先按用例名称过滤控件及相关策划场景。 +- 策划宿主集成用例使用现有 Vitest / Testing Library,按实际测试文件定向运行。 +- `npm run ai-game-creator-shell:typecheck` +- `npm run check:doc-index` +- `npm run check:encoding` +- `git diff --check` + +## 风险与回滚点 + +- 防止扩大 `directCodex` 条件时带入语音、队列或改变 GameAgent 行为:仅共享控件排,保留其它分支。 +- 模型目录失败通过原选择器反馈,不给策划宿主增加前置检查,也不改造控件已有逻辑。 +- 本次回滚仅撤回前端接入、相关用例和文档,不涉及持久化数据迁移。 +- 时间盒:一个工作时段内先完成接入与定向测试,随后检查类型和布局;仅影响里程碑验收的发现纳入修复。 +- 当前已知限制:策划旧会话仍可能使用创建时模型;本次不将控件读写成功视为运行时已切换模型。 + +## 验收证据 + +| 项目 | 结果 | +| --- | --- | +| 源码边界核对 | 两个控件文件、策划动作回调、GameAgent 提交校验及 Rust 均无修改;仅扩展控件排适用条件与策划布局 | +| 定向 ESLint | `ProjectSupervisorView.tsx`、`design-agent.suite.ts`、`harness.ts` 通过 | + +定向测试命令:`npm test -- apps/ai-game-creator-shell/tests/appSurface.test.ts -t 'Design Agent|design session|clarification free text|reasoning effort control|selecting the model|model dropdown|chat composer an inset|current turn reasoning|historical reasoning'`。 + +用户已授权提交第一步、进入第二步。 diff --git a/docs/project-memory/plans/【里程碑】策划Agent回合模型选择生效-2026-09-20.md b/docs/project-memory/plans/【里程碑】策划Agent回合模型选择生效-2026-09-20.md new file mode 100644 index 000000000..6b43a4417 --- /dev/null +++ b/docs/project-memory/plans/【里程碑】策划Agent回合模型选择生效-2026-09-20.md @@ -0,0 +1,48 @@ +# 策划 Agent 回合模型选择生效 + +| 字段 | 值 | +| --- | --- | +| Version | 1.0 | +| Status | implemented(待验收) | +| Date | 2026-09-20 | +| Parent Spec | [策划 Agent 生产迁移与工作区浏览方案 §4.1](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md#41-策划对话模型与推理档选择) | + +## 目标 + +策划已有会话在后续执行时真正采用控件保存的模型和推理档,执行途中保持选择稳定,恢复不破坏既有工具副作用边界。 + +## 范围 + +- 新会话、旧会话后续消息、回答澄清、阶段审批继续和用户主动重试的选择生效。 +- 同一次执行中的工具循环、自动重试固定使用开始时的选择。 +- 活动回合自动恢复所需的最小模型、推理档快照及旧会话缺字段读取。 +- 模型切换保留策划上下文、阶段、审批和产物。 + +## 不在范围内 + +- 不改变 GameAgent Runtime 或既有配置控件算法。 +- 不调整模型目录、默认档位、供应商协议、提示词和阶段规则。 +- 不建立 Agent 专属设置、通用快照框架、历史转换器或平行账本。 + +## 依赖与前置条件 + +- [控件接入里程碑](./【里程碑】策划Agent模型与推理档控件接入-2026-09-20.md) 已验收。 +- 主规范和本里程碑已评审,实施前编写仅覆盖本步的实现计划。 +- 生效时机、主动重试与自动恢复的区分遵循主规范,不通过重建会话实现切换。 + +## 验收标准 + +- [ ] 新策划会话和旧策划会话下一次执行都使用当前已保存选择;旧模型不再永久覆盖新选择。 +- [ ] 发送、澄清、审批继续与主动重试的实际 Provider 请求使用新选择。 +- [ ] 执行中改配置不影响本次后续工具请求或瞬态自动重试,下一次用户执行才生效。 +- [ ] 自动恢复优先使用已有活动回合快照;旧记录缺推理档时按主规范补齐,不重复已执行工具副作用。 +- [ ] 切换后上下文、阶段、产物和审批身份保留,纯读取不改历史模型信息。 +- [ ] 配置/Provider 失败沿用可见错误,不静默降级、换模型或清空历史。 +- [ ] GameAgent 既有选择和运行行为通过兼容回归,没有借机修正其本征不足。 + +## 证据要求 + +- 自动化:本地 Provider fixture 捕获请求模型和推理档;覆盖跨工具调用、自动重试、用户重试、审批/澄清继续及旧会话恢复;运行相关 Rust 定向测试、必要类型检查、编码和文档索引检查。 +- 运行时:在现有策划项目选择另一模型及推理档,触发下一次执行核对实际请求;真实供应商是否接受跨模型历史需按环境记录实测或未验证。 +- 边界:验证恢复幂等和凭据不进入新增快照;无需新增通用权限或供应商测试体系。 +- 全部验收后将主规范提案改为当前行为,更新稳定项目记忆并删除本次已完成临时计划。 diff --git a/docs/project-memory/plans/【里程碑】策划Agent模型与推理档控件接入-2026-09-20.md b/docs/project-memory/plans/【里程碑】策划Agent模型与推理档控件接入-2026-09-20.md new file mode 100644 index 000000000..692ae4ba8 --- /dev/null +++ b/docs/project-memory/plans/【里程碑】策划Agent模型与推理档控件接入-2026-09-20.md @@ -0,0 +1,53 @@ +# 策划 Agent 模型与推理档控件接入 + +| 字段 | 值 | +| --- | --- | +| Version | 1.0 | +| Status | accepted(用户已授权提交、进入第二步) | +| Date | 2026-09-20 | +| Parent Spec | [策划 Agent 生产迁移与工作区浏览方案 §4.1](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md#41-策划对话模型与推理档选择) | + +## 目标 + +策划对话复用已有模型和推理档控件,能够读取和保存全局选择,保持 GameAgent 兼容性。 + +## 范围 + +- 输入区域中控件的显隐、位置、策划面板布局与必要的宿主接线。 +- 复用原有目录、默认模型、保存和错误提示,不复制逻辑。 +- 策划发送、澄清、审批继续和主动重试保持原流程;不新增模型可用性检查或提交门禁。 +- 重新进入策划时显示保存值;执行中可以调整后续选择,但原输入与提交忙态维持不变。 + +## 不在范围内 + +- 不修改策划 Provider 的模型选择和推理档采样逻辑,不声称旧会话已能切模型。 +- 不检查、修复或重构 GameAgent 组件本征不足,不引入通用缓存、同步、保存、下拉或配置框架改造。 +- 不为策划引入队列、语音或素材引用,不更改默认推理档。 + +## 依赖与前置条件 + +- 主规范本节与本里程碑完成评审。 +- 实施前仅为本里程碑编写实现计划,确认现有 GameAgent 对应回归用例与策划宿主入口。 +- 本步作为内部接入结果;第二步完成前不单独发布为完整可切模型功能。 + +## 验收标准 + +- [ ] 策划入口显示原模型及推理档控件,没有重复实现或第二份设置。 +- [ ] 选择走原保存通道;重新进入显示已保存值;保存失败显示原有错误反馈。 +- [ ] 策划提交和报错流程保持原样,没有新增模型检查;原控件内部行为不改造。 +- [ ] 策划忙态、待审批/澄清行为保持;新增布局在宽/窄面板可操作。 +- [ ] GameAgent 原控件的显示、选择、发送校验、忙态和运行行为通过相关回归。 +- [ ] 交付明确记录旧策划会话仍沿用旧模型,留待下一里程碑解决。 + +## 证据要求 + +- 自动化:现有界面测试中增加策划入口的集成场景,复用 GameAgent 回归;运行 AGC 类型检查、文档索引、编码和 diff 检查。 +- 运行时:桌面与窄面板选择、保存、重新进入和一次策划发送 smoke;缺失环境如实标注。 +- 边界:只验证接入所需的失败和忙态,不扩展为现有组件全量审计。 +- 通过本步验收后,才准备并执行模型生效里程碑的实现计划。 + +## 当前交付 + +已接入原控件及策划布局,按用户最终要求保留策划提交、审批、澄清、重试与报错流程,没有新增模型检查。原控件与 GameAgent 的提交逻辑未修改;旧策划会话固定模型的限制仍由第二步解决。 + +新增三条控件集成用例(保存重进、运行中选择、保存失败反馈)。用户已授权提交第一步、进入第二步。 diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 475c49840..acd604732 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -6,6 +6,8 @@ ## 2026-09-20 Godot 编辑器执行接入 +原生引导采用固定版本的官方 `godot-cpp` 和 MSVC x64 构建,绑定及 C++ runtime 静态链接。依赖归档和缓存源码须核验,安装目录仍只分发原生载荷及许可。EDITOR 阶段动态加载/卸载时显式清理 C++ 实例绑定与单例包装,保留纯 GDScript 的异步执行和原有协议;执行权限、项目身份与缓存归属继续由现有宿主处理。 + 可用性边界按引擎区分:Cocos/Unity 保持不按工程类型过滤,Godot 仍绑定当前 Godot 项目,切项目撤销旧插件上下文;前端统一根据宿主投影启动插件。Runtime 工具目录只对 Godot 追加项目条件,编辑器说明沿用外置提示词及审核 Skill 参考。 Godot 编辑器操控复用既有 AGC 插件宿主、EditorAdapter、Runner 和不确定执行回执合同,编辑器实现留在 `plugins/agc-godot-editor`。用户选择 DLL 原件随 AGC 安装资源分发,并确认按编辑器实例在 AGC 私有缓存准备临时加载副本,以满足 Godot Windows 加载器的同目录 `~DLL` 写入要求;项目内不复制 DLL,只用受管 `.gdextension` 引导。Godot 自动 UID 伴生文件必须记录归属并在确认卸载后按内容匹配清理。工作区根不迁移到 Godot 子目录,原始项目配置与场景只通过明确编辑操作修改。完整合同及验证范围见 [Godot 编辑器插件接入](<../../technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md>)。 diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index 0089a2ea1..c9b655161 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -1,9 +1,9 @@ # 踩坑与排障记录 -## Godot 原生插件在 MSVC C 模式下的对齐声明 +## Godot C++ 扩展构建与对象生命周期 -- `native.c` 若首先报 `max_align_t` 语法错误,后面的 `Storage`、`retained_script` 等未声明通常是连带错误。MSVC C 模式不提供该类型;ABI 存储使用 C11 `_Alignas(16)` 显式对齐并保持 128 字节容量,通过实际 MSVC DLL 构建验证,不逐条修补连带错误。 -- `No C compiler found` 则属于开发环境问题:先初始化 Visual Studio x64 开发环境,同时设置 PATH、INCLUDE 与 LIB,再运行构建。只把 `cl.exe` 所在目录加到 PATH 不足以提供头文件和链接库。 +- 原生引导通过官方 `godot-cpp` 管理 Variant、String 和 Ref,不自行维护 ABI 存储。Godot 类型必须在扩展终止回调内释放,不能依赖 DLL 静态对象析构;桥节点可能已经退出,应按实例 ID 核验存活再回调。 +- 正式 Windows 构建使用 CMake 的 Visual Studio x64 generator,并实际验证 MSVC 编译;不能用 GCC 成功替代 MSVC 验收。固定官方归档按 SHA256 校验,缓存源码被修改时拒绝构建并保留证据。 ## Rust 同步回调的测试记录按线程隔离 diff --git a/docs/project-memory/shared-memory/team-conventions.md b/docs/project-memory/shared-memory/team-conventions.md index 24df4716a..db96020cc 100644 --- a/docs/project-memory/shared-memory/team-conventions.md +++ b/docs/project-memory/shared-memory/team-conventions.md @@ -22,6 +22,8 @@ - 策划 Agent 的顾问态由用户指示驱动,不自主推进项目、主动安排下一步或提交阶段审批;完成单次请求不结束顾问态。五个策划阶段的审批用于检阅已完成产物,关键选择先问询;过程文档按需记录且不重复正式正文。顶层设计按需保留易混淆方向及排除理由,提示词精简应保留这些行为与设计边界。详见策划 Agent 生产迁移与工作区浏览方案。 +- 策划 Agent 复用现有模型/推理档控件,宿主不另加模型检查或自动换模型。用户发起执行时采样全局选择,同轮工具循环和自动重试固定使用回合快照;自动恢复复用该快照,旧记录保留已知模型并补齐一次推理档。只持久化模型和档位,不保存连接凭据;GameAgent 保持原逻辑。详见策划 Agent 生产迁移与工作区浏览方案 §4.1。 + - AGC 思考与执行入口共用共享单行摘要骨架;Markdown 在展开正文走既有安全渲染,折叠预览使用纯文本。耗时统一复用中文时分秒格式(不足一分钟一位小数,达到分钟后整数秒),格式化与各层计时边界分离。过程行在运行中和完成后的折叠层内保持同一紧凑间距;失败状态按明确终态与非零退出码呈现红色。 - Direct 对话计时区分条目展示时间与生命周期事件时间:整轮用用户发送到明确终态的跨度,工具用各自开始/完成边界;运行时用 100ms 叶子时钟刷新一位小数,终态冻结,旧历史缺边界不推测。不得用整秒时间的大小比较取代 Thread Manager 的事件顺序判定新回合。 diff --git a/docs/technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md b/docs/technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md index 12c399c5e..722fcbb55 100644 --- a/docs/technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md +++ b/docs/technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md @@ -33,7 +33,10 @@ DLL 原件随 AGC 安装包放在插件资源目录中;Godot Windows 加载器 ## 分发与描述文件 -- Windows 原生构建使用 x64 C11 编译器;MSVC 需先初始化 Visual Studio 的 x64 开发环境,以同时提供 PATH、INCLUDE 与 LIB。ABI 临时存储使用 128 字节、C11 `_Alignas(16)` 显式对齐,不依赖 MSVC C 模式未提供的 `max_align_t`;定向验证运行 `plugins/agc-godot-editor/native/gdextension/build.ps1 -Compiler cl.exe`。 +- 原生引导使用官方 `godot-cpp` 的 C++ 类型和初始化接口,不自行声明 Variant 存储或直接装配 ABI 函数指针。绑定源码固定到 `godot-4.5-stable` 的 `e83fd0904c13356ed1d4c3d09f8bb9132bdc6b77`,以该版本的稳定 API 构建并在 Godot 4.7.2 验证;产品最低版本仍为 4.7,因为嵌入脚本使用该版本能力。Windows x64 构建使用 Visual Studio C++、CMake 和 Python,静态链接绑定及 C++ runtime,用户无需这些构建工具。 +- 构建仅从已固定的官方归档获取绑定源码,并核对 SHA256;下载和生成内容只进入 `.build/`。CMake 构建包含引导源码、嵌入脚本、绑定版本/归档摘要和构建配置的身份指纹。许可证与来源继续随 DLL 分发,安装包不包含 SDK、源码缓存、生成绑定或构建工具。 +- C++ 状态仅在扩展有效期间持有 GDScript 引用和桥节点身份;终止回调先停用仍存活的桥,再释放绑定对象,不能让静态 Godot 对象析构晚于绑定退出。延迟 bootstrap、原生卸载、Node 已退出及同 PID 重连均须实测。受管文件、会话身份、协议、执行回执与不确定阻断沿用现有合同。 +- EDITOR 阶段晚加载不会取得 CORE 阶段终止回调;引导终止时须通过官方绑定接口解除 Node/GDScript 的实例包装回调,并完成单例包装清理。只移除 C++ 包装,不同步销毁仍在 GDScript 调用栈或等待 `queue_free` 的引擎对象;先用 Variant 保活脚本,再解除 Ref 和绑定,避免卸载 DLL 后跳到失效回调。 - 安装资源布局为 `plugins/agc-godot-editor/native/gdextension/bin/win-x64/agc_godot_editor.dll`,邻接元数据记录协议、构建身份和 DLL SHA256。开发模式允许宿主提供仓库插件目录中的同结构产物;RPC 不接受自定义 DLL 候选。 - 缓存根仅由宿主提供,为其私有配置目录下的 `godot-editor-runtime`;按 `PID + startedFileTime + buildId` 隔离,所有路径分量受控且拒绝链接/reparse point。复制前验证安装原件及元数据,缓存已有文件必须匹配来源、归属及 SHA,不能加载被替换的同名文件。受管描述同时保留原件与加载副本身份,重启恢复不得把工程给出的任意 DLL 路径当作受信任来源。 @@ -107,11 +110,13 @@ Windows x64、Godot 4.7.2 标准编辑器的本地实现验收通过。证据保 ### 复验入口 -从仓库根运行,原生构建要求 Windows x64 C 编译器。先把 `AGC_GODOT_TEST_EXECUTABLE` 设置为待验证的标准 Godot 编辑器绝对路径;未设置时 headless 测试会跳过,不能视为实机通过。 +从仓库根运行,原生构建要求 Visual Studio 2022 C++ x64、CMake 3.25 及以上和 Python 3;通过 Visual Studio generator 自动选择完整编译环境。首次构建需访问固定的官方归档,校验后的依赖缓存支持离线复用;`build.ps1` 可用 `-CMake`、`-Python` 指定构建工具。先把 `AGC_GODOT_TEST_EXECUTABLE` 设置为待验证的标准 Godot 编辑器绝对路径;未设置时 headless 测试会跳过,不能视为实机通过。 ```powershell powershell -NoProfile -File plugins/agc-godot-editor/native/gdextension/build.ps1 +python -X utf8 -B plugins/agc-godot-editor/native/gdextension/tests/test_dependencies.py node --test plugins/agc-godot-editor/native/gdextension/tests/native-smoke.test.mjs +node --test plugins/agc-godot-editor/native/gdextension/tests/guide-examples.test.mjs cargo test --locked --manifest-path plugins/agc-godot-editor/native/godot-editor-bridge/Cargo.toml npm run agc:plugins:test cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --features cocos-editor-execute,unity-editor-execute,godot-editor-execute godot @@ -124,3 +129,9 @@ git diff --check ``` 真实 GUI 使用 `native/godot-editor-bridge/examples/live_smoke.rs`;安装位置变更使用同目录的 `install_location_smoke.rs`。二者要求显式传入自有可丢弃工程、已打开编辑器 PID、可信安装 DLL、工程外私有缓存及 `--allow-fixture-mutations`,具体参数见源码用法。多实例验证分别传入两个工程和 PID,通过 `live_smoke` 的 `--hold-ms` 让加载时间重叠,同时核验原生模块路径。Runner 复验须经正式长度前缀 RPC、完整 ACK 和私有配置恢复路径,不能用原生示例替代 Runner 证据。 + +### C++ 引导验收边界 + +官方 C++ 绑定版已通过实际 MSVC 构建、原生/指南 headless 回归、Rust 缓存与连接回归、受管资源 staging 校验,以及同一 Godot 4.7.2 GUI 进程中的首次加载、执行、卸载和重新聚焦后的重连。DLL 的导入依赖只有 KERNEL32,生成 SDK/编译缓存不进入 staging;重复构建命中同一载荷身份,损坏归档和改动过的依赖缓存拒绝构建。验证中首次创建的空工程由 Godot 补写版本特征,按编辑器初始化后的基线确认插件运行不修改原有工程文件。 + +GUI 自动聚焦若未触发扫描,会按原合同返回未派发错误;重新聚焦后再连接,不重放未知执行。此次 C++ 替换未重新运行完整 AGC 发布构建、真实 Provider 或安装包 UI 验证,前述旧版本证据不代替这些验收。 diff --git a/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md b/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md index c2801edee..45c4755bf 100644 --- a/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md +++ b/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md @@ -116,7 +116,63 @@ Runtime 不维护文档版本号,不解析文档版本,不提供版本回退 会话/回合/工具调用身份用于生产恢复和重复请求处理,与 Agent 自行写在策划文档头部的版本号无关。 -策划会话在创建时保存入口选择的 AGC 模型目录 ID(例如 `quality`、`fast`),同一会话后续回合沿用该 ID;客户端不保存或推断上游真实模型名。官方 `platform-llm` 直连 api-server 时携带 AGC 客户端标记,由 api-server 根据模型目录解析实际模型,不能在客户端硬编码某个上游模型替代目录选择。 +策划每次用户发起执行时采用客户端当前保存的模型和推理档,保存在当前回合中;同一执行内的工具调用与自动重试保持该选择,后续用户执行重新读取。官方模式保存 AGC 模型目录 ID(例如 `quality`、`fast`),自定义模式保存已选择的型号;客户端不推断官方上游真实模型名。官方 `platform-llm` 直连 api-server 时携带 AGC 客户端标记,由 api-server 根据模型目录解析实际模型,不能在客户端硬编码某个上游模型替代目录选择。 + +### 4.1 策划对话模型与推理档选择 + +**交付结果**:策划 Agent 对话复用 GameAgent 的模型、推理档选择控件及配置通道,用户的新选择对后续策划回合实际生效,并保持 GameAgent 原有行为兼容。 + +本节是本次变更的唯一主规范。控件接入已完成并提交,运行时模型生效逻辑已实现、待验收。拆分与验收见 [控件接入里程碑](../project-memory/plans/【里程碑】策划Agent模型与推理档控件接入-2026-09-20.md) 和 [模型生效里程碑](../project-memory/plans/【里程碑】策划Agent回合模型选择生效-2026-09-20.md)。 + +#### 范围与非目标 + +- 必须项:复用已有控件及客户端配置读写;补齐策划入口;修正旧策划会话固定使用创建时模型的行为;验证 GameAgent 兼容性。 +- 风险项:界面选择与实际请求不一致、执行中途切换配置、恢复旧会话,以及策划窄面板新增控件的布局。 +- 可选项:无。发现与上述验收无关的问题,只记录发现,不扩展本次实现。 +- 明确不做:不评估或重构 GameAgent 已有控件的本征不足,不重做模型目录、缓存、配置同步、下拉交互、通用保存队列或错误处理;不调整 GameAgent Runtime、推理默认值、供应商适配、提示词或阶段审批规则;不新建 Agent 专属设置、模型管理页、配置框架或测试框架。 +- 优先在现有共享对话容器中复用同一组组件,不复制控件源码,不因新增一个使用方迁移整套配置型组件。若需要局部接口扩展,默认调用必须保持 GameAgent 现有行为。 + +#### 控件和配置合同 + +1. 策划对话输入框附近显示与 GameAgent 相同的模型和推理档控件,读取、选项、保存、错误反馈沿用已有能力;只调整策划宿主必要的显隐和布局。按用户确认,控件保持原样,不给策划发送、审批、澄清或重试新增模型可用性检查,也不以模型目录状态新增提交门禁;GameAgent 已有提交逻辑保持原样。 +2. 继续使用客户端全局模型选择与全局推理档,不新增第二份策划设置。它们是客户端偏好,可能影响其它后续对话;进入或重开策划界面时显示当前保存值。既有 GameAgent 配置解析保持不变,不承诺新增跨窗口实时同步。 +3. 策划运行时最终以选择器保存的全局模型和推理档作为本次用户选择;策划专属底层配置不得在这两个字段上静默覆盖选择。连接、鉴权、超时等其余字段继续按既有生产配置解析,不清理或改写用户其它配置。 +4. 模型的官方目录别名、自定义模型目录、默认项跟随及失效项处理复用已有能力;不新增供应商能力探测或模型自动降级。推理档的枚举与默认值维持现状。 +5. 可以在执行中修改后续选择;不会中断或重启正在执行的策划回合。策划保留原有输入、发送、审批和澄清忙态规则,不引入 GameAgent 的消息队列、素材引用或语音功能。 + +#### 生效边界 + +| 触发 | 目标行为 | +| --- | --- | +| 首次发送、后续普通发送 | 读取最新已保存的选择并开始新回合,不新增提交前模型检查 | +| 回答澄清、批准/拒绝阶段后实际继续调用 Provider | 同样使用本次继续前保存的选择;不更改审批结果和请求身份语义 | +| 用户主动点击失败重试 | 使用最新选择开始本次执行;继续现有工具恢复规则,不重复已完成副作用 | +| 同一执行内的工具循环、HTTP/流式瞬态自动重试 | 始终使用该次执行开始时确定的模型和推理档,不在每次 Provider 调用前重新采样这两个字段 | +| 纯读取、展示历史、未触发 Provider 的操作 | 不创建新回合,不覆盖历史使用的模型信息 | +| 进程中断后的自动续跑 | 优先沿用持久化的活动回合模型和推理档;不把它当成用户重新选模型后的新回合,不重复文件副作用 | + +“后续回合生效”按上表定义,不以底层函数是否创建新 turn ID 为判断依据。无需重建会话或清空历史才能切模型,正式策划阶段、产物和上下文继续保留。 + +#### 失败、兼容与数据约束 + +- 控件保存失败和目录不可用沿用控件现有提示;策划发送、审批、澄清、重试和 Provider 报错流程保持原样。原控件内部的目录同步与默认模型处理不在本次改造范围,也不在策划宿主另加同类逻辑。 +- Provider 不接受所选模型或历史上下文时,沿用现有可见错误和重试;不静默换模型、清历史或另建跨模型上下文转换系统。 +- 已有设计会话无需离线迁移:下次用户发起执行时采用新选择。自动恢复的旧活动回合优先保留已有模型;若尚无推理档快照,使用当次有效配置补齐一次并固定,不伪称还原了历史档位。 +- 持久化在当前回合追加可缺省的 `modelSelection`,只含 `model` 和 `reasoningEffort`;已有会话 `modelId` 表示最近一次用户执行采用的模型,兼作旧活动回合恢复依据。旧记录缺字段可读;不保存完整配置、端点凭据、Token 或 API Key。不增加平行会话账本,不改模型目录 ID 与真实型号的边界。 +- 本次不涉及公开 HTTP API、OpenAPI 或 SpacetimeDB schema。若本地设计会话投影需要新增字段,同步其现有 Rust/TypeScript 定义和恢复用例。 + +#### 两步交付与验收 + +| 步骤 | 交付边界 | 完成证据 | +| --- | --- | --- | +| 第一步:控件接入 | 策划宿主显示并使用原控件,选择写入现有全局配置;保留策划原提交流程;不改策划请求的模型解析与快照逻辑 | 策划控件读写、忙态与失败提示定向测试;GameAgent 相关现有用例;宽/窄面板 smoke | +| 第二步:模型生效 | 在策划执行边界采样并固定模型与推理档,旧会话下次执行采用新选择,自动恢复保留活动回合选择 | 本地 Provider fixture 验证真实请求字段、跨工具调用一致性、重试与恢复;界面到请求 smoke;GameAgent 兼容回归 | + +第一步是内部可验收的接入结果,不能宣称“策划旧会话切模型已生效”,也不能作为完整功能单独发布。第二步验收前保持这一已知限制明确。 + +两个步骤分别形成最小闭环;检查点分别为“控件与兼容验收”和“请求与恢复验收”。实现中的新增发现只有影响本节交付判据时才扩大范围。每步先用一个工作时段完成定向实现与验证;超过时段仍未闭环时,说明剩余阻碍并重估,不以顺手改造组件扩大任务。 + +验收至少覆盖:保存后重新进入策划显示一致;旧会话切换模型后实际请求改变;当前执行不被中途改档;下一次发送/澄清/审批继续/主动重试生效;自动恢复不重复工具副作用;GameAgent 原有选择、发送和运行行为不回归。真实 Provider 或桌面环境缺失时明确记为未验证,不用 fixture 冒充实机结果。 ## 5. Agent Runtime diff --git a/plugins/README.md b/plugins/README.md index 2517e62e9..6ac74a8c1 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -83,7 +83,8 @@ feature 会构建自包含 Attach helper,并只将运行文件与许可放入 [Unity 插件接入](../docs/technical/【技术方案】AGC Unity编辑器插件接入-2026-09-18.md)。 Godot 插件通过 `godot-editor-execute` feature 构建并校验 GDExtension 载荷,只分发 -运行入口、DLL、元数据及许可。构建机需要 Windows x64 C 工具链;DLL 原件留在安装资源, +运行入口、DLL、元数据及许可。原生引导使用固定版本的官方 `godot-cpp`;构建机需要 +Visual Studio C++ x64、CMake 和 Python,首次构建下载并校验绑定源码。DLL 原件留在安装资源, 每个编辑器的临时加载副本放在 AGC 私有缓存。连接时维护工程内受管 `.gdextension` 引用及其 UID,通过 Godot 聚焦扫描首次加载。文件归属、真实执行和卸载规则见 [Godot 插件接入](<../docs/technical/【技术方案】AGC Godot编辑器插件接入-2026-09-20.md>)。 diff --git a/plugins/agc-godot-editor/native/gdextension/CMakeLists.txt b/plugins/agc-godot-editor/native/gdextension/CMakeLists.txt new file mode 100644 index 000000000..a18da16a9 --- /dev/null +++ b/plugins/agc-godot-editor/native/gdextension/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.25) +project(agc_godot_editor LANGUAGES CXX) +if(NOT MSVC OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "Godot editor payload requires MSVC x64") +endif() +find_package(Python3 REQUIRED COMPONENTS Interpreter) +set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded CACHE STRING "Static runtime" FORCE) +set(GODOTCPP_TARGET editor CACHE STRING "Editor bindings" FORCE) +set(GODOTCPP_BUILD_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/build-profile.json" CACHE FILEPATH "Minimal bindings" FORCE) +set(GODOTCPP_USE_STATIC_CPP ON CACHE BOOL "Static runtime" FORCE) +set(GODOTCPP_USE_HOT_RELOAD OFF CACHE BOOL "Explicit unload/reload only" FORCE) +set(GODOTCPP_ENABLE_TESTING OFF CACHE BOOL "Do not package upstream tests" FORCE) +if(NOT EXISTS "${AGC_GODOT_CPP_SOURCE}/CMakeLists.txt") + message(FATAL_ERROR "Run build.ps1 to prepare the verified godot-cpp source") +endif() +add_subdirectory("${AGC_GODOT_CPP_SOURCE}" godot-cpp EXCLUDE_FROM_ALL SYSTEM) +add_library(agc_godot_editor SHARED src/native.cpp) +target_compile_features(agc_godot_editor PRIVATE cxx_std_17) +target_link_libraries(agc_godot_editor PRIVATE godot::cpp) +target_include_directories(agc_godot_editor PRIVATE "${AGC_GENERATED_DIR}") +target_compile_options(agc_godot_editor PRIVATE /W4 /WX /utf-8) +set_target_properties(agc_godot_editor PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/payload") diff --git a/plugins/agc-godot-editor/native/gdextension/build-profile.json b/plugins/agc-godot-editor/native/gdextension/build-profile.json new file mode 100644 index 000000000..44816da19 --- /dev/null +++ b/plugins/agc-godot-editor/native/gdextension/build-profile.json @@ -0,0 +1,3 @@ +{ + "enabled_classes": ["GDScript", "Node", "OS", "ProjectSettings"] +} diff --git a/plugins/agc-godot-editor/native/gdextension/build.ps1 b/plugins/agc-godot-editor/native/gdextension/build.ps1 index a85facb22..3d0aab4bd 100644 --- a/plugins/agc-godot-editor/native/gdextension/build.ps1 +++ b/plugins/agc-godot-editor/native/gdextension/build.ps1 @@ -1,84 +1,73 @@ -param([string]$Compiler = $env:AGC_GODOT_C_COMPILER) +param( + [string]$CMake = 'cmake.exe', + [string]$Python = 'python.exe', + [string]$Generator = 'Visual Studio 17 2022', + [ValidateRange(1, 32)][int]$Jobs = 4 +) $ErrorActionPreference = 'Stop' $root = $PSScriptRoot -if ([Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT) { throw 'Godot editor native payload requires Windows x64.' } -if (-not [Environment]::Is64BitProcess) { throw 'A 64-bit build host is required.' } -if (-not $Compiler) { - foreach ($candidate in @('gcc.exe', 'clang.exe', 'cl.exe')) { - $found = Get-Command $candidate -ErrorAction SilentlyContinue - if ($found) { $Compiler = $found.Source; break } - } +if ([Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT -or -not [Environment]::Is64BitProcess) { + throw 'Godot editor payload requires Windows x64.' } -if (-not $Compiler) { throw 'No C compiler found. Install a Windows x64 C toolchain or pass -Compiler.' } -$Compiler = (Get-Command $Compiler -ErrorAction Stop).Source -$build = Join-Path $root '.build' +$CMake = (Get-Command $CMake -ErrorAction Stop).Source +$Python = (Get-Command $Python -ErrorAction Stop).Source +$build = Join-Path $root '.build/msvc' +$generated = Join-Path $root '.build/generated' $output = Join-Path $root 'bin/win-x64' -New-Item -ItemType Directory -Path $build,$output -Force | Out-Null +New-Item -ItemType Directory -Path $generated,$output -Force | Out-Null $utf8 = [Text.UTF8Encoding]::new($false) -$inputs = @('src/native.c','src/bridge.gd','vendor/gdextension_interface.h','vendor/provenance.json','build.ps1') -$fingerprint = 'agc.godot.editor.v1/windows/x86_64/c11/O2' + "`n" -$fingerprint += 'compiler:' + (Get-FileHash -Algorithm SHA256 -LiteralPath $Compiler).Hash.ToLowerInvariant() + "`n" -foreach ($inputPath in $inputs) { $fingerprint += $inputPath + ':' + (Get-FileHash -Algorithm SHA256 -LiteralPath (Join-Path $root $inputPath)).Hash.ToLowerInvariant() + "`n" } -$hasher = [Security.Cryptography.SHA256]::Create() -try { $buildId = 'sha256:' + ([BitConverter]::ToString($hasher.ComputeHash($utf8.GetBytes($fingerprint))).Replace('-','').ToLowerInvariant()) } finally { $hasher.Dispose() } -$existingDll = Join-Path $output 'agc_godot_editor.dll' -$existingMetadata = Join-Path $output 'metadata.json' -if ((Test-Path -LiteralPath $existingDll) -and (Test-Path -LiteralPath $existingMetadata)) { - try { - $existing = Get-Content -LiteralPath $existingMetadata -Raw | ConvertFrom-Json - $existingHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $existingDll).Hash.ToLowerInvariant() - if ($existing.protocol -eq 'agc.godot.editor.v1' -and $existing.buildId -eq $buildId -and $existing.sha256 -eq $existingHash -and $existing.entrySymbol -eq 'agc_godot_editor_init' -and $existing.platform -eq 'windows' -and $existing.arch -eq 'x86_64' -and $existing.minimumGodotVersion -eq '4.7') { - Write-Output "Native payload is current: $buildId" +$previousBytecode = $env:PYTHONDONTWRITEBYTECODE +try { + $env:PYTHONDONTWRITEBYTECODE = '1' + $dependency = & $Python -X utf8 (Join-Path $root 'prepare_dependencies.py') + if ($LASTEXITCODE -ne 0) { throw 'Pinned godot-cpp dependency verification failed.' } + & $CMake -S $root -B $build -G $Generator -A x64 "-DAGC_GODOT_CPP_SOURCE=$dependency" "-DAGC_GENERATED_DIR=$generated" "-DPython3_EXECUTABLE=$Python" + if ($LASTEXITCODE -ne 0) { throw 'Godot C++ configure failed; install Visual Studio C++ x64, CMake and Python.' } + $compilerRecords = @(Get-ChildItem -LiteralPath (Join-Path $build 'CMakeFiles') -Filter 'CMakeCXXCompiler.cmake' -Recurse -File) + if ($compilerRecords.Count -ne 1) { throw 'MSVC compiler identity is ambiguous.' } + $record = [IO.File]::ReadAllText($compilerRecords[0].FullName) + $compilerMatch = [regex]::Match($record, 'set\(CMAKE_CXX_COMPILER "([^"]+)"\)') + if (-not $compilerMatch.Success -or -not $record.Contains('set(CMAKE_CXX_COMPILER_ID "MSVC")')) { throw 'MSVC compiler identity was not verified.' } + $compiler = $compilerMatch.Groups[1].Value + $inputs = @('src/native.cpp','src/bridge.gd','CMakeLists.txt','build-profile.json','prepare_dependencies.py','vendor/provenance.json','vendor/LICENSE.txt','build.ps1') + $fingerprint = 'agc.godot.editor.v1/windows/x86_64/c++17/msvc/Release/static-crt' + "`n" + $fingerprint += 'compiler:' + (Get-FileHash -LiteralPath $compiler -Algorithm SHA256).Hash.ToLowerInvariant() + "`n" + $fingerprint += 'cmake:' + (Get-FileHash -LiteralPath $CMake -Algorithm SHA256).Hash.ToLowerInvariant() + "`n" + $fingerprint += 'configuration:' + (Get-FileHash -LiteralPath (Join-Path $build 'CMakeCache.txt') -Algorithm SHA256).Hash.ToLowerInvariant() + "`n" + $fingerprint += 'toolchain:' + (Get-FileHash -LiteralPath $compilerRecords[0].FullName -Algorithm SHA256).Hash.ToLowerInvariant() + "`n" + foreach ($relative in $inputs) { $fingerprint += $relative + ':' + (Get-FileHash -LiteralPath (Join-Path $root $relative) -Algorithm SHA256).Hash.ToLowerInvariant() + "`n" } + $hasher = [Security.Cryptography.SHA256]::Create() + try { $buildId = 'sha256:' + ([BitConverter]::ToString($hasher.ComputeHash($utf8.GetBytes($fingerprint))).Replace('-','').ToLowerInvariant()) } finally { $hasher.Dispose() } + $dll = Join-Path $output 'agc_godot_editor.dll' + $metadataPath = Join-Path $output 'metadata.json' + if ((Test-Path -LiteralPath $dll) -and (Test-Path -LiteralPath $metadataPath)) { + $existing = Get-Content -LiteralPath $metadataPath -Raw | ConvertFrom-Json + if ($existing.protocol -eq 'agc.godot.editor.v1' -and $existing.entrySymbol -eq 'agc_godot_editor_init' -and $existing.platform -eq 'windows' -and $existing.arch -eq 'x86_64' -and $existing.minimumGodotVersion -eq '4.7' -and $existing.buildId -eq $buildId -and $existing.sha256 -eq (Get-FileHash -LiteralPath $dll -Algorithm SHA256).Hash.ToLowerInvariant()) { + Write-Output "Native C++ payload is current: $buildId" return } - } catch { Write-Verbose 'Existing metadata could not be verified; rebuilding.' } -} -$script = [IO.File]::ReadAllBytes((Join-Path $root 'src/bridge.gd')) -$embedded = [Text.StringBuilder]::new() -[void]$embedded.AppendLine('/* Generated from src/bridge.gd; never reads a project-side script. */') -[void]$embedded.AppendLine('#define AGC_BUILD_ID "' + $buildId + '"') -[void]$embedded.AppendLine('static const unsigned char AGC_EMBEDDED_BRIDGE[] = {') -for ($index = 0; $index -lt $script.Length; $index += 32) { - $last = [Math]::Min($index + 31, $script.Length - 1) - [void]$embedded.AppendLine(($script[$index..$last] -join ',') + ',') -} -[void]$embedded.AppendLine('0};') -[IO.File]::WriteAllText((Join-Path $build 'embedded_bridge.h'), $embedded.ToString(), $utf8) -$previousTemp = $env:TEMP -$previousTmp = $env:TMP -$previousLocation = Get-Location -try { - $env:TEMP = $build - $env:TMP = $build - Set-Location -LiteralPath $build - $source = Join-Path $root 'src/native.c' - $vendor = Join-Path $root 'vendor' - $temporaryDll = Join-Path $build 'agc_godot_editor.dll' - $compilerName = [IO.Path]::GetFileName($Compiler).ToLowerInvariant() - if ($compilerName -eq 'cl.exe') { - & $Compiler /nologo /std:c11 /O2 /W4 /WX /LD /D_CRT_SECURE_NO_WARNINGS "/I$vendor" "/I$build" $source "/Fe:$temporaryDll" /link /Brepro - } else { - $flags = @('-std=c11','-O2','-Wall','-Wextra','-Werror','-shared') - if ($compilerName -eq 'gcc.exe') { $flags += @('-static-libgcc','-Wl,--no-insert-timestamp') } - & $Compiler @flags -I $vendor -I $build $source -o $temporaryDll } - if ($LASTEXITCODE -ne 0) { throw "Native compiler exited with $LASTEXITCODE" } - $dll = Join-Path $output 'agc_godot_editor.dll' - Copy-Item -LiteralPath $temporaryDll -Destination $dll -Force + $script = [IO.File]::ReadAllBytes((Join-Path $root 'src/bridge.gd')) + $embedded = [Text.StringBuilder]::new() + [void]$embedded.AppendLine('#define AGC_BUILD_ID "' + $buildId + '"') + [void]$embedded.AppendLine('static const unsigned char AGC_EMBEDDED_BRIDGE[] = {') + for ($index = 0; $index -lt $script.Length; $index += 32) { + $last = [Math]::Min($index + 31, $script.Length - 1) + [void]$embedded.AppendLine(($script[$index..$last] -join ',') + ',') + } + [void]$embedded.AppendLine('0};') + $header = Join-Path $generated 'embedded_bridge.h' + if (-not (Test-Path -LiteralPath $header) -or [IO.File]::ReadAllText($header) -ne $embedded.ToString()) { [IO.File]::WriteAllText($header, $embedded.ToString(), $utf8) } + & $CMake --build $build --config Release --target agc_godot_editor --parallel $Jobs + if ($LASTEXITCODE -ne 0) { throw 'Godot C++ MSVC build failed.' } + Copy-Item -LiteralPath (Join-Path $build 'payload/agc_godot_editor.dll') -Destination $dll -Force $metadata = [ordered]@{ - protocol = 'agc.godot.editor.v1' - buildId = $buildId - sha256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $dll).Hash.ToLowerInvariant() - platform = 'windows' - arch = 'x86_64' - entrySymbol = 'agc_godot_editor_init' - minimumGodotVersion = '4.7' + protocol = 'agc.godot.editor.v1'; buildId = $buildId + sha256 = (Get-FileHash -LiteralPath $dll -Algorithm SHA256).Hash.ToLowerInvariant() + platform = 'windows'; arch = 'x86_64'; entrySymbol = 'agc_godot_editor_init'; minimumGodotVersion = '4.7' } - [IO.File]::WriteAllText((Join-Path $output 'metadata.json'), ($metadata | ConvertTo-Json) + "`n", $utf8) - Write-Output "Built $dll" - Write-Output "Build identity: $buildId" + [IO.File]::WriteAllText($metadataPath, ($metadata | ConvertTo-Json) + "`n", $utf8) + Write-Output "Built C++ payload: $buildId" } finally { - Set-Location -LiteralPath $previousLocation - $env:TEMP = $previousTemp - $env:TMP = $previousTmp + $env:PYTHONDONTWRITEBYTECODE = $previousBytecode } diff --git a/plugins/agc-godot-editor/native/gdextension/prepare_dependencies.py b/plugins/agc-godot-editor/native/gdextension/prepare_dependencies.py new file mode 100644 index 000000000..08a1deb78 --- /dev/null +++ b/plugins/agc-godot-editor/native/gdextension/prepare_dependencies.py @@ -0,0 +1,91 @@ +"""Prepare only the pinned official SDK; never execute an unchecked archive.""" +import hashlib +import json +import os +from pathlib import Path, PurePosixPath +import re +import stat +import sys +import tempfile +import urllib.request +import zipfile + + +def plain(path): + for item in (path, *path.parents): + if item.exists() or item.is_symlink(): + info = item.lstat() + if item.is_symlink() or getattr(info, "st_file_attributes", 0) & 0x400: + raise ValueError(f"Dependency path cannot contain links: {item}") + + +def digest(data): + return hashlib.sha256(data).hexdigest() + + +def prepare(root): + provenance = json.loads((root / "vendor/provenance.json").read_text(encoding="utf-8")) + commit = provenance["commit"] + expected = provenance["archiveSha256"] + if not re.fullmatch(r"[a-f0-9]{40}", commit) or not re.fullmatch(r"[a-f0-9]{64}", expected): + raise ValueError("Invalid pinned dependency identity") + url = f"https://codeload.github.com/godotengine/godot-cpp/zip/{commit}" + if provenance["archiveUrl"] != url: + raise ValueError("Dependency URL must identify the pinned official repository") + cache = root / ".build/dependencies" + plain(cache) + cache.mkdir(parents=True, exist_ok=True) + archive = cache / f"{commit}.zip" + plain(archive) + if not archive.exists(): + with urllib.request.urlopen(url, timeout=60) as response: + data = response.read(32 * 1024 * 1024 + 1) + if len(data) > 32 * 1024 * 1024 or digest(data) != expected: + raise ValueError("Official godot-cpp archive SHA256 mismatch") + with tempfile.NamedTemporaryFile(dir=cache, delete=False) as output: + output.write(data) + temporary = Path(output.name) + os.replace(temporary, archive) + if digest(archive.read_bytes()) != expected: + raise ValueError("Cached godot-cpp archive SHA256 mismatch; cache was preserved") + source = cache / f"godot-cpp-{commit}" + plain(source) + source.mkdir(exist_ok=True) + expected_files = set() + with zipfile.ZipFile(archive) as bundle: + for entry in bundle.infolist(): + relative = PurePosixPath(entry.filename) + if (not relative.parts or relative.parts[0] != source.name or relative.is_absolute() + or ".." in relative.parts or "\\" in entry.filename or ":" in entry.filename): + raise ValueError("Unsafe dependency archive entry") + if stat.S_ISLNK(entry.external_attr >> 16): + raise ValueError("Dependency archive cannot contain symbolic links") + if entry.is_dir(): + continue + target = source.joinpath(*relative.parts[1:]) + if target in expected_files: + raise ValueError("Duplicate dependency archive entry") + plain(target) + expected_files.add(target) + content = bundle.read(entry) + if target.exists(): + if not target.is_file() or target.read_bytes() != content: + raise ValueError(f"Modified godot-cpp source cache was preserved: {target}") + else: + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(content) + for item in source.rglob("*"): + plain(item) + if item.is_file() and item not in expected_files: + raise ValueError(f"Unexpected dependency source cache entry: {item}") + if (source / "LICENSE.md").read_text(encoding="utf-8") != (root / "vendor/LICENSE.txt").read_text(encoding="utf-8"): + raise ValueError("Packaged godot-cpp license differs from pinned upstream license") + return source + + +if __name__ == "__main__": + try: + print(prepare(Path(__file__).resolve().parent)) + except (OSError, ValueError, KeyError, zipfile.BadZipFile) as error: + print(str(error), file=sys.stderr) + sys.exit(1) diff --git a/plugins/agc-godot-editor/native/gdextension/src/native.c b/plugins/agc-godot-editor/native/gdextension/src/native.c deleted file mode 100644 index c29455473..000000000 --- a/plugins/agc-godot-editor/native/gdextension/src/native.c +++ /dev/null @@ -1,258 +0,0 @@ -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#include -#include "gdextension_interface.h" -#include "embedded_bridge.h" - -/* Windows x64 ABI storage is deliberately oversized and 16-byte aligned. - * Explicit C11 alignment also works with MSVC C, which lacks max_align_t. - * Objects are constructed/destructed solely through the official interface. */ -typedef struct { _Alignas(16) unsigned char bytes[128]; } Storage; -static GDExtensionInterfacePrintWarning api_warning; -static GDExtensionInterfaceVariantCall api_call; -static GDExtensionInterfaceVariantDestroy api_destroy; -static GDExtensionInterfaceVariantGetType api_type; -static GDExtensionInterfaceGlobalGetSingleton api_singleton; -static GDExtensionInterfaceStringNameNewWithLatin1Chars api_name; -static GDExtensionInterfaceStringNewWithUtf8Chars api_string; -static GDExtensionInterfaceStringToUtf8Chars api_utf8; -static GDExtensionVariantFromTypeConstructorFunc from_object, from_string, from_name; -static GDExtensionTypeFromVariantConstructorFunc to_int, to_string; -static GDExtensionPtrDestructor destroy_name, destroy_string; -static Storage retained_script, retained_node; -static int script_live, node_live, started; - -static void report_failure(const char *operation, int code) { - char message[256]; - snprintf(message, sizeof(message), "AGC Godot editor bridge: %s failed (%d).", operation, code); - if (api_warning) api_warning(message, "agc_godot_editor", "native.c", 0, 0); -} - -static void name_variant(Storage *out, const char *text) { - Storage name; - api_name(&name, text, 0); - from_name(out, &name); - destroy_name(&name); -} - -static void string_variant(Storage *out, const char *text) { - Storage string; - api_string(&string, text); - from_string(out, &string); - destroy_string(&string); -} - -static int invoke(Storage *receiver, const char *method, - const GDExtensionConstVariantPtr *arguments, int count, Storage *out) { - Storage name; - GDExtensionCallError error = { GDEXTENSION_CALL_OK, 0, 0 }; - api_name(&name, method, 0); - api_call(receiver, &name, arguments, count, out, &error); - destroy_name(&name); - if (error.error != GDEXTENSION_CALL_OK) { - report_failure(method, (int)error.error); - return 0; - } - return 1; -} - -static int singleton_variant(Storage *out, const char *text) { - Storage name; - api_name(&name, text, 0); - GDExtensionObjectPtr object = api_singleton(&name); - destroy_name(&name); - if (!object) return 0; - from_object(out, &object); - return 1; -} - -static char *variant_utf8(Storage *value) { - if (api_type(value) != GDEXTENSION_VARIANT_TYPE_STRING) return NULL; - Storage string; - to_string(&string, value); - GDExtensionInt length = api_utf8(&string, NULL, 0); - char *text = NULL; - if (length >= 0 && length < 131072) { - text = (char *)malloc((size_t)length + 1); - if (text) { - api_utf8(&string, text, length); - text[length] = '\0'; - } - } - destroy_string(&string); - return text; -} - -static int plain_directory(const wchar_t *path) { - DWORD attrs = GetFileAttributesW(path); - return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) && - !(attrs & FILE_ATTRIBUTE_REPARSE_POINT); -} - -static int ensure_cache_directory(wchar_t *path, size_t capacity, const wchar_t *part) { - size_t length = wcslen(path), addition = wcslen(part); - if (length + addition + 2 >= capacity) return 0; - if (length && path[length - 1] != L'\\') path[length++] = L'\\'; - memcpy(path + length, part, (addition + 1) * sizeof(wchar_t)); - if (!CreateDirectoryW(path, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) return 0; - return plain_directory(path); -} - -static char *prepare_cache_path(void) { - Storage settings, argument, result; - if (!singleton_variant(&settings, "ProjectSettings")) return NULL; - string_variant(&argument, "res://"); - const GDExtensionConstVariantPtr args[] = { &argument }; - int ok = invoke(&settings, "globalize_path", args, 1, &result); - char *root_utf8 = ok ? variant_utf8(&result) : NULL; - api_destroy(&result); - api_destroy(&argument); - api_destroy(&settings); - if (!root_utf8) return NULL; - wchar_t path[32768]; - int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, root_utf8, -1, path, 32768); - free(root_utf8); - if (length < 4 || path[1] != L':') return NULL; - for (int index = 0; index < length; ++index) if (path[index] == L'/') path[index] = L'\\'; - /* Reject links/junctions in every existing directory, including project ancestors. */ - for (int index = 3; index < length; ++index) { - if (path[index] != L'\\' && path[index] != L'\0') continue; - wchar_t saved = path[index]; - path[index] = L'\0'; - int plain = plain_directory(path); - path[index] = saved; - if (!plain) return NULL; - } - if (!ensure_cache_directory(path, 32768, L".godot") || - !ensure_cache_directory(path, 32768, L"agc")) return NULL; - wchar_t suffix[96]; - swprintf(suffix, 96, L"\\editor-bridge-%lu.json", (unsigned long)GetCurrentProcessId()); - if (wcslen(path) + wcslen(suffix) + 1 >= 32768) return NULL; - wcscat(path, suffix); - DWORD attrs = GetFileAttributesW(path); - if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY))) return NULL; - int size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, path, -1, NULL, 0, NULL, NULL); - if (size <= 0) return NULL; - char *cache = (char *)malloc((size_t)size); - if (cache) WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, path, -1, cache, size, NULL, NULL); - return cache; -} - -static void release_references(void) { - if (node_live) { api_destroy(&retained_node); node_live = 0; } - if (script_live) { api_destroy(&retained_script); script_live = 0; } -} - -static int schedule_bridge(void) { - FILETIME creation, exit_time, kernel, user; - if (!GetProcessTimes(GetCurrentProcess(), &creation, &exit_time, &kernel, &user)) return 0; - ULARGE_INTEGER timestamp; - timestamp.LowPart = creation.dwLowDateTime; - timestamp.HighPart = creation.dwHighDateTime; - char started_file_time[32]; - snprintf(started_file_time, sizeof(started_file_time), "%llu", (unsigned long long)timestamp.QuadPart); - char *cache_path = prepare_cache_path(); - if (!cache_path) { report_failure("session_cache_path", 0); return 0; } - Storage classdb, class_arg, result, source; - if (!singleton_variant(&classdb, "ClassDB")) { free(cache_path); return 0; } - name_variant(&class_arg, "GDScript"); - const GDExtensionConstVariantPtr class_args[] = { &class_arg }; - int ok = invoke(&classdb, "instantiate", class_args, 1, &retained_script); - script_live = 1; - api_destroy(&class_arg); - api_destroy(&classdb); - if (!ok || api_type(&retained_script) != GDEXTENSION_VARIANT_TYPE_OBJECT) { free(cache_path); return 0; } - string_variant(&source, (const char *)AGC_EMBEDDED_BRIDGE); - const GDExtensionConstVariantPtr source_args[] = { &source }; - ok = invoke(&retained_script, "set_source_code", source_args, 1, &result); - api_destroy(&result); - api_destroy(&source); - if (!ok) { free(cache_path); return 0; } - ok = invoke(&retained_script, "reload", NULL, 0, &result); - int64_t reload_error = -1; - if (ok && api_type(&result) == GDEXTENSION_VARIANT_TYPE_INT) to_int(&reload_error, &result); - api_destroy(&result); - if (!ok || reload_error != 0) { free(cache_path); report_failure("bridge_compile", (int)reload_error); return 0; } - ok = invoke(&retained_script, "new", NULL, 0, &retained_node); - node_live = 1; - if (!ok || api_type(&retained_node) != GDEXTENSION_VARIANT_TYPE_OBJECT) { free(cache_path); return 0; } - Storage method, build, process_identity, cache; - name_variant(&method, "bootstrap"); - string_variant(&build, AGC_BUILD_ID); - string_variant(&process_identity, started_file_time); - string_variant(&cache, cache_path); - free(cache_path); - const GDExtensionConstVariantPtr deferred[] = { &method, &build, &process_identity, &cache }; - ok = invoke(&retained_node, "call_deferred", deferred, 4, &result); - api_destroy(&result); - api_destroy(&method); - api_destroy(&build); - api_destroy(&process_identity); - api_destroy(&cache); - return ok; -} - -static void initialize_bridge(void *userdata, GDExtensionInitializationLevel level) { - (void)userdata; - if (level != GDEXTENSION_INITIALIZATION_EDITOR || started) return; - started = 1; - if (!schedule_bridge()) release_references(); -} - -static void deinitialize_bridge(void *userdata, GDExtensionInitializationLevel level) { - (void)userdata; - if (level != GDEXTENSION_INITIALIZATION_EDITOR) return; - if (node_live && api_type(&retained_node) == GDEXTENSION_VARIANT_TYPE_OBJECT) { - Storage returned; - invoke(&retained_node, "native_deinitialize", NULL, 0, &returned); - api_destroy(&returned); - } - release_references(); -} - -__declspec(dllexport) GDExtensionBool agc_godot_editor_init( - GDExtensionInterfaceGetProcAddress get_proc_address, - GDExtensionClassLibraryPtr library, - GDExtensionInitialization *initialization) { - (void)library; - if (!get_proc_address || !initialization) return 0; -#define LOAD(variable, type, symbol) do { \ - GDExtensionInterfaceFunctionPtr raw_function = get_proc_address(symbol); \ - _Static_assert(sizeof(type) == sizeof(raw_function), "Windows function pointer ABI mismatch"); \ - memcpy(&(variable), &raw_function, sizeof(variable)); \ - if (!variable) return 0; \ -} while (0) - LOAD(api_warning, GDExtensionInterfacePrintWarning, "print_warning"); - LOAD(api_call, GDExtensionInterfaceVariantCall, "variant_call"); - LOAD(api_destroy, GDExtensionInterfaceVariantDestroy, "variant_destroy"); - LOAD(api_type, GDExtensionInterfaceVariantGetType, "variant_get_type"); - LOAD(api_singleton, GDExtensionInterfaceGlobalGetSingleton, "global_get_singleton"); - LOAD(api_name, GDExtensionInterfaceStringNameNewWithLatin1Chars, "string_name_new_with_latin1_chars"); - LOAD(api_string, GDExtensionInterfaceStringNewWithUtf8Chars, "string_new_with_utf8_chars"); - LOAD(api_utf8, GDExtensionInterfaceStringToUtf8Chars, "string_to_utf8_chars"); - GDExtensionInterfaceGetVariantFromTypeConstructor get_from; - GDExtensionInterfaceGetVariantToTypeConstructor get_to; - GDExtensionInterfaceVariantGetPtrDestructor get_destructor; - LOAD(get_from, GDExtensionInterfaceGetVariantFromTypeConstructor, "get_variant_from_type_constructor"); - LOAD(get_to, GDExtensionInterfaceGetVariantToTypeConstructor, "get_variant_to_type_constructor"); - LOAD(get_destructor, GDExtensionInterfaceVariantGetPtrDestructor, "variant_get_ptr_destructor"); -#undef LOAD - from_object = get_from(GDEXTENSION_VARIANT_TYPE_OBJECT); - from_string = get_from(GDEXTENSION_VARIANT_TYPE_STRING); - from_name = get_from(GDEXTENSION_VARIANT_TYPE_STRING_NAME); - to_int = get_to(GDEXTENSION_VARIANT_TYPE_INT); - to_string = get_to(GDEXTENSION_VARIANT_TYPE_STRING); - destroy_name = get_destructor(GDEXTENSION_VARIANT_TYPE_STRING_NAME); - destroy_string = get_destructor(GDEXTENSION_VARIANT_TYPE_STRING); - if (!from_object || !from_string || !from_name || !to_int || !to_string || !destroy_name || !destroy_string) return 0; - initialization->minimum_initialization_level = GDEXTENSION_INITIALIZATION_EDITOR; - initialization->userdata = NULL; - initialization->initialize = initialize_bridge; - initialization->deinitialize = deinitialize_bridge; - return 1; -} diff --git a/plugins/agc-godot-editor/native/gdextension/src/native.cpp b/plugins/agc-godot-editor/native/gdextension/src/native.cpp new file mode 100644 index 000000000..7d66c4c63 --- /dev/null +++ b/plugins/agc-godot-editor/native/gdextension/src/native.cpp @@ -0,0 +1,159 @@ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "embedded_bridge.h" + +namespace { +using namespace godot; + +// Godot 值的析构必须发生在官方绑定终止之前,不能依赖 DLL 静态析构顺序。 +struct BridgeState { + Ref script; + uint64_t node_id = 0; +}; +BridgeState *bridge = nullptr; + +bool plain_directory(const std::wstring &path) { + const DWORD attributes = GetFileAttributesW(path.c_str()); + return attributes != INVALID_FILE_ATTRIBUTES && + (attributes & FILE_ATTRIBUTE_DIRECTORY) && + !(attributes & FILE_ATTRIBUTE_REPARSE_POINT); +} + +bool append_cache_directory(std::wstring &path, const wchar_t *part) { + if (path.back() != L'\\') + path += L'\\'; + path += part; + if (!CreateDirectoryW(path.c_str(), nullptr) && + GetLastError() != ERROR_ALREADY_EXISTS) + return false; + return plain_directory(path); +} + +String session_cache_path() { + const String project_root = + ProjectSettings::get_singleton()->globalize_path("res://"); + const Char16String utf16 = project_root.utf16(); + static_assert(sizeof(wchar_t) == sizeof(char16_t), + "Windows UTF-16 path required"); + std::wstring path(reinterpret_cast(utf16.get_data()), + utf16.length()); + if (path.size() < 3 || path.size() > 32000 || path[1] != L':') + return {}; + for (wchar_t &character : path) + if (character == L'/') + character = L'\\'; + // 项目根及其所有祖先都须为普通本地目录,不经过链接或 junction。 + for (size_t index = 3; index <= path.size(); ++index) { + if (index == path.size() || path[index] == L'\\') { + if (!plain_directory(path.substr(0, index))) + return {}; + } + } + if (!append_cache_directory(path, L".godot") || + !append_cache_directory(path, L"agc")) + return {}; + path += + L"\\editor-bridge-" + std::to_wstring(GetCurrentProcessId()) + L".json"; + const DWORD attributes = GetFileAttributesW(path.c_str()); + if (attributes != INVALID_FILE_ATTRIBUTES && + (attributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY))) + return {}; + return String::utf16(reinterpret_cast(path.c_str())); +} + +bool schedule_bridge() { + FILETIME creation, exit_time, kernel, user; + if (!GetProcessTimes(GetCurrentProcess(), &creation, &exit_time, &kernel, + &user)) + return false; + ULARGE_INTEGER timestamp; + timestamp.LowPart = creation.dwLowDateTime; + timestamp.HighPart = creation.dwHighDateTime; + const String started = String::num_uint64(timestamp.QuadPart); + const String cache = session_cache_path(); + if (cache.is_empty()) + return false; + + bridge->script.instantiate(); + bridge->script->set_source_code( + String::utf8(reinterpret_cast(AGC_EMBEDDED_BRIDGE))); + if (bridge->script->reload() != OK) + return false; + const Variant instance = bridge->script->call("new"); + Node *node = Object::cast_to(static_cast(instance)); + if (!node) + return false; + bridge->node_id = node->get_instance_id(); + node->call_deferred("bootstrap", AGC_BUILD_ID, started, cache); + return true; +} + +void initialize_bridge(ModuleInitializationLevel level) { + if (level != MODULE_INITIALIZATION_LEVEL_EDITOR || bridge) + return; + bridge = new BridgeState; + if (!schedule_bridge()) { + UtilityFunctions::push_warning( + "AGC Godot editor bridge initialization failed"); + delete bridge; + bridge = nullptr; + } +} + +void deinitialize_bridge(ModuleInitializationLevel level) { + if (level != MODULE_INITIALIZATION_LEVEL_EDITOR) + return; + if (bridge) { + // bootstrap 失败或编辑器退出时 Node 可能先被销毁,不能保留悬空指针。 + if (Object *node = ObjectDB::get_instance(bridge->node_id)) { + const GDExtensionObjectPtr owner = node->_owner; + node->call("native_deinitialize"); + // GDScript 的 queue_free 晚于 DLL 卸载;只移除 C++ 包装的回调,不销毁引擎 + // Node。 + internal::gdextension_interface_object_free_instance_binding( + owner, internal::token); + } + // 脚本仍可能被当前 GDScript 调用栈引用。用 Variant 保活引擎对象,先释放 C++ + // Ref, 再解除 DLL 内的包装回调;保活值在本回调返回前销毁。 + const Variant script_lifetime = bridge->script; + const GDExtensionObjectPtr script_owner = + bridge->script.is_valid() ? bridge->script->_owner : nullptr; + bridge->script.unref(); + if (script_owner) + internal::gdextension_interface_object_free_instance_binding( + script_owner, internal::token); + delete bridge; + bridge = nullptr; + } + // 晚加载扩展只收到 EDITOR 生命周期,官方单例包装清理原本位于 CORE 终止阶段。 + ClassDB::deinitialize(GDEXTENSION_INITIALIZATION_CORE); +} +} // namespace + +extern "C" GDExtensionBool GDE_EXPORT +agc_godot_editor_init(GDExtensionInterfaceGetProcAddress get_proc_address, + GDExtensionClassLibraryPtr library, + GDExtensionInitialization *initialization) { + godot::GDExtensionBinding::InitObject init(get_proc_address, library, + initialization); + init.register_initializer(initialize_bridge); + init.register_terminator(deinitialize_bridge); + init.set_minimum_library_initialization_level( + godot::MODULE_INITIALIZATION_LEVEL_EDITOR); + return init.init(); +} diff --git a/plugins/agc-godot-editor/native/gdextension/tests/test_dependencies.py b/plugins/agc-godot-editor/native/gdextension/tests/test_dependencies.py new file mode 100644 index 000000000..06fbab88e --- /dev/null +++ b/plugins/agc-godot-editor/native/gdextension/tests/test_dependencies.py @@ -0,0 +1,73 @@ +import hashlib +import importlib.util +import json +from pathlib import Path +import sys +import tempfile +import unittest +import zipfile +from unittest.mock import patch + +sys.dont_write_bytecode = True +spec = importlib.util.spec_from_file_location("dependencies", Path(__file__).parents[1] / "prepare_dependencies.py") +dependencies = importlib.util.module_from_spec(spec) +spec.loader.exec_module(dependencies) + + +class DependencyTests(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.root = Path(self.temp.name) + self.commit = "a" * 40 + self.name = f"godot-cpp-{self.commit}" + self.archive = self.root / ".build/dependencies" / f"{self.commit}.zip" + self.archive.parent.mkdir(parents=True) + (self.root / "vendor").mkdir() + (self.root / "vendor/LICENSE.txt").write_bytes(b"MIT\r\n") + self.write_archive({"LICENSE.md": b"MIT\n", "src/core.cpp": b"verified"}) + + def write_archive(self, entries): + with zipfile.ZipFile(self.archive, "w") as output: + for name, content in entries.items(): + output.writestr(f"{self.name}/{name}", content) + provenance = {"commit": self.commit, + "archiveUrl": f"https://codeload.github.com/godotengine/godot-cpp/zip/{self.commit}", + "archiveSha256": hashlib.sha256(self.archive.read_bytes()).hexdigest()} + (self.root / "vendor/provenance.json").write_text(json.dumps(provenance), encoding="utf-8") + + def test_verified_archive_is_reusable_offline(self): + with patch("urllib.request.urlopen", side_effect=AssertionError("Unexpected network")): + source = dependencies.prepare(self.root) + self.assertEqual(source, dependencies.prepare(self.root)) + self.assertEqual((source / "src/core.cpp").read_bytes(), b"verified") + + def test_corrupt_archive_is_rejected_and_preserved(self): + self.archive.write_bytes(b"corrupt") + with self.assertRaisesRegex(ValueError, "SHA256 mismatch"): + dependencies.prepare(self.root) + self.assertEqual(self.archive.read_bytes(), b"corrupt") + + def test_modified_source_is_rejected_even_with_valid_archive(self): + source = dependencies.prepare(self.root) + (source / "src/core.cpp").write_bytes(b"modified") + with self.assertRaisesRegex(ValueError, "Modified godot-cpp"): + dependencies.prepare(self.root) + self.assertEqual((source / "src/core.cpp").read_bytes(), b"modified") + + def test_extra_source_is_rejected(self): + source = dependencies.prepare(self.root) + (source / "extra.cpp").write_text("unexpected", encoding="utf-8") + with self.assertRaisesRegex(ValueError, "Unexpected dependency"): + dependencies.prepare(self.root) + + def test_archive_paths_cannot_escape_on_windows_or_posix(self): + for name in ["../../escaped", "C:\\escaped", "..\\escaped"]: + with self.subTest(name=name): + self.write_archive({name: b"unexpected"}) + with self.assertRaisesRegex(ValueError, "Unsafe dependency"): + dependencies.prepare(self.root) + + +if __name__ == "__main__": + unittest.main() diff --git a/plugins/agc-godot-editor/native/gdextension/vendor/LICENSE.txt b/plugins/agc-godot-editor/native/gdextension/vendor/LICENSE.txt index 0e3ba08d6..eb446fe72 100644 --- a/plugins/agc-godot-editor/native/gdextension/vendor/LICENSE.txt +++ b/plugins/agc-godot-editor/native/gdextension/vendor/LICENSE.txt @@ -1,5 +1,6 @@ -Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). -Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. +# MIT License + +Copyright (c) 2017-present Godot Engine contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/plugins/agc-godot-editor/native/gdextension/vendor/gdextension_interface.h b/plugins/agc-godot-editor/native/gdextension/vendor/gdextension_interface.h deleted file mode 100644 index 8c34a4474..000000000 --- a/plugins/agc-godot-editor/native/gdextension/vendor/gdextension_interface.h +++ /dev/null @@ -1,3185 +0,0 @@ -/* Generated from official Godot 4.7.2-stable interface JSON. */ -/* Source commit: ed1daf0bf001b61586d9930840f2f1394092c079. */ -/* Copyright Godot contributors; see GODOT-LICENSE.txt. */ -#ifndef AGC_GODOT_GDEXTENSION_INTERFACE_H -#define AGC_GODOT_GDEXTENSION_INTERFACE_H -#ifndef __cplusplus -#include -#include - -typedef uint32_t char32_t; -typedef uint16_t char16_t; -#else -#include -#include - -extern "C" { -#endif - -typedef enum { - GDEXTENSION_VARIANT_TYPE_NIL = 0, - GDEXTENSION_VARIANT_TYPE_BOOL = 1, - GDEXTENSION_VARIANT_TYPE_INT = 2, - GDEXTENSION_VARIANT_TYPE_FLOAT = 3, - GDEXTENSION_VARIANT_TYPE_STRING = 4, - GDEXTENSION_VARIANT_TYPE_VECTOR2 = 5, - GDEXTENSION_VARIANT_TYPE_VECTOR2I = 6, - GDEXTENSION_VARIANT_TYPE_RECT2 = 7, - GDEXTENSION_VARIANT_TYPE_RECT2I = 8, - GDEXTENSION_VARIANT_TYPE_VECTOR3 = 9, - GDEXTENSION_VARIANT_TYPE_VECTOR3I = 10, - GDEXTENSION_VARIANT_TYPE_TRANSFORM2D = 11, - GDEXTENSION_VARIANT_TYPE_VECTOR4 = 12, - GDEXTENSION_VARIANT_TYPE_VECTOR4I = 13, - GDEXTENSION_VARIANT_TYPE_PLANE = 14, - GDEXTENSION_VARIANT_TYPE_QUATERNION = 15, - GDEXTENSION_VARIANT_TYPE_AABB = 16, - GDEXTENSION_VARIANT_TYPE_BASIS = 17, - GDEXTENSION_VARIANT_TYPE_TRANSFORM3D = 18, - GDEXTENSION_VARIANT_TYPE_PROJECTION = 19, - GDEXTENSION_VARIANT_TYPE_COLOR = 20, - GDEXTENSION_VARIANT_TYPE_STRING_NAME = 21, - GDEXTENSION_VARIANT_TYPE_NODE_PATH = 22, - GDEXTENSION_VARIANT_TYPE_RID = 23, - GDEXTENSION_VARIANT_TYPE_OBJECT = 24, - GDEXTENSION_VARIANT_TYPE_CALLABLE = 25, - GDEXTENSION_VARIANT_TYPE_SIGNAL = 26, - GDEXTENSION_VARIANT_TYPE_DICTIONARY = 27, - GDEXTENSION_VARIANT_TYPE_ARRAY = 28, - GDEXTENSION_VARIANT_TYPE_PACKED_BYTE_ARRAY = 29, - GDEXTENSION_VARIANT_TYPE_PACKED_INT32_ARRAY = 30, - GDEXTENSION_VARIANT_TYPE_PACKED_INT64_ARRAY = 31, - GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT32_ARRAY = 32, - GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT64_ARRAY = 33, - GDEXTENSION_VARIANT_TYPE_PACKED_STRING_ARRAY = 34, - GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY = 35, - GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY = 36, - GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY = 37, - GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY = 38, - GDEXTENSION_VARIANT_TYPE_VARIANT_MAX = 39, -} GDExtensionVariantType; - -typedef enum { - GDEXTENSION_VARIANT_OP_EQUAL = 0, - GDEXTENSION_VARIANT_OP_NOT_EQUAL = 1, - GDEXTENSION_VARIANT_OP_LESS = 2, - GDEXTENSION_VARIANT_OP_LESS_EQUAL = 3, - GDEXTENSION_VARIANT_OP_GREATER = 4, - GDEXTENSION_VARIANT_OP_GREATER_EQUAL = 5, - GDEXTENSION_VARIANT_OP_ADD = 6, - GDEXTENSION_VARIANT_OP_SUBTRACT = 7, - GDEXTENSION_VARIANT_OP_MULTIPLY = 8, - GDEXTENSION_VARIANT_OP_DIVIDE = 9, - GDEXTENSION_VARIANT_OP_NEGATE = 10, - GDEXTENSION_VARIANT_OP_POSITIVE = 11, - GDEXTENSION_VARIANT_OP_MODULE = 12, - GDEXTENSION_VARIANT_OP_POWER = 13, - GDEXTENSION_VARIANT_OP_SHIFT_LEFT = 14, - GDEXTENSION_VARIANT_OP_SHIFT_RIGHT = 15, - GDEXTENSION_VARIANT_OP_BIT_AND = 16, - GDEXTENSION_VARIANT_OP_BIT_OR = 17, - GDEXTENSION_VARIANT_OP_BIT_XOR = 18, - GDEXTENSION_VARIANT_OP_BIT_NEGATE = 19, - GDEXTENSION_VARIANT_OP_AND = 20, - GDEXTENSION_VARIANT_OP_OR = 21, - GDEXTENSION_VARIANT_OP_XOR = 22, - GDEXTENSION_VARIANT_OP_NOT = 23, - GDEXTENSION_VARIANT_OP_IN = 24, - GDEXTENSION_VARIANT_OP_MAX = 25, -} GDExtensionVariantOperator; - -/* In this API there are multiple functions which expect the caller to pass a pointer - * on return value as parameter. - * In order to make it clear if the caller should initialize the return value or not - * we have two flavor of types: - * - `GDExtensionXXXPtr` for pointer on an initialized value - * - `GDExtensionUninitializedXXXPtr` for pointer on uninitialized value - * - * Notes: - * - Not respecting those requirements can seems harmless, but will lead to unexpected - * segfault or memory leak (for instance with a specific compiler/OS, or when two - * native extensions start doing ptrcall on each other). - * - Initialization must be done with the function pointer returned by `variant_get_ptr_constructor`, - * zero-initializing the variable should not be considered a valid initialization method here ! - * - Some types have no destructor (see `extension_api.json`'s `has_destructor` field), for - * them it is always safe to skip the constructor for the return value if you are in a hurry ;-) - */ -typedef void *GDExtensionVariantPtr; -typedef const void *GDExtensionConstVariantPtr; -typedef void *GDExtensionUninitializedVariantPtr; -typedef void *GDExtensionStringNamePtr; -typedef const void *GDExtensionConstStringNamePtr; -typedef void *GDExtensionUninitializedStringNamePtr; -typedef void *GDExtensionStringPtr; -typedef const void *GDExtensionConstStringPtr; -typedef void *GDExtensionUninitializedStringPtr; -typedef void *GDExtensionObjectPtr; -typedef const void *GDExtensionConstObjectPtr; -typedef void *GDExtensionUninitializedObjectPtr; -typedef void *GDExtensionTypePtr; -typedef const void *GDExtensionConstTypePtr; -typedef void *GDExtensionUninitializedTypePtr; -typedef const void *GDExtensionMethodBindPtr; -typedef int64_t GDExtensionInt; -typedef uint8_t GDExtensionBool; -typedef uint64_t GDObjectInstanceID; -typedef void *GDExtensionRefPtr; -typedef const void *GDExtensionConstRefPtr; -typedef enum { - GDEXTENSION_CALL_OK = 0, - GDEXTENSION_CALL_ERROR_INVALID_METHOD = 1, - /* Expected a different variant type. */ - GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT = 2, - /* Expected lower number of arguments. */ - GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS = 3, - /* Expected higher number of arguments. */ - GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS = 4, - GDEXTENSION_CALL_ERROR_INSTANCE_IS_NULL = 5, - /* Used for const call. */ - GDEXTENSION_CALL_ERROR_METHOD_NOT_CONST = 6, -} GDExtensionCallErrorType; - -typedef struct { - GDExtensionCallErrorType error; - int32_t argument; - int32_t expected; -} GDExtensionCallError; - -typedef void (*GDExtensionVariantFromTypeConstructorFunc)(GDExtensionUninitializedVariantPtr, GDExtensionTypePtr); -typedef void (*GDExtensionTypeFromVariantConstructorFunc)(GDExtensionUninitializedTypePtr, GDExtensionVariantPtr); -typedef void *(*GDExtensionVariantGetInternalPtrFunc)(GDExtensionVariantPtr); -typedef void (*GDExtensionPtrOperatorEvaluator)(GDExtensionConstTypePtr p_left, GDExtensionConstTypePtr p_right, GDExtensionTypePtr r_result); -typedef void (*GDExtensionPtrBuiltInMethod)(GDExtensionTypePtr p_base, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return, int32_t p_argument_count); -typedef void (*GDExtensionPtrConstructor)(GDExtensionUninitializedTypePtr p_base, const GDExtensionConstTypePtr *p_args); -typedef void (*GDExtensionPtrDestructor)(GDExtensionTypePtr p_base); -typedef void (*GDExtensionPtrSetter)(GDExtensionTypePtr p_base, GDExtensionConstTypePtr p_value); -typedef void (*GDExtensionPtrGetter)(GDExtensionConstTypePtr p_base, GDExtensionTypePtr r_value); -typedef void (*GDExtensionPtrIndexedSetter)(GDExtensionTypePtr p_base, GDExtensionInt p_index, GDExtensionConstTypePtr p_value); -typedef void (*GDExtensionPtrIndexedGetter)(GDExtensionConstTypePtr p_base, GDExtensionInt p_index, GDExtensionTypePtr r_value); -typedef void (*GDExtensionPtrKeyedSetter)(GDExtensionTypePtr p_base, GDExtensionConstTypePtr p_key, GDExtensionConstTypePtr p_value); -typedef void (*GDExtensionPtrKeyedGetter)(GDExtensionConstTypePtr p_base, GDExtensionConstTypePtr p_key, GDExtensionTypePtr r_value); -typedef uint32_t (*GDExtensionPtrKeyedChecker)(GDExtensionConstVariantPtr p_base, GDExtensionConstVariantPtr p_key); -typedef void (*GDExtensionPtrUtilityFunction)(GDExtensionTypePtr r_return, const GDExtensionConstTypePtr *p_args, int32_t p_argument_count); -typedef GDExtensionObjectPtr (*GDExtensionClassConstructor)(); -typedef void *(*GDExtensionInstanceBindingCreateCallback)(void *p_token, void *p_instance); -typedef void (*GDExtensionInstanceBindingFreeCallback)(void *p_token, void *p_instance, void *p_binding); -typedef GDExtensionBool (*GDExtensionInstanceBindingReferenceCallback)(void *p_token, void *p_binding, GDExtensionBool p_reference); -typedef struct { - GDExtensionInstanceBindingCreateCallback create_callback; - GDExtensionInstanceBindingFreeCallback free_callback; - GDExtensionInstanceBindingReferenceCallback reference_callback; -} GDExtensionInstanceBindingCallbacks; - -typedef void *GDExtensionClassInstancePtr; -typedef GDExtensionBool (*GDExtensionClassSet)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value); -typedef GDExtensionBool (*GDExtensionClassGet)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); -typedef uint64_t (*GDExtensionClassGetRID)(GDExtensionClassInstancePtr p_instance); -typedef struct { - GDExtensionVariantType type; - GDExtensionStringNamePtr name; - GDExtensionStringNamePtr class_name; - /* Bitfield of `PropertyHint` (defined in `extension_api.json`). */ - uint32_t hint; - GDExtensionStringPtr hint_string; - /* Bitfield of `PropertyUsageFlags` (defined in `extension_api.json`). */ - uint32_t usage; -} GDExtensionPropertyInfo; - -typedef struct { - GDExtensionStringNamePtr name; - GDExtensionPropertyInfo return_value; - /* Bitfield of `GDExtensionClassMethodFlags`. */ - uint32_t flags; - int32_t id; - /* Arguments: `default_arguments` is an array of size `argument_count`. */ - uint32_t argument_count; - GDExtensionPropertyInfo *arguments; - /* Default arguments: `default_arguments` is an array of size `default_argument_count`. */ - uint32_t default_argument_count; - GDExtensionVariantPtr *default_arguments; -} GDExtensionMethodInfo; - -typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count); -typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list); /* Deprecated in Godot 4.3. Use `GDExtensionClassFreePropertyList2` instead. */ -typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count); -typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name); -typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); -typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property); -typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); /* Deprecated in Godot 4.2. Use `GDExtensionClassNotification2` instead. */ -typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed); -typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out); -typedef void (*GDExtensionClassReference)(GDExtensionClassInstancePtr p_instance); -typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance); -typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); -/* Called to construct an instance of the class. - * For classes descending from RefCounted, the reference count should be zero. - */ -typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_class_userdata); /* Deprecated in Godot 4.4. Use `GDExtensionClassCreateInstance3` instead. */ -/* Called to construct an instance of the class. - * For classes descending from RefCounted, the reference count should be zero. - */ -typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance2)(void *p_class_userdata, GDExtensionBool p_notify_postinitialize); /* Deprecated in Godot 4.7. Use `GDExtensionClassCreateInstance3` instead. */ -/* Called to construct an instance of the class. - * For classes descending from RefCounted, the reference count should already be incremented by 1. - */ -typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance3)(void *p_class_userdata, GDExtensionBool p_notify_postinitialize); -typedef void (*GDExtensionClassFreeInstance)(void *p_class_userdata, GDExtensionClassInstancePtr p_instance); -typedef GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object); -typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name); /* Deprecated in Godot 4.4. Use `GDExtensionClassGetVirtual2` instead. */ -typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual2)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash); -typedef void *(*GDExtensionClassGetVirtualCallData)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name); /* Deprecated in Godot 4.4. Use `GDExtensionClassGetVirtualCallData2` instead. */ -typedef void *(*GDExtensionClassGetVirtualCallData2)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash); -typedef void (*GDExtensionClassCallVirtualWithData)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, void *p_virtual_call_userdata, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); -typedef struct { - GDExtensionBool is_virtual; - GDExtensionBool is_abstract; - GDExtensionClassSet set_func; - GDExtensionClassGet get_func; - GDExtensionClassGetPropertyList get_property_list_func; - GDExtensionClassFreePropertyList free_property_list_func; - GDExtensionClassPropertyCanRevert property_can_revert_func; - GDExtensionClassPropertyGetRevert property_get_revert_func; - GDExtensionClassNotification notification_func; - GDExtensionClassToString to_string_func; - GDExtensionClassReference reference_func; - GDExtensionClassUnreference unreference_func; - /* Class constructor. Required unless the class is virtual or abstract. */ - GDExtensionClassCreateInstance create_instance_func; - /* Destructor; mandatory. */ - GDExtensionClassFreeInstance free_instance_func; - /* Queries a virtual function by name and returns a callback to invoke the requested virtual function. */ - GDExtensionClassGetVirtual get_virtual_func; - GDExtensionClassGetRID get_rid_func; - /* Per-class user data, later accessible in instance bindings. */ - void *class_userdata; -} GDExtensionClassCreationInfo; /* Deprecated in Godot 4.2. Use `GDExtensionClassCreationInfo6` instead. */ - -typedef struct { - GDExtensionBool is_virtual; - GDExtensionBool is_abstract; - GDExtensionBool is_exposed; - GDExtensionClassSet set_func; - GDExtensionClassGet get_func; - GDExtensionClassGetPropertyList get_property_list_func; - GDExtensionClassFreePropertyList free_property_list_func; - GDExtensionClassPropertyCanRevert property_can_revert_func; - GDExtensionClassPropertyGetRevert property_get_revert_func; - GDExtensionClassValidateProperty validate_property_func; - GDExtensionClassNotification2 notification_func; - GDExtensionClassToString to_string_func; - GDExtensionClassReference reference_func; - GDExtensionClassUnreference unreference_func; - /* Class constructor. Required unless the class is virtual or abstract. */ - GDExtensionClassCreateInstance create_instance_func; - /* Destructor; mandatory. */ - GDExtensionClassFreeInstance free_instance_func; - GDExtensionClassRecreateInstance recreate_instance_func; - /* Queries a virtual function by name and returns a callback to invoke the requested virtual function. */ - GDExtensionClassGetVirtual get_virtual_func; - /* Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that - * need or benefit from extra data when calling virtual functions. - * Returns user data that will be passed to `call_virtual_with_data_func`. - * Returning `NULL` from this function signals to Godot that the virtual function is not overridden. - * Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized. - * You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`. - */ - GDExtensionClassGetVirtualCallData get_virtual_call_data_func; - /* Used to call virtual functions when `get_virtual_call_data_func` is not null. */ - GDExtensionClassCallVirtualWithData call_virtual_with_data_func; - GDExtensionClassGetRID get_rid_func; - /* Per-class user data, later accessible in instance bindings. */ - void *class_userdata; -} GDExtensionClassCreationInfo2; /* Deprecated in Godot 4.3. Use `GDExtensionClassCreationInfo6` instead. */ - -typedef struct { - GDExtensionBool is_virtual; - GDExtensionBool is_abstract; - GDExtensionBool is_exposed; - GDExtensionBool is_runtime; - GDExtensionClassSet set_func; - GDExtensionClassGet get_func; - GDExtensionClassGetPropertyList get_property_list_func; - GDExtensionClassFreePropertyList2 free_property_list_func; - GDExtensionClassPropertyCanRevert property_can_revert_func; - GDExtensionClassPropertyGetRevert property_get_revert_func; - GDExtensionClassValidateProperty validate_property_func; - GDExtensionClassNotification2 notification_func; - GDExtensionClassToString to_string_func; - GDExtensionClassReference reference_func; - GDExtensionClassUnreference unreference_func; - /* Class constructor. Required unless the class is virtual or abstract. */ - GDExtensionClassCreateInstance create_instance_func; - /* Destructor; mandatory. */ - GDExtensionClassFreeInstance free_instance_func; - GDExtensionClassRecreateInstance recreate_instance_func; - /* Queries a virtual function by name and returns a callback to invoke the requested virtual function. */ - GDExtensionClassGetVirtual get_virtual_func; - /* Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that - * need or benefit from extra data when calling virtual functions. - * Returns user data that will be passed to `call_virtual_with_data_func`. - * Returning `NULL` from this function signals to Godot that the virtual function is not overridden. - * Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized. - * You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`. - */ - GDExtensionClassGetVirtualCallData get_virtual_call_data_func; - /* Used to call virtual functions when `get_virtual_call_data_func` is not null. */ - GDExtensionClassCallVirtualWithData call_virtual_with_data_func; - GDExtensionClassGetRID get_rid_func; - /* Per-class user data, later accessible in instance bindings. */ - void *class_userdata; -} GDExtensionClassCreationInfo3; /* Deprecated in Godot 4.4. Use `GDExtensionClassCreationInfo6` instead. */ - -typedef struct { - GDExtensionBool is_virtual; - GDExtensionBool is_abstract; - GDExtensionBool is_exposed; - GDExtensionBool is_runtime; - GDExtensionConstStringPtr icon_path; - GDExtensionClassSet set_func; - GDExtensionClassGet get_func; - GDExtensionClassGetPropertyList get_property_list_func; - GDExtensionClassFreePropertyList2 free_property_list_func; - GDExtensionClassPropertyCanRevert property_can_revert_func; - GDExtensionClassPropertyGetRevert property_get_revert_func; - GDExtensionClassValidateProperty validate_property_func; - GDExtensionClassNotification2 notification_func; - GDExtensionClassToString to_string_func; - GDExtensionClassReference reference_func; - GDExtensionClassUnreference unreference_func; - /* Class constructor. Required unless the class is virtual or abstract. */ - GDExtensionClassCreateInstance2 create_instance_func; - /* Destructor; mandatory. */ - GDExtensionClassFreeInstance free_instance_func; - GDExtensionClassRecreateInstance recreate_instance_func; - /* Queries a virtual function by name and returns a callback to invoke the requested virtual function. */ - GDExtensionClassGetVirtual2 get_virtual_func; - /* Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that - * need or benefit from extra data when calling virtual functions. - * Returns user data that will be passed to `call_virtual_with_data_func`. - * Returning `NULL` from this function signals to Godot that the virtual function is not overridden. - * Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized. - * You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`. - */ - GDExtensionClassGetVirtualCallData2 get_virtual_call_data_func; - /* Used to call virtual functions when `get_virtual_call_data_func` is not null. */ - GDExtensionClassCallVirtualWithData call_virtual_with_data_func; - /* Per-class user data, later accessible in instance bindings. */ - void *class_userdata; -} GDExtensionClassCreationInfo4; /* Deprecated in Godot 4.5. Use `GDExtensionClassCreationInfo6` instead. */ - -typedef GDExtensionClassCreationInfo4 GDExtensionClassCreationInfo5; /* Deprecated in Godot 4.7. Use `GDExtensionClassCreationInfo6` instead. */ -typedef struct { - GDExtensionBool is_virtual; - GDExtensionBool is_abstract; - GDExtensionBool is_exposed; - GDExtensionBool is_runtime; - GDExtensionConstStringPtr icon_path; - GDExtensionClassSet set_func; - GDExtensionClassGet get_func; - GDExtensionClassGetPropertyList get_property_list_func; - GDExtensionClassFreePropertyList2 free_property_list_func; - GDExtensionClassPropertyCanRevert property_can_revert_func; - GDExtensionClassPropertyGetRevert property_get_revert_func; - GDExtensionClassValidateProperty validate_property_func; - GDExtensionClassNotification2 notification_func; - GDExtensionClassToString to_string_func; - GDExtensionClassReference reference_func; - GDExtensionClassUnreference unreference_func; - /* Class constructor. Required unless the class is virtual or abstract. */ - GDExtensionClassCreateInstance3 create_instance_func; - /* Destructor; mandatory. */ - GDExtensionClassFreeInstance free_instance_func; - GDExtensionClassRecreateInstance recreate_instance_func; - /* Queries a virtual function by name and returns a callback to invoke the requested virtual function. */ - GDExtensionClassGetVirtual2 get_virtual_func; - /* Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that - * need or benefit from extra data when calling virtual functions. - * Returns user data that will be passed to `call_virtual_with_data_func`. - * Returning `NULL` from this function signals to Godot that the virtual function is not overridden. - * Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized. - * You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`. - */ - GDExtensionClassGetVirtualCallData2 get_virtual_call_data_func; - /* Used to call virtual functions when `get_virtual_call_data_func` is not null. */ - GDExtensionClassCallVirtualWithData call_virtual_with_data_func; - /* Per-class user data, later accessible in instance bindings. */ - void *class_userdata; -} GDExtensionClassCreationInfo6; - -typedef void *GDExtensionClassLibraryPtr; -/* Passed a pointer to a PackedStringArray that should be filled with the classes that may be used by the GDExtension. */ -typedef void (*GDExtensionEditorGetClassesUsedCallback)(GDExtensionTypePtr p_packed_string_array); -typedef enum { - GDEXTENSION_METHOD_FLAG_NORMAL = 1, - GDEXTENSION_METHOD_FLAG_EDITOR = 2, - GDEXTENSION_METHOD_FLAG_CONST = 4, - GDEXTENSION_METHOD_FLAG_VIRTUAL = 8, - GDEXTENSION_METHOD_FLAG_VARARG = 16, - GDEXTENSION_METHOD_FLAG_STATIC = 32, - GDEXTENSION_METHOD_FLAG_VIRTUAL_REQUIRED = 128, - GDEXTENSION_METHOD_FLAGS_DEFAULT = 1, -} GDExtensionClassMethodFlags; - -typedef enum { - GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE = 0, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT8 = 1, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16 = 2, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32 = 3, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64 = 4, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT8 = 5, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT16 = 6, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32 = 7, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64 = 8, - GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT = 9, - GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE = 10, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR16 = 11, - GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR32 = 12, - GDEXTENSION_METHOD_ARGUMENT_METADATA_OBJECT_IS_REQUIRED = 13, -} GDExtensionClassMethodArgumentMetadata; - -typedef void (*GDExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error); -typedef void (*GDExtensionClassMethodValidatedCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionVariantPtr r_return); -typedef void (*GDExtensionClassMethodPtrCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); -typedef struct { - GDExtensionStringNamePtr name; - void *method_userdata; - GDExtensionClassMethodCall call_func; - GDExtensionClassMethodPtrCall ptrcall_func; - /* Bitfield of `GDExtensionClassMethodFlags`. */ - uint32_t method_flags; - /* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored. - * - * @todo Consider dropping `has_return_value` and making the other two properties match `GDExtensionMethodInfo` and `GDExtensionClassVirtualMethod` for consistency in future version of this struct. - */ - GDExtensionBool has_return_value; - GDExtensionPropertyInfo *return_value_info; - GDExtensionClassMethodArgumentMetadata return_value_metadata; - /* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`. - * Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. - * - * @todo Consider renaming `arguments_info` to `arguments` for consistency in future version of this struct. - */ - uint32_t argument_count; - GDExtensionPropertyInfo *arguments_info; - GDExtensionClassMethodArgumentMetadata *arguments_metadata; - /* Default arguments: `default_arguments` is an array of size `default_argument_count`. */ - uint32_t default_argument_count; - GDExtensionVariantPtr *default_arguments; -} GDExtensionClassMethodInfo; - -typedef struct { - GDExtensionStringNamePtr name; - /* Bitfield of `GDExtensionClassMethodFlags`. */ - uint32_t method_flags; - GDExtensionPropertyInfo return_value; - GDExtensionClassMethodArgumentMetadata return_value_metadata; - uint32_t argument_count; - GDExtensionPropertyInfo *arguments; - GDExtensionClassMethodArgumentMetadata *arguments_metadata; -} GDExtensionClassVirtualMethodInfo; - -typedef void (*GDExtensionCallableCustomCall)(void *callable_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error); -typedef GDExtensionBool (*GDExtensionCallableCustomIsValid)(void *callable_userdata); -typedef void (*GDExtensionCallableCustomFree)(void *callable_userdata); -typedef uint32_t (*GDExtensionCallableCustomHash)(void *callable_userdata); -typedef GDExtensionBool (*GDExtensionCallableCustomEqual)(void *callable_userdata_a, void *callable_userdata_b); -typedef GDExtensionBool (*GDExtensionCallableCustomLessThan)(void *callable_userdata_a, void *callable_userdata_b); -typedef void (*GDExtensionCallableCustomToString)(void *callable_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out); -typedef GDExtensionInt (*GDExtensionCallableCustomGetArgumentCount)(void *callable_userdata, GDExtensionBool *r_is_valid); -/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method. - * - * `token` should point to an address that uniquely identifies the GDExtension (for example, the - * `GDExtensionClassLibraryPtr` passed to the entry symbol function. - * - * `hash_func`, `equal_func`, and `less_than_func` are optional. If not provided both `call_func` and - * `callable_userdata` together are used as the identity of the callable for hashing and comparison purposes. - * - * The hash returned by `hash_func` is cached, `hash_func` will not be called more than once per callable. - * - * `is_valid_func` is necessary if the validity of the callable can change before destruction. - * - * `free_func` is necessary if `callable_userdata` needs to be cleaned up when the callable is freed. - */ -typedef struct { - void *callable_userdata; - void *token; - GDObjectInstanceID object_id; - GDExtensionCallableCustomCall call_func; - GDExtensionCallableCustomIsValid is_valid_func; - GDExtensionCallableCustomFree free_func; - GDExtensionCallableCustomHash hash_func; - GDExtensionCallableCustomEqual equal_func; - GDExtensionCallableCustomLessThan less_than_func; - GDExtensionCallableCustomToString to_string_func; -} GDExtensionCallableCustomInfo; /* Deprecated in Godot 4.3. Use `GDExtensionCallableCustomInfo2` instead. */ - -/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method. - * - * `token` should point to an address that uniquely identifies the GDExtension (for example, the - * `GDExtensionClassLibraryPtr` passed to the entry symbol function. - * - * `hash_func`, `equal_func`, and `less_than_func` are optional. If not provided both `call_func` and - * `callable_userdata` together are used as the identity of the callable for hashing and comparison purposes. - * - * The hash returned by `hash_func` is cached, `hash_func` will not be called more than once per callable. - * - * `is_valid_func` is necessary if the validity of the callable can change before destruction. - * - * `free_func` is necessary if `callable_userdata` needs to be cleaned up when the callable is freed. - */ -typedef struct { - void *callable_userdata; - void *token; - GDObjectInstanceID object_id; - GDExtensionCallableCustomCall call_func; - GDExtensionCallableCustomIsValid is_valid_func; - GDExtensionCallableCustomFree free_func; - GDExtensionCallableCustomHash hash_func; - GDExtensionCallableCustomEqual equal_func; - GDExtensionCallableCustomLessThan less_than_func; - GDExtensionCallableCustomToString to_string_func; - GDExtensionCallableCustomGetArgumentCount get_argument_count_func; -} GDExtensionCallableCustomInfo2; - -/* Pointer to custom ScriptInstance native implementation. */ -typedef void *GDExtensionScriptInstanceDataPtr; -typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value); -typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); -typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count); -typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list); /* Deprecated in Godot 4.3. Use `GDExtensionScriptInstanceFreePropertyList2` instead. */ -typedef void (*GDExtensionScriptInstanceFreePropertyList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count); -typedef GDExtensionBool (*GDExtensionScriptInstanceGetClassCategory)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_class_category); -typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid); -typedef GDExtensionBool (*GDExtensionScriptInstanceValidateProperty)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_property); -typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name); -typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); -typedef GDExtensionObjectPtr (*GDExtensionScriptInstanceGetOwner)(GDExtensionScriptInstanceDataPtr p_instance); -typedef void (*GDExtensionScriptInstancePropertyStateAdd)(GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value, void *p_userdata); -typedef void (*GDExtensionScriptInstanceGetPropertyState)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionScriptInstancePropertyStateAdd p_add_func, void *p_userdata); -typedef const GDExtensionMethodInfo *(*GDExtensionScriptInstanceGetMethodList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count); -typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list); /* Deprecated in Godot 4.3. Use `GDExtensionScriptInstanceFreeMethodList2` instead. */ -typedef void (*GDExtensionScriptInstanceFreeMethodList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list, uint32_t p_count); -typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name); -typedef GDExtensionInt (*GDExtensionScriptInstanceGetMethodArgumentCount)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid); -typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error); -typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what); /* Deprecated in Godot 4.2. Use `GDExtensionScriptInstanceNotification2` instead. */ -typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, GDExtensionBool p_reversed); -typedef void (*GDExtensionScriptInstanceToString)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out); -typedef void (*GDExtensionScriptInstanceRefCountIncremented)(GDExtensionScriptInstanceDataPtr p_instance); -typedef GDExtensionBool (*GDExtensionScriptInstanceRefCountDecremented)(GDExtensionScriptInstanceDataPtr p_instance); -typedef GDExtensionObjectPtr (*GDExtensionScriptInstanceGetScript)(GDExtensionScriptInstanceDataPtr p_instance); -typedef GDExtensionBool (*GDExtensionScriptInstanceIsPlaceholder)(GDExtensionScriptInstanceDataPtr p_instance); -typedef void *GDExtensionScriptLanguagePtr; -typedef GDExtensionScriptLanguagePtr (*GDExtensionScriptInstanceGetLanguage)(GDExtensionScriptInstanceDataPtr p_instance); -typedef void (*GDExtensionScriptInstanceFree)(GDExtensionScriptInstanceDataPtr p_instance); -/* Pointer to ScriptInstance. */ -typedef void *GDExtensionScriptInstancePtr; -typedef struct { - GDExtensionScriptInstanceSet set_func; - GDExtensionScriptInstanceGet get_func; - GDExtensionScriptInstanceGetPropertyList get_property_list_func; - GDExtensionScriptInstanceFreePropertyList free_property_list_func; - GDExtensionScriptInstancePropertyCanRevert property_can_revert_func; - GDExtensionScriptInstancePropertyGetRevert property_get_revert_func; - GDExtensionScriptInstanceGetOwner get_owner_func; - GDExtensionScriptInstanceGetPropertyState get_property_state_func; - GDExtensionScriptInstanceGetMethodList get_method_list_func; - GDExtensionScriptInstanceFreeMethodList free_method_list_func; - GDExtensionScriptInstanceGetPropertyType get_property_type_func; - GDExtensionScriptInstanceHasMethod has_method_func; - GDExtensionScriptInstanceCall call_func; - GDExtensionScriptInstanceNotification notification_func; - GDExtensionScriptInstanceToString to_string_func; - GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func; - GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func; - GDExtensionScriptInstanceGetScript get_script_func; - GDExtensionScriptInstanceIsPlaceholder is_placeholder_func; - GDExtensionScriptInstanceSet set_fallback_func; - GDExtensionScriptInstanceGet get_fallback_func; - GDExtensionScriptInstanceGetLanguage get_language_func; - GDExtensionScriptInstanceFree free_func; -} GDExtensionScriptInstanceInfo; /* Deprecated in Godot 4.2. Use `GDExtensionScriptInstanceInfo3` instead. */ - -typedef struct { - GDExtensionScriptInstanceSet set_func; - GDExtensionScriptInstanceGet get_func; - GDExtensionScriptInstanceGetPropertyList get_property_list_func; - GDExtensionScriptInstanceFreePropertyList free_property_list_func; - /* Optional. Set to NULL for the default behavior. */ - GDExtensionScriptInstanceGetClassCategory get_class_category_func; - GDExtensionScriptInstancePropertyCanRevert property_can_revert_func; - GDExtensionScriptInstancePropertyGetRevert property_get_revert_func; - GDExtensionScriptInstanceGetOwner get_owner_func; - GDExtensionScriptInstanceGetPropertyState get_property_state_func; - GDExtensionScriptInstanceGetMethodList get_method_list_func; - GDExtensionScriptInstanceFreeMethodList free_method_list_func; - GDExtensionScriptInstanceGetPropertyType get_property_type_func; - GDExtensionScriptInstanceValidateProperty validate_property_func; - GDExtensionScriptInstanceHasMethod has_method_func; - GDExtensionScriptInstanceCall call_func; - GDExtensionScriptInstanceNotification2 notification_func; - GDExtensionScriptInstanceToString to_string_func; - GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func; - GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func; - GDExtensionScriptInstanceGetScript get_script_func; - GDExtensionScriptInstanceIsPlaceholder is_placeholder_func; - GDExtensionScriptInstanceSet set_fallback_func; - GDExtensionScriptInstanceGet get_fallback_func; - GDExtensionScriptInstanceGetLanguage get_language_func; - GDExtensionScriptInstanceFree free_func; -} GDExtensionScriptInstanceInfo2; /* Deprecated in Godot 4.3. Use `GDExtensionScriptInstanceInfo3` instead. */ - -typedef struct { - GDExtensionScriptInstanceSet set_func; - GDExtensionScriptInstanceGet get_func; - GDExtensionScriptInstanceGetPropertyList get_property_list_func; - GDExtensionScriptInstanceFreePropertyList2 free_property_list_func; - /* Optional. Set to NULL for the default behavior. */ - GDExtensionScriptInstanceGetClassCategory get_class_category_func; - GDExtensionScriptInstancePropertyCanRevert property_can_revert_func; - GDExtensionScriptInstancePropertyGetRevert property_get_revert_func; - GDExtensionScriptInstanceGetOwner get_owner_func; - GDExtensionScriptInstanceGetPropertyState get_property_state_func; - GDExtensionScriptInstanceGetMethodList get_method_list_func; - GDExtensionScriptInstanceFreeMethodList2 free_method_list_func; - GDExtensionScriptInstanceGetPropertyType get_property_type_func; - GDExtensionScriptInstanceValidateProperty validate_property_func; - GDExtensionScriptInstanceHasMethod has_method_func; - GDExtensionScriptInstanceGetMethodArgumentCount get_method_argument_count_func; - GDExtensionScriptInstanceCall call_func; - GDExtensionScriptInstanceNotification2 notification_func; - GDExtensionScriptInstanceToString to_string_func; - GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func; - GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func; - GDExtensionScriptInstanceGetScript get_script_func; - GDExtensionScriptInstanceIsPlaceholder is_placeholder_func; - GDExtensionScriptInstanceSet set_fallback_func; - GDExtensionScriptInstanceGet get_fallback_func; - GDExtensionScriptInstanceGetLanguage get_language_func; - GDExtensionScriptInstanceFree free_func; -} GDExtensionScriptInstanceInfo3; - -typedef void (*GDExtensionWorkerThreadPoolGroupTask)(void *, uint32_t); -typedef void (*GDExtensionWorkerThreadPoolTask)(void *); -typedef enum { - GDEXTENSION_INITIALIZATION_CORE = 0, - GDEXTENSION_INITIALIZATION_SERVERS = 1, - GDEXTENSION_INITIALIZATION_SCENE = 2, - GDEXTENSION_INITIALIZATION_EDITOR = 3, - GDEXTENSION_MAX_INITIALIZATION_LEVEL = 4, -} GDExtensionInitializationLevel; - -typedef void (*GDExtensionInitializeCallback)(void *p_userdata, GDExtensionInitializationLevel p_level); -typedef void (*GDExtensionDeinitializeCallback)(void *p_userdata, GDExtensionInitializationLevel p_level); -typedef struct { - /* Minimum initialization level required. - * If Core or Servers, the extension needs editor or game restart to take effect - */ - GDExtensionInitializationLevel minimum_initialization_level; - /* Up to the user to supply when initializing */ - void *userdata; - /* This function will be called multiple times for each initialization level. */ - GDExtensionInitializeCallback initialize; - GDExtensionDeinitializeCallback deinitialize; -} GDExtensionInitialization; - -typedef void (*GDExtensionInterfaceFunctionPtr)(); -typedef GDExtensionInterfaceFunctionPtr (*GDExtensionInterfaceGetProcAddress)(const char *p_function_name); -/* Each GDExtension should define a C function that matches the signature of GDExtensionInitializationFunction, - * and export it so that it can be loaded via dlopen() or equivalent for the given platform. - * - * For example: - * - * GDExtensionBool my_extension_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization); - * - * This function's name must be specified as the 'entry_symbol' in the .gdextension file. - * - * This makes it the entry point of the GDExtension and will be called on initialization. - * - * The GDExtension can then modify the r_initialization structure, setting the minimum initialization level, - * and providing pointers to functions that will be called at various stages of initialization/shutdown. - * - * The rest of the GDExtension's interface to Godot consists of function pointers that can be loaded - * by calling p_get_proc_address("...") with the name of the function. - * - * For example: - * - * GDExtensionInterfaceGetGodotVersion get_godot_version = (GDExtensionInterfaceGetGodotVersion)p_get_proc_address("get_godot_version"); - * - * (Note that snippet may cause "cast between incompatible function types" on some compilers, you can - * silence this by adding an intermediary `void*` cast.) - * - * You can then call it like a normal function: - * - * GDExtensionGodotVersion godot_version; - * get_godot_version(&godot_version); - * printf("Godot v%d.%d.%d\n", godot_version.major, godot_version.minor, godot_version.patch); - * - * All of these interface functions are described below, together with the name that's used to load it, - * and the function pointer typedef that shows its signature. - */ -typedef GDExtensionBool (*GDExtensionInitializationFunction)(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization); -typedef struct { - uint32_t major; - uint32_t minor; - uint32_t patch; - const char *string; -} GDExtensionGodotVersion; /* Deprecated in Godot 4.5. Use `GDExtensionGodotVersion2` instead. */ - -typedef struct { - uint32_t major; - uint32_t minor; - uint32_t patch; - /* Full version encoded as hexadecimal with one byte (2 hex digits) per number (e.g. for "3.1.12" it would be 0x03010C) */ - uint32_t hex; - /* (e.g. "stable", "beta", "rc1", "rc2") */ - const char *status; - /* (e.g. "custom_build") */ - const char *build; - /* Full Git commit hash. */ - const char *hash; - /* Git commit date UNIX timestamp in seconds, or 0 if unavailable. */ - uint64_t timestamp; - /* (e.g. "Godot v3.1.4.stable.official.mono") */ - const char *string; -} GDExtensionGodotVersion2; - -/* Called when starting the main loop. */ -typedef void (*GDExtensionMainLoopStartupCallback)(); -/* Called when shutting down the main loop. */ -typedef void (*GDExtensionMainLoopShutdownCallback)(); -/* Called for every frame iteration of the main loop. */ -typedef void (*GDExtensionMainLoopFrameCallback)(); -typedef struct { - /* Will be called after Godot is started and is fully initialized. */ - GDExtensionMainLoopStartupCallback startup_func; - /* Will be called before Godot is shutdown when it is still fully initialized. */ - GDExtensionMainLoopShutdownCallback shutdown_func; - /* Will be called for each process frame. This will run after all `_process()` methods on Node, and before `ScriptServer::frame()`. - * This is intended to be the equivalent of `ScriptLanguage::frame()` for GDExtension language bindings that don't use the script API. - */ - GDExtensionMainLoopFrameCallback frame_func; -} GDExtensionMainLoopCallbacks; - -/** - * @name get_godot_version - * @since 4.1 - * @deprecated Deprecated in Godot 4.5. Use `get_godot_version2` instead. - * - * Gets the Godot version that the GDExtension was loaded into. - * - * @param r_godot_version A pointer to the structure to write the version information into. - */ -typedef void (*GDExtensionInterfaceGetGodotVersion)(GDExtensionGodotVersion *r_godot_version); - -/** - * @name get_godot_version2 - * @since 4.5 - * - * Gets the Godot version that the GDExtension was loaded into. - * - * @param r_godot_version A pointer to the structure to write the version information into. - */ -typedef void (*GDExtensionInterfaceGetGodotVersion2)(GDExtensionGodotVersion2 *r_godot_version); - -/** - * @name mem_alloc - * @since 4.1 - * @deprecated Deprecated in Godot 4.6. Does not allow explicitly requesting padding. Use `mem_alloc2` instead. - * - * Allocates memory. - * - * @param p_bytes The amount of memory to allocate in bytes. - * - * @return A pointer to the allocated memory, or NULL if unsuccessful. - */ -typedef void *(*GDExtensionInterfaceMemAlloc)(size_t p_bytes); - -/** - * @name mem_realloc - * @since 4.1 - * @deprecated Deprecated in Godot 4.6. Does not allow explicitly requesting padding. Use `mem_realloc2` instead. - * - * Reallocates memory. - * - * @param p_ptr A pointer to the previously allocated memory. - * @param p_bytes The number of bytes to resize the memory block to. - * - * @return A pointer to the allocated memory, or NULL if unsuccessful. - */ -typedef void *(*GDExtensionInterfaceMemRealloc)(void *p_ptr, size_t p_bytes); - -/** - * @name mem_free - * @since 4.1 - * @deprecated Deprecated in Godot 4.6. Does not allow explicitly requesting padding. Use `mem_free2` instead. - * - * Frees memory. - * - * @param p_ptr A pointer to the previously allocated memory. - */ -typedef void (*GDExtensionInterfaceMemFree)(void *p_ptr); - -/** - * @name mem_alloc2 - * @since 4.6 - * - * Allocates memory. - * - * @param p_bytes The amount of memory to allocate in bytes. - * @param p_pad_align If true, the returned memory will have prepadding of at least 8 bytes. - * - * @return A pointer to the allocated memory, or NULL if unsuccessful. - */ -typedef void *(*GDExtensionInterfaceMemAlloc2)(size_t p_bytes, GDExtensionBool p_pad_align); - -/** - * @name mem_realloc2 - * @since 4.6 - * - * Reallocates memory. - * - * @param p_ptr A pointer to the previously allocated memory. - * @param p_bytes The number of bytes to resize the memory block to. - * @param p_pad_align If true, the returned memory will have prepadding of at least 8 bytes. - * - * @return A pointer to the allocated memory, or NULL if unsuccessful. - */ -typedef void *(*GDExtensionInterfaceMemRealloc2)(void *p_ptr, size_t p_bytes, GDExtensionBool p_pad_align); - -/** - * @name mem_free2 - * @since 4.6 - * - * Frees memory. - * - * @param p_ptr A pointer to the previously allocated memory. - * @param p_pad_align If true, the given memory was allocated with prepadding. - */ -typedef void (*GDExtensionInterfaceMemFree2)(void *p_ptr, GDExtensionBool p_pad_align); - -/** - * @name print_error - * @since 4.1 - * - * Logs an error to Godot's built-in debugger and to the OS terminal. - * - * @param p_description The code triggering the error. - * @param p_function The function name where the error occurred. - * @param p_file The file where the error occurred. - * @param p_line The line where the error occurred. - * @param p_editor_notify Whether or not to notify the editor. - */ -typedef void (*GDExtensionInterfacePrintError)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line, GDExtensionBool p_editor_notify); - -/** - * @name print_error_with_message - * @since 4.1 - * - * Logs an error with a message to Godot's built-in debugger and to the OS terminal. - * - * @param p_description The code triggering the error. - * @param p_message The message to show along with the error. - * @param p_function The function name where the error occurred. - * @param p_file The file where the error occurred. - * @param p_line The line where the error occurred. - * @param p_editor_notify Whether or not to notify the editor. - */ -typedef void (*GDExtensionInterfacePrintErrorWithMessage)(const char *p_description, const char *p_message, const char *p_function, const char *p_file, int32_t p_line, GDExtensionBool p_editor_notify); - -/** - * @name print_warning - * @since 4.1 - * - * Logs a warning to Godot's built-in debugger and to the OS terminal. - * - * @param p_description The code triggering the warning. - * @param p_function The function name where the warning occurred. - * @param p_file The file where the warning occurred. - * @param p_line The line where the warning occurred. - * @param p_editor_notify Whether or not to notify the editor. - */ -typedef void (*GDExtensionInterfacePrintWarning)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line, GDExtensionBool p_editor_notify); - -/** - * @name print_warning_with_message - * @since 4.1 - * - * Logs a warning with a message to Godot's built-in debugger and to the OS terminal. - * - * @param p_description The code triggering the warning. - * @param p_message The message to show along with the warning. - * @param p_function The function name where the warning occurred. - * @param p_file The file where the warning occurred. - * @param p_line The line where the warning occurred. - * @param p_editor_notify Whether or not to notify the editor. - */ -typedef void (*GDExtensionInterfacePrintWarningWithMessage)(const char *p_description, const char *p_message, const char *p_function, const char *p_file, int32_t p_line, GDExtensionBool p_editor_notify); - -/** - * @name print_script_error - * @since 4.1 - * - * Logs a script error to Godot's built-in debugger and to the OS terminal. - * - * @param p_description The code triggering the error. - * @param p_function The function name where the error occurred. - * @param p_file The file where the error occurred. - * @param p_line The line where the error occurred. - * @param p_editor_notify Whether or not to notify the editor. - */ -typedef void (*GDExtensionInterfacePrintScriptError)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line, GDExtensionBool p_editor_notify); - -/** - * @name print_script_error_with_message - * @since 4.1 - * - * Logs a script error with a message to Godot's built-in debugger and to the OS terminal. - * - * @param p_description The code triggering the error. - * @param p_message The message to show along with the error. - * @param p_function The function name where the error occurred. - * @param p_file The file where the error occurred. - * @param p_line The line where the error occurred. - * @param p_editor_notify Whether or not to notify the editor. - */ -typedef void (*GDExtensionInterfacePrintScriptErrorWithMessage)(const char *p_description, const char *p_message, const char *p_function, const char *p_file, int32_t p_line, GDExtensionBool p_editor_notify); - -/** - * @name get_native_struct_size - * @since 4.1 - * - * Gets the size of a native struct (ex. ObjectID) in bytes. - * - * @param p_name A pointer to a StringName identifying the struct name. - * - * @return The size in bytes. - */ -typedef uint64_t (*GDExtensionInterfaceGetNativeStructSize)(GDExtensionConstStringNamePtr p_name); - -/** - * @name variant_new_copy - * @since 4.1 - * - * Copies one Variant into a another. - * - * @param r_dest A pointer to the destination Variant. - * @param p_src A pointer to the source Variant. - */ -typedef void (*GDExtensionInterfaceVariantNewCopy)(GDExtensionUninitializedVariantPtr r_dest, GDExtensionConstVariantPtr p_src); - -/** - * @name variant_new_nil - * @since 4.1 - * - * Creates a new Variant containing nil. - * - * @param r_dest A pointer to the destination Variant. - */ -typedef void (*GDExtensionInterfaceVariantNewNil)(GDExtensionUninitializedVariantPtr r_dest); - -/** - * @name variant_destroy - * @since 4.1 - * - * Destroys a Variant. - * - * @param p_self A pointer to the Variant to destroy. - */ -typedef void (*GDExtensionInterfaceVariantDestroy)(GDExtensionVariantPtr p_self); - -/** - * @name variant_call - * @since 4.1 - * - * Calls a method on a Variant. - * - * @param p_self A pointer to the Variant. - * @param p_method A pointer to a StringName identifying the method. - * @param p_args A pointer to a C array of Variant. - * @param p_argument_count The number of arguments. - * @param r_return A pointer a Variant which will be assigned the return value. - * @param r_error A pointer the structure which will hold error information. - * - * @see Variant::callp() - */ -typedef void (*GDExtensionInterfaceVariantCall)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error); - -/** - * @name variant_call_static - * @since 4.1 - * - * Calls a static method on a Variant. - * - * @param p_type The variant type. - * @param p_method A pointer to a StringName identifying the method. - * @param p_args A pointer to a C array of Variant. - * @param p_argument_count The number of arguments. - * @param r_return A pointer a Variant which will be assigned the return value. - * @param r_error A pointer the structure which will be updated with error information. - * - * @see Variant::call_static() - */ -typedef void (*GDExtensionInterfaceVariantCallStatic)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error); - -/** - * @name variant_evaluate - * @since 4.1 - * - * Evaluate an operator on two Variants. - * - * @param p_op The operator to evaluate. - * @param p_a The first Variant. - * @param p_b The second Variant. - * @param r_return A pointer a Variant which will be assigned the return value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @see Variant::evaluate() - */ -typedef void (*GDExtensionInterfaceVariantEvaluate)(GDExtensionVariantOperator p_op, GDExtensionConstVariantPtr p_a, GDExtensionConstVariantPtr p_b, GDExtensionUninitializedVariantPtr r_return, GDExtensionBool *r_valid); - -/** - * @name variant_set - * @since 4.1 - * - * Sets a key on a Variant to a value. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a Variant representing the key. - * @param p_value A pointer to a Variant representing the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @see Variant::set() - */ -typedef void (*GDExtensionInterfaceVariantSet)(GDExtensionVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid); - -/** - * @name variant_set_named - * @since 4.1 - * - * Sets a named key on a Variant to a value. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a StringName representing the key. - * @param p_value A pointer to a Variant representing the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @see Variant::set_named() - */ -typedef void (*GDExtensionInterfaceVariantSetNamed)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid); - -/** - * @name variant_set_keyed - * @since 4.1 - * - * Sets a keyed property on a Variant to a value. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a Variant representing the key. - * @param p_value A pointer to a Variant representing the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @see Variant::set_keyed() - */ -typedef void (*GDExtensionInterfaceVariantSetKeyed)(GDExtensionVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid); - -/** - * @name variant_set_indexed - * @since 4.1 - * - * Sets an index on a Variant to a value. - * - * @param p_self A pointer to the Variant. - * @param p_index The index. - * @param p_value A pointer to a Variant representing the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * @param r_oob A pointer to a boolean which will be set to true if the index is out of bounds. - */ -typedef void (*GDExtensionInterfaceVariantSetIndexed)(GDExtensionVariantPtr p_self, GDExtensionInt p_index, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid, GDExtensionBool *r_oob); - -/** - * @name variant_get - * @since 4.1 - * - * Gets the value of a key from a Variant. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a Variant representing the key. - * @param r_ret A pointer to a Variant which will be assigned the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - */ -typedef void (*GDExtensionInterfaceVariantGet)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); - -/** - * @name variant_get_named - * @since 4.1 - * - * Gets the value of a named key from a Variant. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a StringName representing the key. - * @param r_ret A pointer to a Variant which will be assigned the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - */ -typedef void (*GDExtensionInterfaceVariantGetNamed)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); - -/** - * @name variant_get_keyed - * @since 4.1 - * - * Gets the value of a keyed property from a Variant. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a Variant representing the key. - * @param r_ret A pointer to a Variant which will be assigned the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - */ -typedef void (*GDExtensionInterfaceVariantGetKeyed)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); - -/** - * @name variant_get_indexed - * @since 4.1 - * - * Gets the value of an index from a Variant. - * - * @param p_self A pointer to the Variant. - * @param p_index The index. - * @param r_ret A pointer to a Variant which will be assigned the value. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * @param r_oob A pointer to a boolean which will be set to true if the index is out of bounds. - */ -typedef void (*GDExtensionInterfaceVariantGetIndexed)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_index, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid, GDExtensionBool *r_oob); - -/** - * @name variant_iter_init - * @since 4.1 - * - * Initializes an iterator over a Variant. - * - * @param p_self A pointer to the Variant. - * @param r_iter A pointer to a Variant which will be assigned the iterator. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @return true if the operation is valid; otherwise false. - * - * @see Variant::iter_init() - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantIterInit)(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedVariantPtr r_iter, GDExtensionBool *r_valid); - -/** - * @name variant_iter_next - * @since 4.1 - * - * Gets the next value for an iterator over a Variant. - * - * @param p_self A pointer to the Variant. - * @param r_iter A pointer to a Variant which will be assigned the iterator. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @return true if the operation is valid; otherwise false. - * - * @see Variant::iter_next() - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantIterNext)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionBool *r_valid); - -/** - * @name variant_iter_get - * @since 4.1 - * - * Gets the next value for an iterator over a Variant. - * - * @param p_self A pointer to the Variant. - * @param r_iter A pointer to a Variant which will be assigned the iterator. - * @param r_ret A pointer to a Variant which will be assigned false if the operation is invalid. - * @param r_valid A pointer to a boolean which will be set to false if the operation is invalid. - * - * @see Variant::iter_get() - */ -typedef void (*GDExtensionInterfaceVariantIterGet)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); - -/** - * @name variant_hash - * @since 4.1 - * - * Gets the hash of a Variant. - * - * @param p_self A pointer to the Variant. - * - * @return The hash value. - * - * @see Variant::hash() - */ -typedef GDExtensionInt (*GDExtensionInterfaceVariantHash)(GDExtensionConstVariantPtr p_self); - -/** - * @name variant_recursive_hash - * @since 4.1 - * - * Gets the recursive hash of a Variant. - * - * @param p_self A pointer to the Variant. - * @param p_recursion_count The number of recursive loops so far. - * - * @return The hash value. - * - * @see Variant::recursive_hash() - */ -typedef GDExtensionInt (*GDExtensionInterfaceVariantRecursiveHash)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_recursion_count); - -/** - * @name variant_hash_compare - * @since 4.1 - * - * Compares two Variants by their hash. - * - * @param p_self A pointer to the Variant. - * @param p_other A pointer to the other Variant to compare it to. - * - * @return The hash value. - * - * @see Variant::hash_compare() - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantHashCompare)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_other); - -/** - * @name variant_booleanize - * @since 4.1 - * - * Converts a Variant to a boolean. - * - * @param p_self A pointer to the Variant. - * - * @return The boolean value of the Variant. - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantBooleanize)(GDExtensionConstVariantPtr p_self); - -/** - * @name variant_duplicate - * @since 4.1 - * - * Duplicates a Variant. - * - * @param p_self A pointer to the Variant. - * @param r_ret A pointer to a Variant to store the duplicated value. - * @param p_deep Whether or not to duplicate deeply (when supported by the Variant type). - */ -typedef void (*GDExtensionInterfaceVariantDuplicate)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_ret, GDExtensionBool p_deep); - -/** - * @name variant_stringify - * @since 4.1 - * - * Converts a Variant to a string. - * - * @param p_self A pointer to the Variant. - * @param r_ret A pointer to a String to store the resulting value. - */ -typedef void (*GDExtensionInterfaceVariantStringify)(GDExtensionConstVariantPtr p_self, GDExtensionStringPtr r_ret); - -/** - * @name variant_get_type - * @since 4.1 - * - * Gets the type of a Variant. - * - * @param p_self A pointer to the Variant. - * - * @return The variant type. - */ -typedef GDExtensionVariantType (*GDExtensionInterfaceVariantGetType)(GDExtensionConstVariantPtr p_self); - -/** - * @name variant_has_method - * @since 4.1 - * - * Checks if a Variant has the given method. - * - * @param p_self A pointer to the Variant. - * @param p_method A pointer to a StringName with the method name. - * - * @return true if the variant has the given method; otherwise false. - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMethod)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_method); - -/** - * @name variant_has_member - * @since 4.1 - * - * Checks if a type of Variant has the given member. - * - * @param p_type The Variant type. - * @param p_member A pointer to a StringName with the member name. - * - * @return true if the variant has the given method; otherwise false. - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member); - -/** - * @name variant_has_key - * @since 4.1 - * - * Checks if a Variant has a key. - * - * @param p_self A pointer to the Variant. - * @param p_key A pointer to a Variant representing the key. - * @param r_valid A pointer to a boolean which will be set to false if the key doesn't exist. - * - * @return true if the key exists; otherwise false. - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid); - -/** - * @name variant_get_object_instance_id - * @since 4.4 - * - * Gets the object instance ID from a variant of type GDEXTENSION_VARIANT_TYPE_OBJECT. - * - * If the variant isn't of type GDEXTENSION_VARIANT_TYPE_OBJECT, then zero will be returned. - * The instance ID will be returned even if the object is no longer valid - use `object_get_instance_by_id()` to check if the object is still valid. - * - * @param p_self A pointer to the Variant. - * - * @return The instance ID for the contained object. - */ -typedef GDObjectInstanceID (*GDExtensionInterfaceVariantGetObjectInstanceId)(GDExtensionConstVariantPtr p_self); - -/** - * @name variant_get_type_name - * @since 4.1 - * - * Gets the name of a Variant type. - * - * @param p_type The Variant type. - * @param r_name A pointer to a String to store the Variant type name. - */ -typedef void (*GDExtensionInterfaceVariantGetTypeName)(GDExtensionVariantType p_type, GDExtensionUninitializedStringPtr r_name); - -/** - * @name variant_get_type_by_name - * @since 4.7 - * - * Gets the Variant type by name. - * - * @param p_type_name The variant type name. - * - * @return The variant type for the given name; otherwise VARIANT_MAX if name is invalid. - */ -typedef GDExtensionVariantType (*GDExtensionInterfaceVariantGetTypeByName)(GDExtensionConstStringPtr p_type_name); - -/** - * @name variant_can_convert - * @since 4.1 - * - * Checks if Variants can be converted from one type to another. - * - * @param p_from The Variant type to convert from. - * @param p_to The Variant type to convert to. - * - * @return true if the conversion is possible; otherwise false. - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantCanConvert)(GDExtensionVariantType p_from, GDExtensionVariantType p_to); - -/** - * @name variant_can_convert_strict - * @since 4.1 - * - * Checks if Variant can be converted from one type to another using stricter rules. - * - * @param p_from The Variant type to convert from. - * @param p_to The Variant type to convert to. - * - * @return true if the conversion is possible; otherwise false. - */ -typedef GDExtensionBool (*GDExtensionInterfaceVariantCanConvertStrict)(GDExtensionVariantType p_from, GDExtensionVariantType p_to); - -/** - * @name get_variant_from_type_constructor - * @since 4.1 - * - * Gets a pointer to a function that can create a Variant of the given type from a raw value. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can create a Variant of the given type from a raw value. - */ -typedef GDExtensionVariantFromTypeConstructorFunc (*GDExtensionInterfaceGetVariantFromTypeConstructor)(GDExtensionVariantType p_type); - -/** - * @name get_variant_to_type_constructor - * @since 4.1 - * - * Gets a pointer to a function that can get the raw value from a Variant of the given type. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can get the raw value from a Variant of the given type. - */ -typedef GDExtensionTypeFromVariantConstructorFunc (*GDExtensionInterfaceGetVariantToTypeConstructor)(GDExtensionVariantType p_type); - -/** - * @name variant_get_ptr_internal_getter - * @since 4.4 - * - * Provides a function pointer for retrieving a pointer to a variant's internal value. - * - * Access to a variant's internal value can be used to modify it in-place, or to retrieve its value without the overhead of variant conversion functions. - * It is recommended to cache the getter for all variant types in a function table to avoid retrieval overhead upon use. - * - * Each function assumes the variant's type has already been determined and matches the function. - * Invoking the function with a variant of a mismatched type has undefined behavior, and may lead to a segmentation fault. - * - * @param p_type The Variant type. - * - * @return A pointer to a type-specific function that returns a pointer to the internal value of a variant. Check the implementation of this function (gdextension_variant_get_ptr_internal_getter) for pointee type info of each variant type. - */ -typedef GDExtensionVariantGetInternalPtrFunc (*GDExtensionInterfaceVariantGetPtrInternalGetter)(GDExtensionVariantType p_type); - -/** - * @name variant_get_ptr_operator_evaluator - * @since 4.1 - * - * Gets a pointer to a function that can evaluate the given Variant operator on the given Variant types. - * - * @param p_operator The variant operator. - * @param p_type_a The type of the first Variant. - * @param p_type_b The type of the second Variant. - * - * @return A pointer to a function that can evaluate the given Variant operator on the given Variant types. - */ -typedef GDExtensionPtrOperatorEvaluator (*GDExtensionInterfaceVariantGetPtrOperatorEvaluator)(GDExtensionVariantOperator p_operator, GDExtensionVariantType p_type_a, GDExtensionVariantType p_type_b); - -/** - * @name variant_get_ptr_builtin_method - * @since 4.1 - * - * Gets a pointer to a function that can call a builtin method on a type of Variant. - * - * @param p_type The Variant type. - * @param p_method A pointer to a StringName with the method name. - * @param p_hash A hash representing the method signature. - * - * @return A pointer to a function that can call a builtin method on a type of Variant. - */ -typedef GDExtensionPtrBuiltInMethod (*GDExtensionInterfaceVariantGetPtrBuiltinMethod)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, GDExtensionInt p_hash); - -/** - * @name variant_get_ptr_constructor - * @since 4.1 - * - * Gets a pointer to a function that can call one of the constructors for a type of Variant. - * - * @param p_type The Variant type. - * @param p_constructor The index of the constructor. - * - * @return A pointer to a function that can call one of the constructors for a type of Variant. - */ -typedef GDExtensionPtrConstructor (*GDExtensionInterfaceVariantGetPtrConstructor)(GDExtensionVariantType p_type, int32_t p_constructor); - -/** - * @name variant_get_ptr_destructor - * @since 4.1 - * - * Gets a pointer to a function than can call the destructor for a type of Variant. - * - * @param p_type The Variant type. - * - * @return A pointer to a function than can call the destructor for a type of Variant. - */ -typedef GDExtensionPtrDestructor (*GDExtensionInterfaceVariantGetPtrDestructor)(GDExtensionVariantType p_type); - -/** - * @name variant_construct - * @since 4.1 - * - * Constructs a Variant of the given type, using the first constructor that matches the given arguments. - * - * @param p_type The Variant type. - * @param r_base A pointer to a Variant to store the constructed value. - * @param p_args A pointer to a C array of Variant pointers representing the arguments for the constructor. - * @param p_argument_count The number of arguments to pass to the constructor. - * @param r_error A pointer the structure which will be updated with error information. - */ -typedef void (*GDExtensionInterfaceVariantConstruct)(GDExtensionVariantType p_type, GDExtensionUninitializedVariantPtr r_base, const GDExtensionConstVariantPtr *p_args, int32_t p_argument_count, GDExtensionCallError *r_error); - -/** - * @name variant_get_ptr_setter - * @since 4.1 - * - * Gets a pointer to a function that can call a member's setter on the given Variant type. - * - * @param p_type The Variant type. - * @param p_member A pointer to a StringName with the member name. - * - * @return A pointer to a function that can call a member's setter on the given Variant type. - */ -typedef GDExtensionPtrSetter (*GDExtensionInterfaceVariantGetPtrSetter)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member); - -/** - * @name variant_get_ptr_getter - * @since 4.1 - * - * Gets a pointer to a function that can call a member's getter on the given Variant type. - * - * @param p_type The Variant type. - * @param p_member A pointer to a StringName with the member name. - * - * @return A pointer to a function that can call a member's getter on the given Variant type. - */ -typedef GDExtensionPtrGetter (*GDExtensionInterfaceVariantGetPtrGetter)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member); - -/** - * @name variant_get_ptr_indexed_setter - * @since 4.1 - * - * Gets a pointer to a function that can set an index on the given Variant type. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can set an index on the given Variant type. - */ -typedef GDExtensionPtrIndexedSetter (*GDExtensionInterfaceVariantGetPtrIndexedSetter)(GDExtensionVariantType p_type); - -/** - * @name variant_get_ptr_indexed_getter - * @since 4.1 - * - * Gets a pointer to a function that can get an index on the given Variant type. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can get an index on the given Variant type. - */ -typedef GDExtensionPtrIndexedGetter (*GDExtensionInterfaceVariantGetPtrIndexedGetter)(GDExtensionVariantType p_type); - -/** - * @name variant_get_ptr_keyed_setter - * @since 4.1 - * - * Gets a pointer to a function that can set a key on the given Variant type. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can set a key on the given Variant type. - */ -typedef GDExtensionPtrKeyedSetter (*GDExtensionInterfaceVariantGetPtrKeyedSetter)(GDExtensionVariantType p_type); - -/** - * @name variant_get_ptr_keyed_getter - * @since 4.1 - * - * Gets a pointer to a function that can get a key on the given Variant type. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can get a key on the given Variant type. - */ -typedef GDExtensionPtrKeyedGetter (*GDExtensionInterfaceVariantGetPtrKeyedGetter)(GDExtensionVariantType p_type); - -/** - * @name variant_get_ptr_keyed_checker - * @since 4.1 - * - * Gets a pointer to a function that can check a key on the given Variant type. - * - * @param p_type The Variant type. - * - * @return A pointer to a function that can check a key on the given Variant type. - */ -typedef GDExtensionPtrKeyedChecker (*GDExtensionInterfaceVariantGetPtrKeyedChecker)(GDExtensionVariantType p_type); - -/** - * @name variant_get_constant_value - * @since 4.1 - * - * Gets the value of a constant from the given Variant type. - * - * @param p_type The Variant type. - * @param p_constant A pointer to a StringName with the constant name. - * @param r_ret A pointer to a Variant to store the value. - */ -typedef void (*GDExtensionInterfaceVariantGetConstantValue)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_constant, GDExtensionUninitializedVariantPtr r_ret); - -/** - * @name variant_get_ptr_utility_function - * @since 4.1 - * - * Gets a pointer to a function that can call a Variant utility function. - * - * @param p_function A pointer to a StringName with the function name. - * @param p_hash A hash representing the function signature. - * - * @return A pointer to a function that can call a Variant utility function. - */ -typedef GDExtensionPtrUtilityFunction (*GDExtensionInterfaceVariantGetPtrUtilityFunction)(GDExtensionConstStringNamePtr p_function, GDExtensionInt p_hash); - -/** - * @name string_new_with_latin1_chars - * @since 4.1 - * - * Creates a String from a Latin-1 encoded C string. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a Latin-1 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringNewWithLatin1Chars)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents); - -/** - * @name string_new_with_utf8_chars - * @since 4.1 - * - * Creates a String from a UTF-8 encoded C string. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-8 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringNewWithUtf8Chars)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents); - -/** - * @name string_new_with_utf16_chars - * @since 4.1 - * - * Creates a String from a UTF-16 encoded C string. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-16 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringNewWithUtf16Chars)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents); - -/** - * @name string_new_with_utf32_chars - * @since 4.1 - * - * Creates a String from a UTF-32 encoded C string. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-32 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringNewWithUtf32Chars)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents); - -/** - * @name string_new_with_wide_chars - * @since 4.1 - * - * Creates a String from a wide C string. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a wide C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringNewWithWideChars)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents); - -/** - * @name string_new_with_latin1_chars_and_len - * @since 4.1 - * - * Creates a String from a Latin-1 encoded C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a Latin-1 encoded C string. - * @param p_size The number of characters (= number of bytes). - */ -typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); - -/** - * @name string_new_with_utf8_chars_and_len - * @since 4.1 - * @deprecated Deprecated in Godot 4.3. Use `string_new_with_utf8_chars_and_len2` instead. - * - * Creates a String from a UTF-8 encoded C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-8 encoded C string. - * @param p_size The number of bytes (not code units). - */ -typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); - -/** - * @name string_new_with_utf8_chars_and_len2 - * @since 4.3 - * - * Creates a String from a UTF-8 encoded C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-8 encoded C string. - * @param p_size The number of bytes (not code units). - * - * @return Error code signifying if the operation successful. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen2)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); - -/** - * @name string_new_with_utf16_chars_and_len - * @since 4.1 - * @deprecated Deprecated in Godot 4.3. Use `string_new_with_utf16_chars_and_len2` instead. - * - * Creates a String from a UTF-16 encoded C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-16 encoded C string. - * @param p_char_count The number of characters (not bytes). - */ -typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count); - -/** - * @name string_new_with_utf16_chars_and_len2 - * @since 4.3 - * - * Creates a String from a UTF-16 encoded C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-16 encoded C string. - * @param p_char_count The number of characters (not bytes). - * @param p_default_little_endian If true, UTF-16 use little endian. - * - * @return Error code signifying if the operation successful. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen2)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian); - -/** - * @name string_new_with_utf32_chars_and_len - * @since 4.1 - * - * Creates a String from a UTF-32 encoded C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a UTF-32 encoded C string. - * @param p_char_count The number of characters (not bytes). - */ -typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_char_count); - -/** - * @name string_new_with_wide_chars_and_len - * @since 4.1 - * - * Creates a String from a wide C string with the given length. - * - * @param r_dest A pointer to a Variant to hold the newly created String. - * @param p_contents A pointer to a wide C string. - * @param p_char_count The number of characters (not bytes). - */ -typedef void (*GDExtensionInterfaceStringNewWithWideCharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_char_count); - -/** - * @name string_to_latin1_chars - * @since 4.1 - * - * Converts a String to a Latin-1 encoded C string. - * - * It doesn't write a null terminator. - * - * @param p_self A pointer to the String. - * @param r_text A pointer to the buffer to hold the resulting data. If NULL is passed in, only the length will be computed. - * @param p_max_write_length The maximum number of characters that can be written to r_text. It has no affect on the return value. - * - * @return The resulting encoded string length in characters, not including a null terminator. Characters that cannot be converted to Latin-1 are replaced with a space. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringToLatin1Chars)(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length); - -/** - * @name string_to_utf8_chars - * @since 4.1 - * - * Converts a String to a UTF-8 encoded C string. - * - * It doesn't write a null terminator. - * - * @param p_self A pointer to the String. - * @param r_text A pointer to the buffer to hold the resulting data. If NULL is passed in, only the length will be computed. - * @param p_max_write_length The maximum number of characters that can be written to r_text. It has no affect on the return value. - * - * @return The resulting encoded string length in bytes (not characters), not including a null terminator. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf8Chars)(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length); - -/** - * @name string_to_utf16_chars - * @since 4.1 - * - * Converts a String to a UTF-16 encoded C string. - * - * It doesn't write a null terminator. - * - * @param p_self A pointer to the String. - * @param r_text A pointer to the buffer to hold the resulting data. If NULL is passed in, only the length will be computed. - * @param p_max_write_length The maximum number of characters that can be written to r_text. It has no affect on the return value. - * - * @return The resulting encoded string length in 16-bit code units (not bytes or characters), not including a null terminator. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf16Chars)(GDExtensionConstStringPtr p_self, char16_t *r_text, GDExtensionInt p_max_write_length); - -/** - * @name string_to_utf32_chars - * @since 4.1 - * - * Converts a String to a UTF-32 encoded C string. - * - * It doesn't write a null terminator. - * - * @param p_self A pointer to the String. - * @param r_text A pointer to the buffer to hold the resulting data. If NULL is passed in, only the length will be computed. - * @param p_max_write_length The maximum number of characters that can be written to r_text. It has no affect on the return value. - * - * @return The resulting encoded string length in characters (not bytes), not including a null terminator. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf32Chars)(GDExtensionConstStringPtr p_self, char32_t *r_text, GDExtensionInt p_max_write_length); - -/** - * @name string_to_wide_chars - * @since 4.1 - * - * Converts a String to a wide C string. - * - * It doesn't write a null terminator. - * - * @param p_self A pointer to the String. - * @param r_text A pointer to the buffer to hold the resulting data. If NULL is passed in, only the length will be computed. - * @param p_max_write_length The maximum number of characters that can be written to r_text. It has no affect on the return value. - * - * @return The resulting encoded string length in characters (for UTF-32) or 16-bit code units (for UTF-16), depending on the wchar_t representation. Does not include a null terminator. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringToWideChars)(GDExtensionConstStringPtr p_self, wchar_t *r_text, GDExtensionInt p_max_write_length); - -/** - * @name string_operator_index - * @since 4.1 - * - * Gets a pointer to the character at the given index from a String. - * - * @param p_self A pointer to the String. - * @param p_index The index. - * - * @return A pointer to the requested character. - */ -typedef char32_t *(*GDExtensionInterfaceStringOperatorIndex)(GDExtensionStringPtr p_self, GDExtensionInt p_index); - -/** - * @name string_operator_index_const - * @since 4.1 - * - * Gets a const pointer to the character at the given index from a String. - * - * @param p_self A pointer to the String. - * @param p_index The index. - * - * @return A const pointer to the requested character. - */ -typedef const char32_t *(*GDExtensionInterfaceStringOperatorIndexConst)(GDExtensionConstStringPtr p_self, GDExtensionInt p_index); - -/** - * @name string_operator_plus_eq_string - * @since 4.1 - * - * Appends another String to a String. - * - * @param p_self A pointer to the String. - * @param p_b A pointer to the other String to append. - */ -typedef void (*GDExtensionInterfaceStringOperatorPlusEqString)(GDExtensionStringPtr p_self, GDExtensionConstStringPtr p_b); - -/** - * @name string_operator_plus_eq_char - * @since 4.1 - * - * Appends a character to a String. - * - * @param p_self A pointer to the String. - * @param p_b A pointer to the character to append. - */ -typedef void (*GDExtensionInterfaceStringOperatorPlusEqChar)(GDExtensionStringPtr p_self, char32_t p_b); - -/** - * @name string_operator_plus_eq_cstr - * @since 4.1 - * - * Appends a Latin-1 encoded C string to a String. - * - * @param p_self A pointer to the String. - * @param p_b A pointer to a Latin-1 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringOperatorPlusEqCstr)(GDExtensionStringPtr p_self, const char *p_b); - -/** - * @name string_operator_plus_eq_wcstr - * @since 4.1 - * - * Appends a wide C string to a String. - * - * @param p_self A pointer to the String. - * @param p_b A pointer to a wide C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringOperatorPlusEqWcstr)(GDExtensionStringPtr p_self, const wchar_t *p_b); - -/** - * @name string_operator_plus_eq_c32str - * @since 4.1 - * - * Appends a UTF-32 encoded C string to a String. - * - * @param p_self A pointer to the String. - * @param p_b A pointer to a UTF-32 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionStringPtr p_self, const char32_t *p_b); - -/** - * @name string_resize - * @since 4.2 - * - * Resizes the underlying string data to the given number of characters. - * - * Space needs to be allocated for the null terminating character ('\0') which - * also must be added manually, in order for all string functions to work correctly. - * - * Warning: This is an error-prone operation - only use it if there's no other - * efficient way to accomplish your goal. - * - * @param p_self A pointer to the String. - * @param p_resize The new length for the String. - * - * @return Error code signifying if the operation successful. - */ -typedef GDExtensionInt (*GDExtensionInterfaceStringResize)(GDExtensionStringPtr p_self, GDExtensionInt p_resize); - -/** - * @name string_name_new_with_latin1_chars - * @since 4.2 - * - * Creates a StringName from a Latin-1 encoded C string. - * - * If `p_is_static` is true, then: - * - The StringName will reuse the `p_contents` buffer instead of copying it. - * - You must guarantee that the buffer remains valid for the duration of the application (e.g. string literal). - * - You must not call a destructor for this StringName. Incrementing the initial reference once should achieve this. - * - * `p_is_static` is purely an optimization and can easily introduce undefined behavior if used wrong. In case of doubt, set it to false. - * - * @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed. - * @param p_contents A pointer to a C string (null terminated and Latin-1 or ASCII encoded). - * @param p_is_static Whether the StringName reuses the buffer directly (see above). - */ -typedef void (*GDExtensionInterfaceStringNameNewWithLatin1Chars)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionBool p_is_static); - -/** - * @name string_name_new_with_utf8_chars - * @since 4.2 - * - * Creates a StringName from a UTF-8 encoded C string. - * - * @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed. - * @param p_contents A pointer to a C string (null terminated and UTF-8 encoded). - */ -typedef void (*GDExtensionInterfaceStringNameNewWithUtf8Chars)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents); - -/** - * @name string_name_new_with_utf8_chars_and_len - * @since 4.2 - * - * Creates a StringName from a UTF-8 encoded string with a given number of characters. - * - * @param r_dest A pointer to uninitialized storage, into which the newly created StringName is constructed. - * @param p_contents A pointer to a C string (null terminated and UTF-8 encoded). - * @param p_size The number of bytes (not UTF-8 code points). - */ -typedef void (*GDExtensionInterfaceStringNameNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringNamePtr r_dest, const char *p_contents, GDExtensionInt p_size); - -/** - * @name xml_parser_open_buffer - * @since 4.1 - * - * Opens a raw XML buffer on an XMLParser instance. - * - * @param p_instance A pointer to an XMLParser object. - * @param p_buffer A pointer to the buffer. - * @param p_size The size of the buffer. - * - * @return A Godot error code (ex. OK, ERR_INVALID_DATA, etc). - * - * @see XMLParser::open_buffer() - */ -typedef GDExtensionInt (*GDExtensionInterfaceXmlParserOpenBuffer)(GDExtensionObjectPtr p_instance, const uint8_t *p_buffer, size_t p_size); - -/** - * @name file_access_store_buffer - * @since 4.1 - * - * Stores the given buffer using an instance of FileAccess. - * - * @param p_instance A pointer to a FileAccess object. - * @param p_src A pointer to the buffer. - * @param p_length The size of the buffer. - * - * @see FileAccess::store_buffer() - */ -typedef void (*GDExtensionInterfaceFileAccessStoreBuffer)(GDExtensionObjectPtr p_instance, const uint8_t *p_src, uint64_t p_length); - -/** - * @name file_access_get_buffer - * @since 4.1 - * - * Reads the next p_length bytes into the given buffer using an instance of FileAccess. - * - * @param p_instance A pointer to a FileAccess object. - * @param p_dst A pointer to the buffer to store the data. - * @param p_length The requested number of bytes to read. - * - * @return The actual number of bytes read (may be less than requested). - */ -typedef uint64_t (*GDExtensionInterfaceFileAccessGetBuffer)(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length); - -/** - * @name image_ptrw - * @since 4.3 - * - * Returns writable pointer to internal Image buffer. - * - * @param p_instance A pointer to a Image object. - * - * @return Pointer to internal Image buffer. - * - * @see Image::ptrw() - */ -typedef uint8_t *(*GDExtensionInterfaceImagePtrw)(GDExtensionObjectPtr p_instance); - -/** - * @name image_ptr - * @since 4.3 - * - * Returns read only pointer to internal Image buffer. - * - * @param p_instance A pointer to a Image object. - * - * @return Pointer to internal Image buffer. - * - * @see Image::ptr() - */ -typedef const uint8_t *(*GDExtensionInterfaceImagePtr)(GDExtensionObjectPtr p_instance); - -/** - * @name worker_thread_pool_add_native_group_task - * @since 4.1 - * - * Adds a group task to an instance of WorkerThreadPool. - * - * @param p_instance A pointer to a WorkerThreadPool object. - * @param p_func A pointer to a function to run in the thread pool. - * @param p_userdata A pointer to arbitrary data which will be passed to p_func. - * @param p_elements The number of element needed in the group. - * @param p_tasks The number of tasks needed in the group. - * @param p_high_priority Whether or not this is a high priority task. - * @param p_description A pointer to a String with the task description. - * - * @return The task group ID. - * - * @see WorkerThreadPool::add_group_task() - */ -typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask)(GDExtensionObjectPtr p_instance, GDExtensionWorkerThreadPoolGroupTask p_func, void *p_userdata, int32_t p_elements, int32_t p_tasks, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description); - -/** - * @name worker_thread_pool_add_native_task - * @since 4.1 - * - * Adds a task to an instance of WorkerThreadPool. - * - * @param p_instance A pointer to a WorkerThreadPool object. - * @param p_func A pointer to a function to run in the thread pool. - * @param p_userdata A pointer to arbitrary data which will be passed to p_func. - * @param p_high_priority Whether or not this is a high priority task. - * @param p_description A pointer to a String with the task description. - * - * @return The task ID. - */ -typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeTask)(GDExtensionObjectPtr p_instance, GDExtensionWorkerThreadPoolTask p_func, void *p_userdata, GDExtensionBool p_high_priority, GDExtensionConstStringPtr p_description); - -/** - * @name packed_byte_array_operator_index - * @since 4.1 - * - * Gets a pointer to a byte in a PackedByteArray. - * - * @param p_self A pointer to a PackedByteArray object. - * @param p_index The index of the byte to get. - * - * @return A pointer to the requested byte. - */ -typedef uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_byte_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a byte in a PackedByteArray. - * - * @param p_self A const pointer to a PackedByteArray object. - * @param p_index The index of the byte to get. - * - * @return A const pointer to the requested byte. - */ -typedef const uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_float32_array_operator_index - * @since 4.1 - * - * Gets a pointer to a 32-bit float in a PackedFloat32Array. - * - * @param p_self A pointer to a PackedFloat32Array object. - * @param p_index The index of the float to get. - * - * @return A pointer to the requested 32-bit float. - */ -typedef float *(*GDExtensionInterfacePackedFloat32ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_float32_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a 32-bit float in a PackedFloat32Array. - * - * @param p_self A const pointer to a PackedFloat32Array object. - * @param p_index The index of the float to get. - * - * @return A const pointer to the requested 32-bit float. - */ -typedef const float *(*GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_float64_array_operator_index - * @since 4.1 - * - * Gets a pointer to a 64-bit float in a PackedFloat64Array. - * - * @param p_self A pointer to a PackedFloat64Array object. - * @param p_index The index of the float to get. - * - * @return A pointer to the requested 64-bit float. - */ -typedef double *(*GDExtensionInterfacePackedFloat64ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_float64_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a 64-bit float in a PackedFloat64Array. - * - * @param p_self A const pointer to a PackedFloat64Array object. - * @param p_index The index of the float to get. - * - * @return A const pointer to the requested 64-bit float. - */ -typedef const double *(*GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_int32_array_operator_index - * @since 4.1 - * - * Gets a pointer to a 32-bit integer in a PackedInt32Array. - * - * @param p_self A pointer to a PackedInt32Array object. - * @param p_index The index of the integer to get. - * - * @return A pointer to the requested 32-bit integer. - */ -typedef int32_t *(*GDExtensionInterfacePackedInt32ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_int32_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a 32-bit integer in a PackedInt32Array. - * - * @param p_self A const pointer to a PackedInt32Array object. - * @param p_index The index of the integer to get. - * - * @return A const pointer to the requested 32-bit integer. - */ -typedef const int32_t *(*GDExtensionInterfacePackedInt32ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_int64_array_operator_index - * @since 4.1 - * - * Gets a pointer to a 64-bit integer in a PackedInt64Array. - * - * @param p_self A pointer to a PackedInt64Array object. - * @param p_index The index of the integer to get. - * - * @return A pointer to the requested 64-bit integer. - */ -typedef int64_t *(*GDExtensionInterfacePackedInt64ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_int64_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a 64-bit integer in a PackedInt64Array. - * - * @param p_self A const pointer to a PackedInt64Array object. - * @param p_index The index of the integer to get. - * - * @return A const pointer to the requested 64-bit integer. - */ -typedef const int64_t *(*GDExtensionInterfacePackedInt64ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_string_array_operator_index - * @since 4.1 - * - * Gets a pointer to a string in a PackedStringArray. - * - * @param p_self A pointer to a PackedStringArray object. - * @param p_index The index of the String to get. - * - * @return A pointer to the requested String. - */ -typedef GDExtensionStringPtr (*GDExtensionInterfacePackedStringArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_string_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a string in a PackedStringArray. - * - * @param p_self A const pointer to a PackedStringArray object. - * @param p_index The index of the String to get. - * - * @return A const pointer to the requested String. - */ -typedef GDExtensionStringPtr (*GDExtensionInterfacePackedStringArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_vector2_array_operator_index - * @since 4.1 - * - * Gets a pointer to a Vector2 in a PackedVector2Array. - * - * @param p_self A pointer to a PackedVector2Array object. - * @param p_index The index of the Vector2 to get. - * - * @return A pointer to the requested Vector2. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector2ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_vector2_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a Vector2 in a PackedVector2Array. - * - * @param p_self A const pointer to a PackedVector2Array object. - * @param p_index The index of the Vector2 to get. - * - * @return A const pointer to the requested Vector2. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector2ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_vector3_array_operator_index - * @since 4.1 - * - * Gets a pointer to a Vector3 in a PackedVector3Array. - * - * @param p_self A pointer to a PackedVector3Array object. - * @param p_index The index of the Vector3 to get. - * - * @return A pointer to the requested Vector3. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_vector3_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a Vector3 in a PackedVector3Array. - * - * @param p_self A const pointer to a PackedVector3Array object. - * @param p_index The index of the Vector3 to get. - * - * @return A const pointer to the requested Vector3. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_vector4_array_operator_index - * @since 4.3 - * - * Gets a pointer to a Vector4 in a PackedVector4Array. - * - * @param p_self A pointer to a PackedVector4Array object. - * @param p_index The index of the Vector4 to get. - * - * @return A pointer to the requested Vector4. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_vector4_array_operator_index_const - * @since 4.3 - * - * Gets a const pointer to a Vector4 in a PackedVector4Array. - * - * @param p_self A const pointer to a PackedVector4Array object. - * @param p_index The index of the Vector4 to get. - * - * @return A const pointer to the requested Vector4. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_color_array_operator_index - * @since 4.1 - * - * Gets a pointer to a color in a PackedColorArray. - * - * @param p_self A pointer to a PackedColorArray object. - * @param p_index The index of the Color to get. - * - * @return A pointer to the requested Color. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name packed_color_array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a color in a PackedColorArray. - * - * @param p_self A const pointer to a PackedColorArray object. - * @param p_index The index of the Color to get. - * - * @return A const pointer to the requested Color. - */ -typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name array_operator_index - * @since 4.1 - * - * Gets a pointer to a Variant in an Array. - * - * @param p_self A pointer to an Array object. - * @param p_index The index of the Variant to get. - * - * @return A pointer to the requested Variant. - */ -typedef GDExtensionVariantPtr (*GDExtensionInterfaceArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index); - -/** - * @name array_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a Variant in an Array. - * - * @param p_self A const pointer to an Array object. - * @param p_index The index of the Variant to get. - * - * @return A const pointer to the requested Variant. - */ -typedef GDExtensionVariantPtr (*GDExtensionInterfaceArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); - -/** - * @name array_ref - * @since 4.1 - * @deprecated Deprecated in Godot 4.5. Removed from interface. Use copy constructor instead. - * - * Sets an Array to be a reference to another Array object. - * - * @param p_self A pointer to the Array object to update. - * @param p_from A pointer to the Array object to reference. - */ -typedef void (*GDExtensionInterfaceArrayRef)(GDExtensionTypePtr p_self, GDExtensionConstTypePtr p_from); - -/** - * @name array_set_typed - * @since 4.1 - * - * Makes an Array into a typed Array. - * - * @param p_self A pointer to the Array. - * @param p_type The type of Variant the Array will store. - * @param p_class_name A pointer to a StringName with the name of the object (if p_type is GDEXTENSION_VARIANT_TYPE_OBJECT). - * @param p_script A pointer to a Script object (if p_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script). - */ -typedef void (*GDExtensionInterfaceArraySetTyped)(GDExtensionTypePtr p_self, GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstVariantPtr p_script); - -/** - * @name dictionary_operator_index - * @since 4.1 - * - * Gets a pointer to a Variant in a Dictionary with the given key. - * - * @param p_self A pointer to a Dictionary object. - * @param p_key A pointer to a Variant representing the key. - * - * @return A pointer to a Variant representing the value at the given key. - */ -typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionConstVariantPtr p_key); - -/** - * @name dictionary_operator_index_const - * @since 4.1 - * - * Gets a const pointer to a Variant in a Dictionary with the given key. - * - * @param p_self A const pointer to a Dictionary object. - * @param p_key A pointer to a Variant representing the key. - * - * @return A const pointer to a Variant representing the value at the given key. - */ -typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionConstVariantPtr p_key); - -/** - * @name dictionary_set_typed - * @since 4.4 - * - * Makes a Dictionary into a typed Dictionary. - * - * @param p_self A pointer to the Dictionary. - * @param p_key_type The type of Variant the Dictionary key will store. - * @param p_key_class_name A pointer to a StringName with the name of the object (if p_key_type is GDEXTENSION_VARIANT_TYPE_OBJECT). - * @param p_key_script A pointer to a Script object (if p_key_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script). - * @param p_value_type The type of Variant the Dictionary value will store. - * @param p_value_class_name A pointer to a StringName with the name of the object (if p_value_type is GDEXTENSION_VARIANT_TYPE_OBJECT). - * @param p_value_script A pointer to a Script object (if p_value_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script). - */ -typedef void (*GDExtensionInterfaceDictionarySetTyped)(GDExtensionTypePtr p_self, GDExtensionVariantType p_key_type, GDExtensionConstStringNamePtr p_key_class_name, GDExtensionConstVariantPtr p_key_script, GDExtensionVariantType p_value_type, GDExtensionConstStringNamePtr p_value_class_name, GDExtensionConstVariantPtr p_value_script); - -/** - * @name object_method_bind_call - * @since 4.1 - * - * Calls a method on an Object. - * - * @param p_method_bind A pointer to the MethodBind representing the method on the Object's class. - * @param p_instance A pointer to the Object. - * @param p_args A pointer to a C array of Variants representing the arguments. - * @param p_arg_count The number of arguments. - * @param r_ret A pointer to Variant which will receive the return value. - * @param r_error A pointer to a GDExtensionCallError struct that will receive error information. - */ -typedef void (*GDExtensionInterfaceObjectMethodBindCall)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionUninitializedVariantPtr r_ret, GDExtensionCallError *r_error); - -/** - * @name object_method_bind_ptrcall - * @since 4.1 - * - * Calls a method on an Object (using a "ptrcall"). - * - * @param p_method_bind A pointer to the MethodBind representing the method on the Object's class. - * @param p_instance A pointer to the Object. - * @param p_args A pointer to a C array representing the arguments. - * @param r_ret A pointer to the Object that will receive the return value. - */ -typedef void (*GDExtensionInterfaceObjectMethodBindPtrcall)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); - -/** - * @name object_destroy - * @since 4.1 - * - * Destroys an Object. - * - * @param p_o A pointer to the Object. - */ -typedef void (*GDExtensionInterfaceObjectDestroy)(GDExtensionObjectPtr p_o); - -/** - * @name global_get_singleton - * @since 4.1 - * - * Gets a global singleton by name. - * - * @param p_name A pointer to a StringName with the singleton name. - * - * @return A pointer to the singleton Object. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceGlobalGetSingleton)(GDExtensionConstStringNamePtr p_name); - -/** - * @name object_get_instance_binding - * @since 4.1 - * - * Gets a pointer representing an Object's instance binding. - * - * @param p_o A pointer to the Object. - * @param p_token A token the library received by the GDExtension's entry point function. - * @param p_callbacks A pointer to a GDExtensionInstanceBindingCallbacks struct. - * - * @return A pointer to the instance binding. - */ -typedef void *(*GDExtensionInterfaceObjectGetInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks); - -/** - * @name object_set_instance_binding - * @since 4.1 - * - * Sets an Object's instance binding. - * - * @param p_o A pointer to the Object. - * @param p_token A token the library received by the GDExtension's entry point function. - * @param p_binding A pointer to the instance binding. - * @param p_callbacks A pointer to a GDExtensionInstanceBindingCallbacks struct. - */ -typedef void (*GDExtensionInterfaceObjectSetInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks); - -/** - * @name object_free_instance_binding - * @since 4.2 - * - * Free an Object's instance binding. - * - * @param p_o A pointer to the Object. - * @param p_token A token the library received by the GDExtension's entry point function. - */ -typedef void (*GDExtensionInterfaceObjectFreeInstanceBinding)(GDExtensionObjectPtr p_o, void *p_token); - -/** - * @name object_set_instance - * @since 4.1 - * - * Sets an extension class instance on a Object. - * - * `p_classname` should be a registered extension class and should extend the `p_o` Object's class. - * - * @param p_o A pointer to the Object. - * @param p_classname A pointer to a StringName with the registered extension class's name. - * @param p_instance A pointer to the extension class instance. - */ -typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); - -/** - * @name object_get_class_name - * @since 4.1 - * - * Gets the class name of an Object. - * - * If the GDExtension wraps the Godot object in an abstraction specific to its class, this is the - * function that should be used to determine which wrapper to use. - * - * @param p_object A pointer to the Object. - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param r_class_name A pointer to a String to receive the class name. - * - * @return true if successful in getting the class name; otherwise false. - */ -typedef GDExtensionBool (*GDExtensionInterfaceObjectGetClassName)(GDExtensionConstObjectPtr p_object, GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringNamePtr r_class_name); - -/** - * @name object_cast_to - * @since 4.1 - * @deprecated Deprecated in Godot 4.7. Use the `is_class` method on `Object` to check if an object can be cast instead. If true, the previous pointer can be reinterpreted as a pointer to the target type. - * - * Casts an Object to a different type. - * - * @param p_object A pointer to the Object. - * @param p_class_tag A pointer uniquely identifying a built-in class in the ClassDB. - * - * @return Returns a pointer to the Object, or NULL if it can't be cast to the requested type. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectCastTo)(GDExtensionConstObjectPtr p_object, void *p_class_tag); - -/** - * @name object_get_instance_from_id - * @since 4.1 - * - * Gets an Object by its instance ID. - * - * @param p_instance_id The instance ID. - * - * @return A pointer to the Object. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectGetInstanceFromId)(GDObjectInstanceID p_instance_id); - -/** - * @name object_get_instance_id - * @since 4.1 - * - * Gets the instance ID from an Object. - * - * @param p_object A pointer to the Object. - * - * @return The instance ID. - */ -typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensionConstObjectPtr p_object); - -/** - * @name object_has_script_method - * @since 4.3 - * - * Checks if this object has a script with the given method. - * - * @param p_object A pointer to the Object. - * @param p_method A pointer to a StringName identifying the method. - * - * @return true if the object has a script and that script has a method with the given name. Returns false if the object has no script. - */ -typedef GDExtensionBool (*GDExtensionInterfaceObjectHasScriptMethod)(GDExtensionConstObjectPtr p_object, GDExtensionConstStringNamePtr p_method); - -/** - * @name object_call_script_method - * @since 4.3 - * - * Call the given script method on this object. - * - * @param p_object A pointer to the Object. - * @param p_method A pointer to a StringName identifying the method. - * @param p_args A pointer to a C array of Variant. - * @param p_argument_count The number of arguments. - * @param r_return A pointer a Variant which will be assigned the return value. - * @param r_error A pointer the structure which will hold error information. - */ -typedef void (*GDExtensionInterfaceObjectCallScriptMethod)(GDExtensionObjectPtr p_object, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error); - -/** - * @name ref_get_object - * @since 4.1 - * - * Gets the Object from a reference. - * - * @param p_ref A pointer to the reference. - * - * @return A pointer to the Object from the reference or NULL. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceRefGetObject)(GDExtensionConstRefPtr p_ref); - -/** - * @name ref_set_object - * @since 4.1 - * - * Sets the Object referred to by a reference. - * - * @param p_ref A pointer to the reference. - * @param p_object A pointer to the Object to refer to. - */ -typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExtensionObjectPtr p_object); - -/** - * @name script_instance_create - * @since 4.1 - * @deprecated Deprecated in Godot 4.2. Use `script_instance_create3` instead. - * - * Creates a script instance that contains the given info and instance data. - * - * @param p_info A pointer to a GDExtensionScriptInstanceInfo struct. - * @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info. - * - * @return A pointer to a ScriptInstanceExtension object. - */ -typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data); - -/** - * @name script_instance_create2 - * @since 4.2 - * @deprecated Deprecated in Godot 4.3. Use `script_instance_create3` instead. - * - * Creates a script instance that contains the given info and instance data. - * - * @param p_info A pointer to a GDExtensionScriptInstanceInfo2 struct. - * @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info. - * - * @return A pointer to a ScriptInstanceExtension object. - */ -typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data); - -/** - * @name script_instance_create3 - * @since 4.3 - * - * Creates a script instance that contains the given info and instance data. - * - * @param p_info A pointer to a GDExtensionScriptInstanceInfo3 struct. - * @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info. - * - * @return A pointer to a ScriptInstanceExtension object. - */ -typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate3)(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data); - -/** - * @name placeholder_script_instance_create - * @since 4.2 - * - * Creates a placeholder script instance for a given script and instance. - * - * This interface is optional as a custom placeholder could also be created with script_instance_create(). - * - * @param p_language A pointer to a ScriptLanguage. - * @param p_script A pointer to a Script. - * @param p_owner A pointer to an Object. - * - * @return A pointer to a PlaceHolderScriptInstance object. - */ -typedef GDExtensionScriptInstancePtr (*GDExtensionInterfacePlaceholderScriptInstanceCreate)(GDExtensionObjectPtr p_language, GDExtensionObjectPtr p_script, GDExtensionObjectPtr p_owner); - -/** - * @name placeholder_script_instance_update - * @since 4.2 - * - * Updates a placeholder script instance with the given properties and values. - * - * The passed in placeholder must be an instance of PlaceHolderScriptInstance - * such as the one returned by placeholder_script_instance_create(). - * - * @param p_placeholder A pointer to a PlaceHolderScriptInstance. - * @param p_properties A pointer to an Array of Dictionary representing PropertyInfo. - * @param p_values A pointer to a Dictionary mapping StringName to Variant values. - */ -typedef void (*GDExtensionInterfacePlaceholderScriptInstanceUpdate)(GDExtensionScriptInstancePtr p_placeholder, GDExtensionConstTypePtr p_properties, GDExtensionConstTypePtr p_values); - -/** - * @name object_get_script_instance - * @since 4.2 - * - * Get the script instance data attached to this object. - * - * @param p_object A pointer to the Object. - * @param p_language A pointer to the language expected for this script instance. - * - * @return A GDExtensionScriptInstanceDataPtr that was attached to this object as part of script_instance_create. - */ -typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptInstance)(GDExtensionConstObjectPtr p_object, GDExtensionObjectPtr p_language); - -/** - * @name object_set_script_instance - * @since 4.5 - * - * Set the script instance data attached to this object. - * - * @param p_object A pointer to the Object. - * @param p_script_instance A pointer to the script instance data to attach to this object. - */ -typedef void (*GDExtensionInterfaceObjectSetScriptInstance)(GDExtensionObjectPtr p_object, GDExtensionScriptInstanceDataPtr p_script_instance); - -/** - * @name callable_custom_create - * @since 4.2 - * @deprecated Deprecated in Godot 4.3. Use `callable_custom_create2` instead. - * - * Creates a custom Callable object from a function pointer. - * - * Provided struct can be safely freed once the function returns. - * - * @param r_callable A pointer that will receive the new Callable. - * @param p_callable_custom_info The info required to construct a Callable. - */ -typedef void (*GDExtensionInterfaceCallableCustomCreate)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_callable_custom_info); - -/** - * @name callable_custom_create2 - * @since 4.3 - * - * Creates a custom Callable object from a function pointer. - * - * Provided struct can be safely freed once the function returns. - * - * @param r_callable A pointer that will receive the new Callable. - * @param p_callable_custom_info The info required to construct a Callable. - */ -typedef void (*GDExtensionInterfaceCallableCustomCreate2)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo2 *p_callable_custom_info); - -/** - * @name callable_custom_get_userdata - * @since 4.2 - * - * Retrieves the userdata pointer from a custom Callable. - * - * If the Callable is not a custom Callable or the token does not match the one provided to callable_custom_create() via GDExtensionCallableCustomInfo then NULL will be returned. - * - * @param p_callable A pointer to a Callable. - * @param p_token A pointer to an address that uniquely identifies the GDExtension. - * - * @return The userdata pointer given when creating this custom Callable. - */ -typedef void *(*GDExtensionInterfaceCallableCustomGetUserdata)(GDExtensionConstTypePtr p_callable, void *p_token); - -/** - * @name classdb_construct_object - * @since 4.1 - * @deprecated Deprecated in Godot 4.4. Use `classdb_construct_object3` instead. - * - * Constructs an Object of the requested class. - * - * The passed class must be a built-in godot class, or an already-registered extension class. In both cases, object_set_instance() should be called to fully initialize the object. - * - * @param p_classname A pointer to a StringName with the class name. - * - * @return A pointer to the newly created Object. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExtensionConstStringNamePtr p_classname); - -/** - * @name classdb_construct_object2 - * @since 4.4 - * @deprecated Deprecated in Godot 4.7. Use `classdb_construct_object3` instead. - * - * Constructs an Object of the requested class. - * - * The passed class must be a built-in godot class, or an already-registered extension class. In both cases, object_set_instance() should be called to fully initialize the object. - * - * "NOTIFICATION_POSTINITIALIZE" must be sent after construction. - * - * @param p_classname A pointer to a StringName with the class name. - * - * @return A pointer to the newly created Object. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject2)(GDExtensionConstStringNamePtr p_classname); - -/** - * @name classdb_construct_object3 - * @since 4.7 - * - * Constructs an Object of the requested class. - * - * The passed class must be a built-in godot class, or an already-registered extension class. In both cases, object_set_instance() should be called to fully initialize the object. - * If the type is a subtype of RefCounted, it already has a refcount of 1. The caller must take ownership the refcount and is responsible for decrementing it again when the object is no longer needed. - * - * "NOTIFICATION_POSTINITIALIZE" must be sent after construction. - * - * @param p_classname A pointer to a StringName with the class name. - * - * @return A pointer to the newly created Object. - */ -typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject3)(GDExtensionConstStringNamePtr p_classname); - -/** - * @name classdb_get_method_bind - * @since 4.1 - * - * Gets a pointer to the MethodBind in ClassDB for the given class, method and hash. - * - * @param p_classname A pointer to a StringName with the class name. - * @param p_methodname A pointer to a StringName with the method name. - * @param p_hash A hash representing the function signature. - * - * @return A pointer to the MethodBind from ClassDB. - */ -typedef GDExtensionMethodBindPtr (*GDExtensionInterfaceClassdbGetMethodBind)(GDExtensionConstStringNamePtr p_classname, GDExtensionConstStringNamePtr p_methodname, GDExtensionInt p_hash); - -/** - * @name classdb_get_class_tag - * @since 4.1 - * @deprecated Deprecated in Godot 4.7. No longer needed. Use the `is_class` method on `Object` instead. - * - * Gets a pointer uniquely identifying the given built-in class in the ClassDB. - * - * @param p_classname A pointer to a StringName with the class name. - * - * @return A pointer uniquely identifying the built-in class in the ClassDB. - */ -typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNamePtr p_classname); - -/** - * @name classdb_register_extension_class - * @since 4.1 - * @deprecated Deprecated in Godot 4.2. Use `classdb_register_extension_class6` instead. - * - * Registers an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_parent_class_name A pointer to a StringName with the parent class name. - * @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs); - -/** - * @name classdb_register_extension_class2 - * @since 4.2 - * @deprecated Deprecated in Godot 4.3. Use `classdb_register_extension_class6` instead. - * - * Registers an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_parent_class_name A pointer to a StringName with the parent class name. - * @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs); - -/** - * @name classdb_register_extension_class3 - * @since 4.3 - * @deprecated Deprecated in Godot 4.4. Use `classdb_register_extension_class6` instead. - * - * Registers an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_parent_class_name A pointer to a StringName with the parent class name. - * @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo3 struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs); - -/** - * @name classdb_register_extension_class4 - * @since 4.4 - * @deprecated Deprecated in Godot 4.5. Use `classdb_register_extension_class6` instead. - * - * Registers an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_parent_class_name A pointer to a StringName with the parent class name. - * @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo4 struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass4)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs); - -/** - * @name classdb_register_extension_class5 - * @since 4.5 - * @deprecated Deprecated in Godot 4.7. Use `classdb_register_extension_class6` instead. - * - * Registers an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_parent_class_name A pointer to a StringName with the parent class name. - * @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo5 struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass5)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo5 *p_extension_funcs); - -/** - * @name classdb_register_extension_class6 - * @since 4.7 - * - * Registers an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_parent_class_name A pointer to a StringName with the parent class name. - * @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo6 struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass6)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo6 *p_extension_funcs); - -/** - * @name classdb_register_extension_class_method - * @since 4.1 - * - * Registers a method on an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_method_info A pointer to a GDExtensionClassMethodInfo struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info); - -/** - * @name classdb_register_extension_class_virtual_method - * @since 4.3 - * - * Registers a virtual method on an extension class in ClassDB, that can be implemented by scripts or other extensions. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_method_info A pointer to a GDExtensionClassMethodInfo struct. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info); - -/** - * @name classdb_register_extension_class_integer_constant - * @since 4.1 - * - * Registers an integer constant on an extension class in the ClassDB. - * - * Note about registering bitfield values (if p_is_bitfield is true): even though p_constant_value is signed, language bindings are - * advised to treat bitfields as uint64_t, since this is generally clearer and can prevent mistakes like using -1 for setting all bits. - * Language APIs should thus provide an abstraction that registers bitfields (uint64_t) separately from regular constants (int64_t). - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_enum_name A pointer to a StringName with the enum name. - * @param p_constant_name A pointer to a StringName with the constant name. - * @param p_constant_value The constant value. - * @param p_is_bitfield Whether or not this constant is part of a bitfield. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield); - -/** - * @name classdb_register_extension_class_property - * @since 4.1 - * - * Registers a property on an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_info A pointer to a GDExtensionPropertyInfo struct. - * @param p_setter A pointer to a StringName with the name of the setter method. - * @param p_getter A pointer to a StringName with the name of the getter method. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassProperty)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter); - -/** - * @name classdb_register_extension_class_property_indexed - * @since 4.2 - * - * Registers an indexed property on an extension class in the ClassDB. - * - * Provided struct can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_info A pointer to a GDExtensionPropertyInfo struct. - * @param p_setter A pointer to a StringName with the name of the setter method. - * @param p_getter A pointer to a StringName with the name of the getter method. - * @param p_index The index to pass as the first argument to the getter and setter methods. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter, GDExtensionInt p_index); - -/** - * @name classdb_register_extension_class_property_group - * @since 4.1 - * - * Registers a property group on an extension class in the ClassDB. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_group_name A pointer to a String with the group name. - * @param p_prefix A pointer to a String with the prefix used by properties in this group. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringPtr p_group_name, GDExtensionConstStringPtr p_prefix); - -/** - * @name classdb_register_extension_class_property_subgroup - * @since 4.1 - * - * Registers a property subgroup on an extension class in the ClassDB. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_subgroup_name A pointer to a String with the subgroup name. - * @param p_prefix A pointer to a String with the prefix used by properties in this subgroup. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringPtr p_subgroup_name, GDExtensionConstStringPtr p_prefix); - -/** - * @name classdb_register_extension_class_signal - * @since 4.1 - * - * Registers a signal on an extension class in the ClassDB. - * - * Provided structs can be safely freed once the function returns. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - * @param p_signal_name A pointer to a StringName with the signal name. - * @param p_argument_info A pointer to a GDExtensionPropertyInfo struct. - * @param p_argument_count The number of arguments the signal receives. - */ -typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassSignal)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count); - -/** - * @name classdb_unregister_extension_class - * @since 4.1 - * - * Unregisters an extension class in the ClassDB. - * - * Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_class_name A pointer to a StringName with the class name. - */ -typedef void (*GDExtensionInterfaceClassdbUnregisterExtensionClass)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name); - -/** - * @name get_library_path - * @since 4.1 - * - * Gets the path to the current GDExtension library. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param r_path A pointer to a String which will receive the path. - */ -typedef void (*GDExtensionInterfaceGetLibraryPath)(GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringPtr r_path); - -/** - * @name editor_add_plugin - * @since 4.1 - * - * Adds an editor plugin. - * - * It's safe to call during initialization. - * - * @param p_class_name A pointer to a StringName with the name of a class (descending from EditorPlugin) which is already registered with ClassDB. - */ -typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePtr p_class_name); - -/** - * @name editor_remove_plugin - * @since 4.1 - * - * Removes an editor plugin. - * - * @param p_class_name A pointer to a StringName with the name of a class that was previously added as an editor plugin. - */ -typedef void (*GDExtensionInterfaceEditorRemovePlugin)(GDExtensionConstStringNamePtr p_class_name); - -/** - * @name editor_help_load_xml_from_utf8_chars - * @since 4.3 - * - * Loads new XML-formatted documentation data in the editor. - * - * The provided pointer can be immediately freed once the function returns. - * - * @param p_data A pointer to a UTF-8 encoded C string (null terminated). - */ -typedef void (*GDExtensionInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *p_data); - -/** - * @name editor_help_load_xml_from_utf8_chars_and_len - * @since 4.3 - * - * Loads new XML-formatted documentation data in the editor. - * - * The provided pointer can be immediately freed once the function returns. - * - * @param p_data A pointer to a UTF-8 encoded C string. - * @param p_size The number of bytes (not code units). - */ -typedef void (*GDExtensionInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size); - -/** - * @name editor_register_get_classes_used_callback - * @since 4.5 - * - * Registers a callback that Godot can call to get the list of all classes (from ClassDB) that may be used by the calling GDExtension. - * - * This is used by the editor to generate a build profile (in "Tools" > "Engine Compilation Configuration Editor..." > "Detect from project"), - * in order to recompile Godot with only the classes used. - * In the provided callback, the GDExtension should provide the list of classes that _may_ be used statically, thus the time of invocation shouldn't matter. - * If a GDExtension doesn't register a callback, Godot will assume that it could be using any classes. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_callback The callback to retrieve the list of classes used. - */ -typedef void (*GDExtensionInterfaceEditorRegisterGetClassesUsedCallback)(GDExtensionClassLibraryPtr p_library, GDExtensionEditorGetClassesUsedCallback p_callback); - -/** - * @name register_main_loop_callbacks - * @since 4.5 - * - * Registers callbacks to be called at different phases of the main loop. - * - * @param p_library A pointer the library received by the GDExtension's entry point function. - * @param p_callbacks A pointer to the structure that contains the callbacks. - */ -typedef void (*GDExtensionInterfaceRegisterMainLoopCallbacks)(GDExtensionClassLibraryPtr p_library, const GDExtensionMainLoopCallbacks *p_callbacks); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/plugins/agc-godot-editor/native/gdextension/vendor/provenance.json b/plugins/agc-godot-editor/native/gdextension/vendor/provenance.json index c08bfa9dd..205f63340 100644 --- a/plugins/agc-godot-editor/native/gdextension/vendor/provenance.json +++ b/plugins/agc-godot-editor/native/gdextension/vendor/provenance.json @@ -1,10 +1,10 @@ { - "project": "Godot Engine", - "version": "4.7.2-stable", - "commit": "ed1daf0bf001b61586d9930840f2f1394092c079", + "project": "godot-cpp", + "version": "godot-4.5-stable", + "commit": "e83fd0904c13356ed1d4c3d09f8bb9132bdc6b77", "license": "MIT", "licenseFile": "LICENSE.txt", - "interfaceSource": "https://github.com/godotengine/godot/blob/ed1daf0bf001b61586d9930840f2f1394092c079/core/extension/gdextension_interface.json", - "headerGenerator": "https://github.com/godotengine/godot/blob/ed1daf0bf001b61586d9930840f2f1394092c079/core/extension/make_interface_header.py", - "generation": "Official unmodified generator using local file IO helpers; include guard and provenance comments added. No godot-cpp dependency." + "archiveUrl": "https://codeload.github.com/godotengine/godot-cpp/zip/e83fd0904c13356ed1d4c3d09f8bb9132bdc6b77", + "archiveSha256": "579af30c5f62c1084edb28216788188227d80a583f0114463699ac4edd22140f", + "generation": "Unmodified official C++ bindings and interface, generated using the checked-in minimal build profile and statically linked into the editor DLL." }