Dev:2.5/Source/Architecture/GlobalsBadCalls
目次
Globals and Bad Calls
For 2.5 many globals are being replaced by context, bad level calls from blenkernel into src for example are not allowed anymore, as well as functions that block waiting for user input or confirmation. This document lists 2.4x variables and function calls and how to replace them in common cases, though of course each case must be considered individually. Also debatable if every global is worth replacing, some are basically harmless in practice.
Note: we won't remove all globals at once since that would break too much, so this part of the globals have been removed, but most of them are still there, so the list is split up in Removed and Proposed items.
-- Brecht 01:02, 5 December 2008 (UTC)
Context vs. Passing Function Argument
An important thing to consider everytime a global is replaced, is if you should get it from the context or if it should be passed as an argument to the function. Passing everything as an argument can give many function parameters, but it does make the code more reusable. Generally, try to avoid passing context if possible, and get the data from the context in the main operator invoke/exec or drawing functions for example, and then other utility functions can take these values as parameters.
Functions
Removed
- error(): error reporting cannot be blocking in this way anymore, and it is the user interface that should pop up the actual errors. BKE_report() and BKE_reportf() can be used to report warnings and errors of various types into the context. Depending on who is calling the function, an operator, a python script, the dependency graph, this error still has be reported in different ways, which is not yet implemented itself.
- waitcursor(): the operator should call WM_waitcursor instead, this should not be called in blenkernel or other non-ui modules.
- blender_test_break(): split up the function, for example in begin/step/end, such that an operator can be created that calls those three and does step() with a TIMER event.
- force_draw(): don't call this function, but rather split up the operator such that it is non-blocking, either waiting for more events, or installing a TIMER event for example.
Windowing and Events
Removed
- curarea: use CTX_wm_area().
- G.sipo, G.buts, G.sima, G.soops, ..: use CTX_wm_space_data() and cast it to the right space type.
- G.qual: add arguments or pass along the wmEvent.
Proposed
- G.curscreen: use CTX_wm_screen().
- G.windowstate: don't use anymore, window manager handles it differently.
- G.font, G.fonts, G.ui_international: this can be an internal static variable in either the interface or blenfont module.
- G.v2d: unsure, get it from the region or space?
- G.ndofdevice: unsure, something in the window manager?
- G.afbreek: unsure, perhaps check report list for errors? That may not cover all cases.
Data
Proposed
- G.main: use CTX_data_main(), or pass it as an argument.
- G.scene: use CTX_data_scene(), or pass it as an argument.
- G.obedit, G.edbo, G.editBMesh: unsure, use CTX_data_edit_object(). EditMesh, EditBones, etc can be replaced with Mesh.edit and Armature.edit members, which can be retrieved from the object.
- G.textcurs: unsure, something like EditFont *Font.edit could be added, containing this.
Why? Storing edit data per object data will allow multiple objects being editable at the same time like pose mode in the future easier. It is also useful for operator and python code that temporarily wants to manipulate the object in this representation.
- G.totobj, G.totlamp, G.totvert, ..: unsure, info header could keep this local, and wait for data notifiers?
- G.editModeTitleExtra: unsure, text for info header.
- G.moving: unsure, object itself could have a flag maybe?
Evaluation
Proposed
- G.rendering: use CTX_data_eval_render_resolution().
- CFRA, G.scene->cfra: use CTX_data_eval_current_frame().
Why? Abstracting these can make multithreading of evaluation code easier in the future, i.e. two can threads can be evaluating things at the different resolution and frame.
Other
Removed
- G.order: use ENDIAN_ORDER.
- G.version: use BLENDER_VERSION.
Proposed
- G.background: ideally this should not be used too much, it is usually the thing preceding a bad context call. Could be added to the context if necessary.
- G.have_libtiff, G.have_quicktime: this could become a function call for the respective modules, like IMB_support_format().
- G.recent_files, G.ima, G.sce, G.lib: recent files and last used paths. Not sure about replacement, but it is basically a global path anyway.
- G.sce, G.relbase_valid, G.save_over: this is used for looking up with relative paths for example, or checking if we need to write untitled.blend. Not sure why this doesn't use Main.name?
- G.listener: sound handle.
- G.ttffont, G.selfont, G.charstart, G.charmin, G.charmax: these are used the for font editing and evaluation.
File Wide Settings
Proposed
What I would like to do is create a struct with file wide settings. This would be pointed to by Main and saved to file, and it could be called MainSettings. It would contain settings related to viewing, tools, game engine and some others. The ToolSettings that are scene level now would be moved to this level, though some of these should perhaps disappear as they become operator properties which are remembered somehow.
struct MainSettings {
int flag;
#define G_DOSCRIPTLINKS
#define G_FILE_LOCK
#define G_FILE_SIGN
#define G_FIle_PUBLISH
#define G_AUTOPACK
#define G_FILE_COMPRESS
struct MainViewSettings {
#define G_DRAW_EXT
#define G_DRAWNORMALS
#define G_DRAWFACES
#define G_ALLEDGES
#define G_DRAW_VNORMALS
#define G_DRAWEDGES
#define G_DRAWCREASES
#define G_DRAWSEAMS
#define G_HIDDENEDGES
#define G_DRAW_EDGELEN
#define G_DRAW_FACEAREA
#define G_DRAW_EDGEANG
#define G_DRAWSHARP
#define G_HIDDENHANDLES
#define G_DRAWBWEIGHTS
(render)displaymode
(render)winpos
} draw;
struct MainGameSettings {
#define G_FILE_AUTOPLAY
#define G_FILE_ENABLE_ALL_FRAMES
#define G_FILE_SHOW_DEBUG_PROPS
#define G_FILE_SHOW_FRAMERATE
#define G_FILE_SHOW_PROFILE
#define G_FILE_GAME_TO_IPO
#define G_FILE_GAME_MAT
#define G_FILE_DISPLAY_LISTS
#define G_FILE_SHOW_PHYSICS
#define G_FILE_GAME_MAT_GLSL
#define G_FILE_GLSL_NO_*
} game;
struct MainToolSettings {
part of ToolSettings contents
remember properties of operators
} tool;
}
Should become a user preference in U:
#define G_FILE_NO_UI
Temporary 3d view states that should be local there:
#define G_RENDER_SHADOW
#define G_RENDER_OGL
#define G_BACKBUFSEL
#define G_PICKSEL
Local flag in grease pencil layer?
#define G_GREASEPENCIL
Further we have modes. In order to allow multiple objects to be in edited/painted/sculpted at the same time, some time in the future, it would be good to have such flags per object instead of global. Perhaps it would still be useful for efficiency to have some global flag for quickly checking if some object is being edited for example though, not sure.
#define G_SCULPTMODE
#define G_PARTICLEEDIT
#define G_WEIGHTPAINT
#define G_TEXTUREPAINT
#define G_FACESELECT
#define G_VERTEXPAINT
No idea what to do with this:
#define G_DEBUG
G.rt
G.move
#define G_PLAYANIM
#define G_G_FILE_AUTOPLAY