This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/blenkernel/intern/context.c
Brecht Van Lommel ecc4e55b66 2.5
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
2008-12-18 02:56:48 +00:00

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;
}