Context API This adds the context API as described here. The main practical change now is that C is not longer directly accessible but has to be accessed through accessor functions. This basically adds the implementation of the API and adaption of existing code with some minor changes. The next task of course is to actually use this design to cleanup of bad level calls and global access, in blenkernel, blenloader. http://wiki.blender.org/index.php/BlenderDev/Blender2.5/Context Error, Warning and Debug Info Reporting This adds the error reporting API as described here. It should help clean up error() calls in non-ui code, but eventually can become used for gathering messages for a console window, and throwing exceptions in python scripts when an error happens executing something. http://wiki.blender.org/index.php/BlenderDev/Blender2.5/Reports
362 lines
7.3 KiB
C
362 lines
7.3 KiB
C
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* Contributor(s): Blender Foundation (2008).
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "DNA_listBase.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_screen_types.h"
|
|
#include "DNA_space_types.h"
|
|
#include "DNA_windowmanager_types.h"
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "BKE_context.h"
|
|
#include "BKE_main.h"
|
|
#include "BKE_report.h"
|
|
#include "BKE_screen.h"
|
|
|
|
#include <string.h>
|
|
|
|
/* struct */
|
|
|
|
struct bContext {
|
|
bContextTask task;
|
|
ReportList *reports;
|
|
int thread;
|
|
|
|
/* windowmanager context */
|
|
struct {
|
|
struct wmWindowManager *manager;
|
|
struct wmWindow *window;
|
|
struct bScreen *screen;
|
|
struct ScrArea *area;
|
|
struct ARegion *region;
|
|
struct uiBlock *block;
|
|
|
|
bContextDataCallback manager_cb;
|
|
bContextDataCallback window_cb;
|
|
bContextDataCallback screen_cb;
|
|
bContextDataCallback area_cb;
|
|
bContextDataCallback region_cb;
|
|
bContextDataCallback block_cb;
|
|
} wm;
|
|
|
|
/* data context */
|
|
struct {
|
|
struct Main *main;
|
|
struct Scene *scene;
|
|
} data;
|
|
|
|
/* data evaluation */
|
|
struct {
|
|
int render;
|
|
} eval;
|
|
};
|
|
|
|
/* context */
|
|
|
|
bContext *CTX_create()
|
|
{
|
|
bContext *C;
|
|
|
|
C= MEM_callocN(sizeof(bContext), "bContext");
|
|
|
|
C->task= CTX_UNDEFINED;
|
|
C->thread= 0;
|
|
|
|
return C;
|
|
}
|
|
|
|
bContext *CTX_copy(const bContext *C, int thread)
|
|
{
|
|
bContext *newC;
|
|
|
|
if(C->task != CTX_UNDEFINED)
|
|
BKE_report(C->reports, RPT_ERROR_INVALID_CONTEXT, "CTX_copy not allowed for this task");
|
|
|
|
newC= MEM_dupallocN((void*)C);
|
|
newC->thread= thread;
|
|
|
|
return newC;
|
|
}
|
|
|
|
int CTX_thread(const bContext *C)
|
|
{
|
|
return C->thread;
|
|
}
|
|
|
|
void CTX_free(bContext *C)
|
|
{
|
|
MEM_freeN(C);
|
|
}
|
|
|
|
/* context task and reports */
|
|
|
|
bContextTask CTX_task(const bContext *C)
|
|
{
|
|
return C->task;
|
|
}
|
|
|
|
void CTX_task_set(bContext *C, bContextTask task)
|
|
{
|
|
C->task= task;
|
|
}
|
|
|
|
ReportList *CTX_reports(const bContext *C)
|
|
{
|
|
return C->reports;
|
|
}
|
|
|
|
void CTX_reports_set(bContext *C, ReportList *reports)
|
|
{
|
|
C->reports= reports;
|
|
}
|
|
|
|
/* window manager context */
|
|
|
|
wmWindowManager *CTX_wm_manager(const bContext *C)
|
|
{
|
|
return C->wm.manager;
|
|
}
|
|
|
|
wmWindow *CTX_wm_window(const bContext *C)
|
|
{
|
|
return C->wm.window;
|
|
}
|
|
|
|
bScreen *CTX_wm_screen(const bContext *C)
|
|
{
|
|
return C->wm.screen;
|
|
}
|
|
|
|
ScrArea *CTX_wm_area(const bContext *C)
|
|
{
|
|
return C->wm.area;
|
|
}
|
|
|
|
SpaceLink *CTX_wm_space_data(const bContext *C)
|
|
{
|
|
return (C->wm.area)? C->wm.area->spacedata.first: NULL;
|
|
}
|
|
|
|
ARegion *CTX_wm_region(const bContext *C)
|
|
{
|
|
return C->wm.region;
|
|
}
|
|
|
|
void *CTX_wm_region_data(const bContext *C)
|
|
{
|
|
return (C->wm.region)? C->wm.region->regiondata: NULL;
|
|
}
|
|
|
|
struct uiBlock *CTX_wm_ui_block(const bContext *C)
|
|
{
|
|
return C->wm.block;
|
|
}
|
|
|
|
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
|
|
{
|
|
C->wm.manager= wm;
|
|
}
|
|
|
|
void CTX_wm_window_set(bContext *C, wmWindow *win)
|
|
{
|
|
C->wm.window= win;
|
|
C->wm.screen= (win)? win->screen: NULL;
|
|
C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
|
|
}
|
|
|
|
void CTX_wm_screen_set(bContext *C, bScreen *screen)
|
|
{
|
|
C->wm.screen= screen;
|
|
C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
|
|
}
|
|
|
|
void CTX_wm_area_set(bContext *C, ScrArea *area)
|
|
{
|
|
C->wm.area= area;
|
|
C->wm.area_cb= (area && area->type)? area->type->context: NULL;
|
|
}
|
|
|
|
void CTX_wm_region_set(bContext *C, ARegion *region)
|
|
{
|
|
C->wm.region= region;
|
|
C->wm.region_cb= (region && region->type)? region->type->context: NULL;
|
|
}
|
|
|
|
void CTX_wm_ui_block_set(bContext *C, struct uiBlock *block, bContextDataCallback cb)
|
|
{
|
|
C->wm.block= block;
|
|
C->wm.block_cb= cb;
|
|
}
|
|
|
|
/* data context utility functions */
|
|
|
|
struct bContextDataMember {
|
|
StructRNA *rna;
|
|
const char *name;
|
|
int collection;
|
|
};
|
|
|
|
bContextDataMember CTX_DataMain = {&RNA_Main, "main", 0};
|
|
bContextDataMember CTX_DataScene = {&RNA_Scene, "scene", 0};
|
|
|
|
bContextDataMember CTX_DataObjects = {&RNA_Object, "objects", 1};
|
|
|
|
bContextDataMember CTX_DataEditObject = {&RNA_Object, "edit_object", 0};
|
|
bContextDataMember CTX_DataEditArmature = {NULL, "edit_armature", 0};
|
|
bContextDataMember CTX_DataEditMesh = {NULL, "edit_mesh", 0};
|
|
|
|
static int ctx_data_get(const bContext *C, const bContextDataMember *member, bContextDataResult *result)
|
|
{
|
|
if(C->wm.block_cb && C->wm.block_cb(C, member, result)) return 1;
|
|
if(C->wm.region_cb && C->wm.region_cb(C, member, result)) return 1;
|
|
if(C->wm.area_cb && C->wm.area_cb(C, member, result)) return 1;
|
|
if(C->wm.screen_cb && C->wm.screen_cb(C, member, result)) return 1;
|
|
if(C->wm.window_cb && C->wm.window_cb(C, member, result)) return 1;
|
|
if(C->wm.manager_cb && C->wm.manager_cb(C, member, result)) return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void *ctx_data_pointer_get(const bContext *C, const bContextDataMember *member)
|
|
{
|
|
bContextDataResult result;
|
|
|
|
if(ctx_data_get(C, member, &result))
|
|
return result.pointer;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int ctx_data_pointer_verify(const bContext *C, const bContextDataMember *member, void **pointer)
|
|
{
|
|
bContextDataResult result;
|
|
|
|
if(ctx_data_get(C, member, &result)) {
|
|
*pointer= result.pointer;
|
|
return 1;
|
|
}
|
|
else {
|
|
*pointer= NULL;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static int ctx_data_collection_get(const bContext *C, const bContextDataMember *member, bContextDataIterator *iter)
|
|
{
|
|
bContextDataResult result;
|
|
|
|
if(ctx_data_get(C, member, &result)) {
|
|
*iter= result.iterator;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* data context */
|
|
|
|
Main *CTX_data_main(const bContext *C)
|
|
{
|
|
Main *bmain;
|
|
|
|
if(ctx_data_pointer_verify(C, &CTX_DataMain, (void*)&bmain))
|
|
return bmain;
|
|
else
|
|
return C->data.main;
|
|
}
|
|
|
|
void CTX_data_main_set(bContext *C, Main *bmain)
|
|
{
|
|
C->data.main= bmain;
|
|
}
|
|
|
|
Scene *CTX_data_scene(const bContext *C)
|
|
{
|
|
Scene *scene;
|
|
|
|
if(ctx_data_pointer_verify(C, &CTX_DataScene, (void*)&scene))
|
|
return scene;
|
|
else
|
|
return C->data.scene;
|
|
}
|
|
|
|
void CTX_data_scene_set(bContext *C, Scene *scene)
|
|
{
|
|
C->data.scene= scene;
|
|
}
|
|
|
|
ToolSettings *CTX_data_tool_settings(const bContext *C)
|
|
{
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
if(scene)
|
|
return scene->toolsettings;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
int CTX_data_objects(const bContext *C, bContextDataIterator *iter)
|
|
{
|
|
return ctx_data_collection_get(C, &CTX_DataObjects, iter);
|
|
}
|
|
|
|
struct Object *CTX_data_edit_object(const bContext *C)
|
|
{
|
|
return ctx_data_pointer_get(C, &CTX_DataEditObject);
|
|
}
|
|
|
|
struct EditMesh *CTX_data_edit_mesh(const bContext *C)
|
|
{
|
|
return ctx_data_pointer_get(C, &CTX_DataEditMesh);
|
|
}
|
|
|
|
ListBase *CTX_data_edit_armature(const bContext *C)
|
|
{
|
|
return ctx_data_pointer_get(C, &CTX_DataEditArmature);
|
|
}
|
|
|
|
/* data evaluation */
|
|
|
|
float CTX_eval_frame(const bContext *C)
|
|
{
|
|
return (C->data.scene)? C->data.scene->r.cfra: 0.0f;
|
|
}
|
|
|
|
int CTX_eval_render_resolution(const bContext *C)
|
|
{
|
|
return C->eval.render;
|
|
}
|
|
|
|
void CTX_eval_render_resolution_set(bContext *C, int render)
|
|
{
|
|
C->eval.render= render;
|
|
}
|
|
|