diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/Makefile | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/context.c | 361 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/report.c | 186 |
5 files changed, 561 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 4cfc8f91efe..8919719d64d 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -43,6 +43,7 @@ CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include # Reference to the types in makesdna and imbuf CPPFLAGS += -I../../makesdna +CPPFLAGS += -I../../makesrna CPPFLAGS += -I../../imbuf # This mod uses the BLI and BLO module CPPFLAGS += -I../../blenlib diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index e5625fa03e0..b891e75a71b 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -67,6 +67,7 @@ #include "BKE_action.h" #include "BKE_blender.h" +#include "BKE_context.h" #include "BKE_curve.h" #include "BKE_depsgraph.h" #include "BKE_displist.h" @@ -324,7 +325,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) SWAP(ListBase, G.main->script, bfd->main->script); /* we re-use current screen */ - curscreen= C->screen; + curscreen= CTX_wm_screen(C); /* but use new Scene pointer */ curscene= bfd->curscene; if(curscene==NULL) curscene= bfd->main->scene.first; @@ -341,6 +342,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) if(mode!='u') G.save_over = 1; G.main= bfd->main; + CTX_data_main_set(C, G.main); if (bfd->user) { @@ -356,20 +358,20 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) /* case G_FILE_NO_UI or no screens in file */ if(mode) { - C->screen= curscreen; - C->scene= curscene; + CTX_wm_screen_set(C, curscreen); + CTX_data_scene_set(C, curscene); } else { G.winpos= bfd->winpos; G.displaymode= bfd->displaymode; G.fileflags= bfd->fileflags; - C->screen= bfd->curscreen; - C->scene= C->screen->scene; + CTX_wm_screen_set(C, bfd->curscreen); + CTX_data_scene_set(C, bfd->curscreen->scene); } /* this can happen when active scene was lib-linked, and doesnt exist anymore */ - if(C->scene==NULL) { - C->scene= G.main->scene.first; - C->screen->scene= C->scene; + if(CTX_data_scene(C)==NULL) { + CTX_data_scene_set(C, G.main->scene.first); + CTX_wm_screen(C)->scene= CTX_data_scene(C); } /* special cases, override loaded flags: */ @@ -385,7 +387,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) } /* baseflags, groups, make depsgraph, etc */ - set_scene_bg(C->scene); + set_scene_bg(CTX_data_scene(C)); /* clear BONE_UNKEYED flags, these are not valid anymore for proxies */ framechange_poses_clear_unkeyed(); @@ -397,7 +399,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) } /* now tag update flags, to ensure deformers get calculated on redraw */ - DAG_scene_update_flags(C->scene, C->scene->lay); + DAG_scene_update_flags(CTX_data_scene(C), CTX_data_scene(C)->lay); if (G.f & G_DOSCRIPTLINKS) { /* there's an onload scriptlink to execute in screenmain */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c new file mode 100644 index 00000000000..b8633d8618e --- /dev/null +++ b/source/blender/blenkernel/intern/context.c @@ -0,0 +1,361 @@ +/** + * $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; +} + diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 8e36ea0204b..4fd36806393 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -83,6 +83,7 @@ #include "BLI_dynstr.h" #include "BKE_library.h" +#include "BKE_context.h" #include "BKE_main.h" #include "BKE_global.h" #include "BKE_sound.h" diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c new file mode 100644 index 00000000000..569377a1c2f --- /dev/null +++ b/source/blender/blenkernel/intern/report.c @@ -0,0 +1,186 @@ +/** + * $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 "BLI_blenlib.h" + +#include "BKE_report.h" + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#ifdef _WIN32 +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif +#endif + +static char *report_type_str(int type) +{ + switch(type) { + case RPT_DEBUG: return "Debug"; + case RPT_INFO: return "Info"; + case RPT_WARNING: return "Warning"; + case RPT_ERROR: return "Error"; + case RPT_ERROR_INVALID_INPUT: return "Invalid Input Error"; + case RPT_ERROR_INVALID_CONTEXT: return "Invalid Context Error"; + case RPT_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error"; + default: return "Undefined Type"; + } +} + +void BKE_report_list_init(ReportList *reports, int flags) +{ + memset(reports, 0, sizeof(ReportList)); + + reports->level= RPT_WARNING; + reports->flags= flags; +} + +void BKE_report_list_clear(ReportList *reports) +{ + Report *report; + + for(report=reports->list.first; report; report=report->next) + MEM_freeN(report->message); + + BLI_freelistN(&reports->list); +} + +void BKE_report(ReportList *reports, ReportType type, const char *message) +{ + Report *report; + int len; + + if(!reports || type < reports->level) + return; + + if(reports->flags & RPT_PRINT) { + printf("%s: %s\n", report_type_str(type), message); + fflush(stdout); /* this ensures the message is printed before a crash */ + } + + if(reports->flags & RPT_STORE) { + report= MEM_callocN(sizeof(Report), "Report"); + report->type= type; + report->typestr= report_type_str(type); + + len= strlen(message); + report->message= MEM_callocN(sizeof(char)*(len+1), "ReportMessage"); + memcpy(report->message, message, sizeof(char)*(len+1)); + + BLI_addtail(&reports->list, report); + } +} + +void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) +{ + Report *report; + va_list args; + char *message; + int len= 256, maxlen= 65536, retval; + + if(!reports || type < reports->level) + return; + + if(reports->flags & RPT_PRINT) { + va_start(args, format); + vprintf(format, args); + va_end(args); + fflush(stdout); /* this ensures the message is printed before a crash */ + } + + if(reports->flags & RPT_STORE) { + while(1) { + message= MEM_callocN(sizeof(char)*len+1, "ReportMessage"); + + va_start(args, format); + retval= vsnprintf(message, len, format, args); + va_end(args); + + if(retval == -1) { + /* -1 means not enough space, but on windows it may also mean + * there is a formatting error, so we impose a maximum length */ + MEM_freeN(message); + message= NULL; + + len *= 2; + if(len > maxlen) { + fprintf(stderr, "BKE_reportf message too long or format error.\n"); + break; + } + } + else if(retval > len) { + /* in C99 the actual length required is returned */ + MEM_freeN(message); + message= NULL; + + len= retval; + } + else + break; + } + + if(message) { + report= MEM_callocN(sizeof(Report), "Report"); + report->type= type; + report->typestr= report_type_str(type); + report->message= message; + + BLI_addtail(&reports->list, report); + } + } +} + +ReportType BKE_report_level(ReportList *reports) +{ + return reports->level; +} + +void BKE_report_level_set(ReportList *reports, ReportType level) +{ + reports->level= level; +} + +int BKE_report_has_error(ReportList *reports) +{ + Report *report; + + if(!reports) + return 0; + + for(report=reports->list.first; report; report=report->next) + if(report->type >= RPT_ERROR) + return 1; + + return 0; +} + |