Esempio n. 1
0
static PointerRNA rna_KeyingSet_typeinfo_get(PointerRNA *ptr)
{
	KeyingSet *ks = (KeyingSet *)ptr->data;
	KeyingSetInfo *ksi = NULL;
	
	/* keying set info is only for builtin Keying Sets */
	if ((ks->flag & KEYINGSET_ABSOLUTE) == 0)
		ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
	return rna_pointer_inherit_refine(ptr, &RNA_KeyingSetInfo, ksi);
}
Esempio n. 2
0
static StructRNA *rna_KeyingSetInfo_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
                                             StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	KeyingSetInfo dummyksi = {NULL};
	KeyingSetInfo *ksi;
	PointerRNA dummyptr = {{NULL}};
	int have_function[3];

	/* setup dummy type info to store static properties in */
	/* TODO: perhaps we want to get users to register as if they're using 'KeyingSet' directly instead? */
	RNA_pointer_create(NULL, &RNA_KeyingSetInfo, &dummyksi, &dummyptr);
	
	/* validate the python class */
	if (validate(&dummyptr, data, have_function) != 0)
		return NULL;
	
	if (strlen(identifier) >= sizeof(dummyksi.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering keying set info class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummyksi.idname));
		return NULL;
	}
	
	/* check if we have registered this info before, and remove it */
	ksi = ANIM_keyingset_info_find_name(dummyksi.idname);
	if (ksi && ksi->ext.srna)
		rna_KeyingSetInfo_unregister(bmain, ksi->ext.srna);
	
	/* create a new KeyingSetInfo type */
	ksi = MEM_callocN(sizeof(KeyingSetInfo), "python keying set info");
	memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo));
	
	/* set RNA-extensions info */
	ksi->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
	ksi->ext.data = data;
	ksi->ext.call = call;
	ksi->ext.free = free;
	RNA_struct_blender_type_set(ksi->ext.srna, ksi);
	
	/* set callbacks */
	/* NOTE: we really should have all of these...  */
	ksi->poll = (have_function[0]) ? RKS_POLL_rna_internal : NULL;
	ksi->iter = (have_function[1]) ? RKS_ITER_rna_internal : NULL;
	ksi->generate = (have_function[2]) ? RKS_GEN_rna_internal : NULL;
	
	/* add and register with other info as needed */
	ANIM_keyingset_info_register(ksi);
	
	WM_main_add_notifier(NC_WINDOW, NULL);

	/* return the struct-rna added */
	return ksi->ext.srna;
}
Esempio n. 3
0
/* Check if KeyingSet can be used in the current context */
short ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
{
	if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
		KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
		
		/* get the associated 'type info' for this KeyingSet */
		if (ksi == NULL)
			return 0;
		/* TODO: check for missing callbacks! */

		/* check if it can be used in the current context */
		return (ksi->poll(ksi, C));
	}
	
	return 1;
}
Esempio n. 4
0
/* Given a KeyingSet and context info, validate Keying Set's paths.
 * This is only really necessary with relative/built-in KeyingSets
 * where their list of paths is dynamically generated based on the
 * current context info.
 *
 * Returns 0 if succeeded, otherwise an error code: eModifyKey_Returns
 */
short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
{
	/* sanity check */
	if (ks == NULL)
		return 0;
	
	/* if relative Keying Sets, poll and build up the paths */
	if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
		KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
		
		/* clear all existing paths 
		 * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
		 */
		BKE_keyingset_free(ks);
		
		/* get the associated 'type info' for this KeyingSet */
		if (ksi == NULL)
			return MODIFYKEY_MISSING_TYPEINFO;
		/* TODO: check for missing callbacks! */
		
		/* check if it can be used in the current context */
		if (ksi->poll(ksi, C)) {
			/* if a list of data sources are provided, run a special iterator over them,
			 * otherwise, just continue per normal
			 */
			if (dsources) 
				RKS_ITER_overrides_list(ksi, C, ks, dsources);
			else
				ksi->iter(ksi, C, ks);
				
			/* if we don't have any paths now, then this still qualifies as invalid context */
			// FIXME: we need some error conditions (to be retrieved from the iterator why this failed!)
			if (ks->paths.first == NULL)
				return MODIFYKEY_INVALID_CONTEXT;
		}
		else {
			/* poll callback tells us that KeyingSet is useless in current context */
			// FIXME: the poll callback needs to give us more info why
			return MODIFYKEY_INVALID_CONTEXT;
		}
	}
	
	/* succeeded; return 0 to tag error free */
	return 0;
}