The `pre` handler is called after blender internal code is done populating the link/append context with data to be processed, and before this data starts being linked from library files. The `post` handler is called after blender is done linking, and potentailly appending and/or instantiating, the requested data and all of their dependencies. Both handlers are called with a single argument, the link/append context. An new RNA sets of wrappers have been added to expose relevant info from these internal C++ structures. NOTE: !113658 is very similar (but tied to asset drag & drop), whereas this PR is more general (these could probably live hand-in-hand / side- by-side). Implements #122357 Pull Request: https://projects.blender.org/blender/blender/pulls/128279 ----------------- Some quick py example code: ```python import bpy def my_handler_pre(lapp_context): print("About to {}:\n\t".format("link" if "LINK" in lapp_context.options else "append"), "\n\t".join("{} '{}', from libs ['{}']".format(item.id_type, item.name, "', '".join([l.filepath for l in item.source_libraries])) for item in lapp_context.import_items)) def my_handler_post(lapp_context): print("{}:\n\t".format("Linked" if "LINK" in lapp_context.options else "Appended"), "\n\t".join("{} '{}', from lib '{}'".format(item.id.id_type, item.id.name, item.source_library.filepath) for item in lapp_context.import_items)) bpy.app.handlers.link_append_pre.append(my_handler_pre) bpy.app.handlers.link_append_post.append(my_handler_post) ```
138 lines
4.3 KiB
C++
138 lines
4.3 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
struct Depsgraph;
|
|
struct ID;
|
|
struct Main;
|
|
struct PointerRNA;
|
|
|
|
/**
|
|
* Callbacks for One Off Actions
|
|
* =============================
|
|
*
|
|
* - `{ACTION}` use in cases where only a single callback is required,
|
|
* `VERSION_UPDATE` and `RENDER_STATS` for example.
|
|
*
|
|
* \note avoid single callbacks if there is a chance `PRE/POST` are useful to differentiate
|
|
* since renaming callbacks may break Python scripts.
|
|
*
|
|
* Callbacks for Common Actions
|
|
* ============================
|
|
*
|
|
* - `{ACTION}_PRE` run before the action.
|
|
* - `{ACTION}_POST` run after the action.
|
|
*
|
|
* Optional Additional Callbacks
|
|
* -----------------------------
|
|
*
|
|
* - `{ACTION}_INIT` when the handler may manipulate the context used to run the action.
|
|
*
|
|
* Examples where `INIT` functions may be useful are:
|
|
*
|
|
* - When rendering, an `INIT` function may change the camera or render settings,
|
|
* things which a `PRE` function can't support as this information has already been used.
|
|
* - When saving an `INIT` function could temporarily change the preferences.
|
|
*
|
|
* - `{ACTION}_POST_FAIL` should be included if the action may fail.
|
|
*
|
|
* Use this so a call to the `PRE` callback always has a matching call to `POST` or `POST_FAIL`.
|
|
*
|
|
* \note in most cases only `PRE/POST` are required.
|
|
*
|
|
* Callbacks for Background/Modal Tasks
|
|
* ====================================
|
|
*
|
|
* - `{ACTION}_INIT`
|
|
* - `{ACTION}_COMPLETE` when a background job has finished.
|
|
* - `{ACTION}_CANCEL` When a background job is canceled partway through.
|
|
*
|
|
* While cancellation may be caused by any number of reasons, common causes may include:
|
|
*
|
|
* - Explicit user cancellation.
|
|
* - Exiting Blender.
|
|
* - Failure to acquire resources (such as disk-full, out of memory ... etc).
|
|
*
|
|
* \note `PRE/POST` handlers may be used along side modal task handlers
|
|
* as is the case for rendering, where rendering an animation uses modal task handlers,
|
|
* rendering a single frame has `PRE/POST` handlers.
|
|
*
|
|
* Python Access
|
|
* =============
|
|
*
|
|
* All callbacks here must be exposed via the Python module `bpy.app.handlers`,
|
|
* see `bpy_app_handlers.cc`.
|
|
*/
|
|
enum eCbEvent {
|
|
BKE_CB_EVT_FRAME_CHANGE_PRE,
|
|
BKE_CB_EVT_FRAME_CHANGE_POST,
|
|
BKE_CB_EVT_RENDER_PRE,
|
|
BKE_CB_EVT_RENDER_POST,
|
|
BKE_CB_EVT_RENDER_WRITE,
|
|
BKE_CB_EVT_RENDER_STATS,
|
|
BKE_CB_EVT_RENDER_INIT,
|
|
BKE_CB_EVT_RENDER_COMPLETE,
|
|
BKE_CB_EVT_RENDER_CANCEL,
|
|
BKE_CB_EVT_LOAD_PRE,
|
|
BKE_CB_EVT_LOAD_POST,
|
|
BKE_CB_EVT_LOAD_POST_FAIL,
|
|
BKE_CB_EVT_SAVE_PRE,
|
|
BKE_CB_EVT_SAVE_POST,
|
|
BKE_CB_EVT_SAVE_POST_FAIL,
|
|
BKE_CB_EVT_UNDO_PRE,
|
|
BKE_CB_EVT_UNDO_POST,
|
|
BKE_CB_EVT_REDO_PRE,
|
|
BKE_CB_EVT_REDO_POST,
|
|
BKE_CB_EVT_DEPSGRAPH_UPDATE_PRE,
|
|
BKE_CB_EVT_DEPSGRAPH_UPDATE_POST,
|
|
BKE_CB_EVT_VERSION_UPDATE,
|
|
BKE_CB_EVT_LOAD_FACTORY_USERDEF_POST,
|
|
BKE_CB_EVT_LOAD_FACTORY_STARTUP_POST,
|
|
BKE_CB_EVT_XR_SESSION_START_PRE,
|
|
BKE_CB_EVT_ANNOTATION_PRE,
|
|
BKE_CB_EVT_ANNOTATION_POST,
|
|
BKE_CB_EVT_OBJECT_BAKE_PRE,
|
|
BKE_CB_EVT_OBJECT_BAKE_COMPLETE,
|
|
BKE_CB_EVT_OBJECT_BAKE_CANCEL,
|
|
BKE_CB_EVT_COMPOSITE_PRE,
|
|
BKE_CB_EVT_COMPOSITE_POST,
|
|
BKE_CB_EVT_COMPOSITE_CANCEL,
|
|
BKE_CB_EVT_ANIMATION_PLAYBACK_PRE,
|
|
BKE_CB_EVT_ANIMATION_PLAYBACK_POST,
|
|
BKE_CB_EVT_TRANSLATION_UPDATE_POST,
|
|
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_PRE,
|
|
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
|
|
BKE_CB_EVT_EXTENSION_REPOS_SYNC,
|
|
BKE_CB_EVT_EXTENSION_REPOS_FILES_CLEAR,
|
|
BKE_CB_EVT_BLENDIMPORT_PRE,
|
|
BKE_CB_EVT_BLENDIMPORT_POST,
|
|
BKE_CB_EVT_TOT,
|
|
};
|
|
|
|
struct bCallbackFuncStore {
|
|
bCallbackFuncStore *next, *prev;
|
|
void (*func)(Main *, PointerRNA **, int num_pointers, void *arg);
|
|
void *arg;
|
|
short alloc;
|
|
};
|
|
|
|
void BKE_callback_exec(Main *bmain, PointerRNA **pointers, int num_pointers, eCbEvent evt);
|
|
void BKE_callback_exec_null(Main *bmain, eCbEvent evt);
|
|
void BKE_callback_exec_id(Main *bmain, ID *id, eCbEvent evt);
|
|
void BKE_callback_exec_id_depsgraph(Main *bmain, ID *id, Depsgraph *depsgraph, eCbEvent evt);
|
|
void BKE_callback_exec_string(Main *bmain, eCbEvent evt, const char *str);
|
|
void BKE_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt);
|
|
void BKE_callback_remove(bCallbackFuncStore *funcstore, eCbEvent evt);
|
|
|
|
void BKE_callback_global_init();
|
|
/**
|
|
* Call on application exit.
|
|
*/
|
|
void BKE_callback_global_finalize();
|