1
1

Compare commits

...

1064 Commits

Author SHA1 Message Date
bcc020b1bc Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/readfile.c
2016-07-25 19:33:55 +02:00
3f36cd3f33 Changed most of ID_IS_LINKED_foo checks as needed.
Basically, due to new 'virtual' libraries & 'path' assets, we consider those 'virtualmy  linked' IDs as:
* Local for editing purpose (i.e. they are editable).
* Linked for datablock management purposes (i.e. they can be made local, etc.).

Note: all this is more like a quick hack to test 'file-based' asset repositories (like cloud)
in comming weeks. I really do not think we should use that in the end, an full-featured
'overriding ID' system (as proposed in replacement of proxies for 2.8) would be much saner imho.
2016-07-25 17:37:34 +02:00
521222b545 Merge branch 'master' into asset-engine 2016-07-25 16:42:35 +02:00
4a298b10ec Merge branch 'master' into asset-engine 2016-07-25 15:07:44 +02:00
784f7f3264 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/windowmanager/intern/wm_files_link.c
2016-07-24 18:13:36 +02:00
70e3f86809 Some more small fixes regarding ID/library asset handling. 2016-07-24 15:58:16 +02:00
d8da816a7c Add more macros to differentiate actual linked datablocks from 'virtually' linked ones (assets only).
Not yet used in code.
2016-07-16 15:54:46 +02:00
5e469bbd95 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/windowmanager/intern/wm_init_exit.c
2016-07-16 15:39:50 +02:00
99bb1accbb Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/readfile.c
	source/blender/windowmanager/intern/wm_init_exit.c
2016-07-12 09:15:49 +02:00
b0760a5c8f Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenloader/intern/readfile.c
2016-07-07 15:15:48 +02:00
581a819432 Merge branch 'master' into asset-engine 2016-07-02 15:30:54 +02:00
6ba8498307 Fix memleak whene deleting IDs with uuid! 2016-06-30 13:02:09 +02:00
b18270f43a Add utility to print UUID (could make it nicer, but for now will do). 2016-06-30 10:44:10 +02:00
3db91def28 Reduce re-allocation while fetching UUIDs per asset engine (asset reload area). 2016-06-30 10:41:03 +02:00
4dd6ffaf37 Split Library/ID asset-related management into own library_asset file.
This is specific enough to deserve its own file imho, and though rather small
currently, it's likely to grow...
2016-06-29 22:38:49 +02:00
4137cc79f2 Cleanup: rename BKE_asset to BKE_asset_engine.
Since this file mostly defines/handles interactions with asset engines...

Asset handling itself is more done in library area (will split it too in next commit).
2016-06-29 22:09:37 +02:00
b25c224d90 Merge branch 'master' into asset-engine 2016-06-29 18:01:35 +02:00
732cd96737 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenloader/intern/writefile.c
2016-06-28 18:21:53 +02:00
71278cc22a Merge branch 'master' into asset-experiments 2016-06-27 17:44:15 +02:00
99869dab7c Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/BKE_library.h
	source/blender/blenkernel/intern/brush.c
	source/blender/blenkernel/intern/library.c
	source/blender/blenkernel/intern/library_remap.c
	source/blender/blenkernel/intern/mesh.c
	source/blender/blenloader/BLO_readfile.h
	source/blender/blenloader/intern/readfile.c
	source/blender/blenloader/intern/writefile.c
	source/blender/editors/space_action/space_action.c
	source/blender/editors/space_clip/space_clip.c
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_graph/space_graph.c
	source/blender/editors/space_image/space_image.c
	source/blender/editors/space_logic/space_logic.c
	source/blender/editors/space_nla/space_nla.c
	source/blender/editors/space_node/space_node.c
	source/blender/editors/space_outliner/outliner_edit.c
	source/blender/editors/space_sequencer/space_sequencer.c
	source/blender/editors/space_text/space_text.c
	source/blender/editors/space_view3d/space_view3d.c
	source/blender/makesrna/intern/rna_ID.c
	source/blender/makesrna/intern/rna_main_api.c
	source/blender/windowmanager/intern/wm_files_link.c
	source/blender/windowmanager/wm_files.h
2016-06-27 17:29:09 +02:00
d012380cae Merge branch 'asset-engine' into asset-experiments 2016-06-16 23:45:02 +02:00
4c086f6b80 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/blenkernel/BKE_library.h
	source/blender/blenkernel/intern/library.c
2016-06-16 23:44:43 +02:00
56677f4f14 Fix remaining cases of datablocks' BKE_foo_free() touching usercount of their IDs.
Note that a few sub-data (like animdata) needs to keep option to unlink their
own ID usages themselves for now, this is not ideal, but need some more time
to mumble on this and find an elegant fix. Nothing blocking here anyway.
2016-06-16 22:06:32 +02:00
bb4c87a130 Merge branch 'master' into asset-engine 2016-06-16 21:17:45 +02:00
4853f75073 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2016-06-16 21:13:15 +02:00
04ee81a081 Merge branch 'master' into id-remap 2016-06-16 19:24:14 +02:00
42dda95e89 Merge branch 'master' into id-remap 2016-06-16 18:12:53 +02:00
21b5ce57f5 Fix bad handling of RegionView3Ds in View3D ID remap callback. 2016-06-16 18:10:44 +02:00
c24ba18d7a Found more id-remap missing cases in spaces (new(?) ads of anim editors). 2016-06-16 17:16:25 +02:00
1eac4fde27 Fix missing mask ID pointer update in Clip/Image spaces' remap callbacks. 2016-06-16 16:56:20 +02:00
fc10e42de3 Finish TODOs related to buttons space and ID remapping. 2016-06-16 16:47:32 +02:00
0256d5dde9 Fix reload/relocate trying to use invalid lib path. 2016-06-16 16:06:10 +02:00
7cbe356c4f Fix broken compilation after recent refactor. 2016-06-16 15:59:30 +02:00
bde19b57d6 Cleanup from review comments. 2016-06-16 15:54:22 +02:00
dbf7d30744 Merge branch 'master' into id-remap 2016-06-16 15:39:54 +02:00
d430237282 Cleanup: headers 2016-06-16 20:43:34 +10:00
5fd97c6e85 Move remapping functions into BKE_library_remap.h
This is done since remapping is quite an involved process.
2016-06-16 20:28:54 +10:00
1880cb6c75 Merge branch 'master' into id-remap 2016-06-16 20:03:53 +10:00
25e0f5e9f2 Fixes/updates needed to make asset reload work with new virtual lib stuff. 2016-06-14 17:41:29 +02:00
b74ad975fd Merge branch 'id-remap' into asset-experiments 2016-06-14 16:39:53 +02:00
0d8e70600b Merge branch 'asset-engine' into asset-experiments 2016-06-14 16:39:47 +02:00
beaf33dfb2 Merge branch 'master' into id-remap 2016-06-14 16:36:42 +02:00
46cf8ba269 Cleanup. 2016-06-14 16:36:15 +02:00
f7b21186b5 Merge branch 'master' into asset-engine 2016-06-14 16:31:58 +02:00
fe41942a90 Cleanup: move 'virtual lib' linking code into own helper. 2016-06-14 15:56:32 +02:00
c6d3f76e69 Fix save/load issues with new virtual-lib assets. 2016-06-14 15:47:54 +02:00
69ae86193c Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenloader/intern/writefile.c
2016-06-14 15:07:18 +02:00
5aaf18c39c WIP experimental support of direct image-as-linkeddata.
Works okish, but break on load (or save) of .blend file currently...
2016-06-13 21:40:48 +02:00
cbf241510d First step towards supporting non-blender-data as assets.
Idea is to avoid the need for asset engines to generate whole .blend files
with relevant datablocks in case they just need/want to provide files (images, videos, sounds...).

This commit introduces the concept of 'virtual' library, which in fact only exists to store
asset repository data. Datablocks from those virtual libs are then fully written in .blend file.

Much to do still, this is only preliminary/experimental work.
2016-06-13 17:39:02 +02:00
088d32d159 Some minor fixes/enhancements.
Asset engines are now only selectable and used in link/append case. Makes no real sense to have
those in other cases (like regular file opening, or even worse when saving a file!).
Also allows to get back asset engine persistance accross filebrowser usage.
2016-06-13 15:06:52 +02:00
d24c85fc12 Merge branch 'asset-engine' into asset-experiments 2016-06-13 12:54:44 +02:00
595159614f Merge branch 'id-remap' into asset-experiments 2016-06-13 12:54:38 +02:00
98654a9c9a Merge branch 'master' into asset-experiments 2016-06-13 12:54:32 +02:00
4286b606b3 Merge branch 'master' into asset-engine 2016-06-13 12:50:06 +02:00
09df8bd2e0 Merge branch 'master' into id-remap 2016-06-13 12:47:09 +02:00
836ecc6142 Merge branch 'asset-engine' into asset-experiments 2016-06-07 10:17:23 +02:00
0f5642b155 Merge branch 'id-remap' into asset-experiments 2016-06-07 10:17:16 +02:00
b1171ea31c Merge branch 'master' into asset-engine 2016-06-07 10:12:59 +02:00
3f4113ce3e Merge branch 'master' into id-remap 2016-06-07 10:10:14 +02:00
aa5f4d98fc Merge branch 'asset-engine' into asset-experiments 2016-06-07 09:44:08 +02:00
6f20d64f3a Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/makesdna/DNA_ID.h
2016-06-07 09:43:56 +02:00
fd12edebf4 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/makesdna/DNA_ID.h
2016-06-07 09:42:52 +02:00
18f87c8dcb Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenloader/intern/readfile.c
2016-06-07 09:27:56 +02:00
434a851703 Merge branch 'asset-engine' into asset-experiments 2016-05-31 09:58:19 +02:00
7282c6592a Merge branch 'id-remap' into asset-experiments 2016-05-31 09:58:08 +02:00
77cdf1fb49 Merge branch 'master' into asset-engine 2016-05-31 09:53:40 +02:00
2c9f6714a7 Fix merge error. 2016-05-31 09:53:16 +02:00
9400ea0647 Merge branch 'master' into id-remap 2016-05-31 09:38:38 +02:00
8346805963 Merge branch 'asset-engine' into asset-experiments 2016-05-24 15:49:11 +02:00
050209d16e Merge branch 'id-remap' into asset-experiments 2016-05-24 15:49:03 +02:00
0929283ddc Merge branch 'master' into asset-experiments 2016-05-24 15:48:55 +02:00
5afc102357 Fix alignement issues in some DNA struct due to ID one now being properly aligned. 2016-05-24 15:48:15 +02:00
6bae015985 Merge branch 'master' into asset-engine 2016-05-24 14:44:13 +02:00
ba1af2e1bf Some cleanup. 2016-05-24 14:43:48 +02:00
adbd9cb1de Better name handling in case we remap an ID adn cannot replace it totally. 2016-05-24 14:10:28 +02:00
16641d4c02 Merge branch 'master' into id-remap 2016-05-24 12:29:07 +02:00
4795d6bdb1 Merge branch 'master' into id-remap 2016-05-23 18:18:36 +02:00
542302e3f6 Revert "Squashed commit of the atomic-operations branch."
This reverts commit ffe7f4175a.
2016-05-09 15:12:16 +02:00
ffe7f4175a Squashed commit of the atomic-operations branch. 2016-05-09 15:11:40 +02:00
cb530ad07e Merge branch 'asset-engine' into asset-experiments 2016-05-06 13:34:15 +02:00
084f5e9a4d Merge branch 'id-remap' into asset-experiments 2016-05-06 13:34:06 +02:00
4c8e2ebde2 Merge branch 'master' into asset-experiments 2016-05-06 13:33:59 +02:00
d27bae4432 Merge branch 'master' into asset-engine 2016-05-06 13:30:37 +02:00
cbe6475383 Merge branch 'master' into id-remap 2016-05-06 13:28:20 +02:00
93c9ff858a First 'working' version of asset reload.
Dead dummy simplistic test runs (nearly) OK here (only have a memleak from versionning code...),
but obviously will need much serious tests to validate everything.

Also, many things in code will need cleanup/refactor. Not to mention UI/UX.

But we do have asset version check & reload on file opening now! :D

Process summary:
I) Open .blend file exactly as in master, load assets just like any other linked data (add placeholders in case not found).
II) Check all asset engines and ask them whether each asset is OK, needs to be updated/reloaded, is missing...
III) User then can decide to actually reload the asset, or not.

Step II) happens in an async job (since engines using remote storage/database could take some time to answer),
step III) is a locking task (just like initial linking). This should allow user to not be blocked at all by that
asset update process.
2016-05-06 13:16:24 +02:00
7cf890e126 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/readfile.c
2016-05-06 13:05:49 +02:00
961ebfa8c4 Set a main's version to current one after do_version is done.
With current master this is not an issue, but with all the reload stuff,
a same main could end up going several time into 'do_version', which is absolutely
not desired (multi-allocations, repeating conversions over some values, etc.).
2016-05-06 13:03:31 +02:00
341237035f Merge branch 'asset-engine' into asset-experiments 2016-05-06 11:09:56 +02:00
82359a7997 Do not update asset repo info inside link code.
Whole 'database' is rebuilt later anyway, and in more complex 'asset reload' cases
(where we may actually be reloading same asset with same uuid from same lib file),
this creates confusion...
2016-05-06 11:07:53 +02:00
4a429f1525 Merge branch 'asset-engine' into asset-experiments 2016-05-05 17:20:10 +02:00
fa21019745 Add global 'asset search by uuid' helper. 2016-05-05 17:19:27 +02:00
f4e4575e3c Merge branch 'asset-engine' into asset-experiments 2016-05-03 17:52:31 +02:00
a6f085f3c9 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/windowmanager/intern/wm_files_link.c
2016-05-03 17:52:19 +02:00
39da83e974 Merge branch 'master' into asset-experiments 2016-05-03 17:45:25 +02:00
783d63f6af Merge branch 'master' into asset-engine 2016-05-03 17:45:05 +02:00
a6a8ff103d Lib relocate/reload: serious rework of code.
Idea here is to both factorize it seriously (reload and relocate are very similar, let's
avoid as much as possible twice the same code...), and make new `lib_relocate_do()`
much more flexible - now it should be able to reload individual IDs as well
(plan is to use it to reload assets in relelvant branch too).
2016-05-03 17:42:23 +02:00
a97da9842c Merge branch 'master' into id-remap 2016-05-03 16:58:34 +02:00
861318bbb9 Merge branch 'master' into asset-engine 2016-05-03 15:32:30 +02:00
41c5ec21b3 Merge branch 'master' into id-remap 2016-05-03 15:32:05 +02:00
b7525de284 Merge branch 'asset-engine' into asset-experiments 2016-05-03 09:57:24 +02:00
071a27f918 Amber: Fix load_pre not using correct repo! 2016-05-03 09:56:44 +02:00
90af45d5b5 Merge branch 'asset-engine' into asset-experiments 2016-05-02 20:51:58 +02:00
56ea898ade Merge branch 'id-remap' into asset-experiments 2016-05-02 20:51:51 +02:00
d95671442d Merge branch 'master' into asset-experiments 2016-05-02 20:51:44 +02:00
26658afad1 Amber: fix missing '..' parent dir entry when inside a repo. 2016-05-02 20:50:57 +02:00
70eb04328c Change how Amber (and all other engines) are expected to work.
So far, we were accepting the idea of several repositories per asset engine (e.g. different
directories in case of Amber). However, if this works OK during listing/initial linking,
it makes things way more complicated later in asset management, since asset uuid is no more
enough to unically indentify an asset!

Now an asset UUID is assumed to be really unique inside an asset engine.

For Amber, we 'salt' assets' uuids with new repo uuids (both being only 2 ints long now),
and keep a config 'cache' of mapping repo uuid -> path to repo.
2016-05-02 20:35:08 +02:00
a47653e5d4 Merge branch 'master' into asset-engine 2016-05-02 14:31:25 +02:00
dd63b849f8 Merge branch 'master' into id-remap 2016-05-02 14:28:49 +02:00
266d99ee42 More WIP code for actual assets reload.
Nothing working yet, need to solve some issue with rootpath actually...
2016-04-28 23:15:46 +02:00
5ad251770b Merge branch 'asset-engine' into asset-experiments 2016-04-28 22:40:03 +02:00
6c478490ea Refactor load_pre helper to work from both DirEntries and uuids... 2016-04-28 22:39:12 +02:00
e451d9b56a WIP (mostly empty for now) code to actually reload assets reported as needing it by update_check. 2016-04-28 21:44:59 +02:00
8bf511ef0b Merge branch 'asset-engine' into asset-experiments 2016-04-28 21:34:46 +02:00
ef14700089 Cleanup: get rid of blocking asset update_check code. 2016-04-28 21:32:32 +02:00
20bf7d949f Some refactor in asset update_check code.
Fetching assets' uuids by engines is now in own func (will be used by update op itself too).

Also, each AssetRef has only *one* asset ID, the first one, avoids us a useless loop!

And early out of update_check op in case we have no asset in current Main, no need to start
job in this case.
2016-04-28 21:30:14 +02:00
60cd55692d Merge branch 'asset-engine' into asset-experiments 2016-04-27 13:16:04 +02:00
b3be710e19 Some tweaks to flags & versionning handling for assets update check. 2016-04-27 13:15:39 +02:00
03d23c42a2 Merge branch 'master' into asset-experiments 2016-04-27 11:02:04 +02:00
42ea7490e5 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/windowmanager/intern/wm_files_link.c
	source/blender/windowmanager/wm_files.h
2016-04-27 11:01:48 +02:00
d4a9111f08 Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2016-04-27 10:58:41 +02:00
e812fb4825 Add some header info about asset errors or reload needs.
Again, rather rough UI but enough to be useful for now.
2016-04-26 16:42:00 +02:00
cf08eec187 Add simple dummy code in outliner to show assets and their status.
This is purely WIP helper stuff, final UI will need real work - but that's for later.
2016-04-26 16:02:51 +02:00
32c83ba950 Merge branch 'master' into asset-engine 2016-04-26 14:42:05 +02:00
c2a5f95122 Merge branch 'master' into id-remap 2016-04-26 14:33:54 +02:00
b1c715a5fa Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenkernel/intern/blender.c
	source/blender/windowmanager/intern/wm_files.c
	source/blender/windowmanager/intern/wm_init_exit.c
2016-04-25 16:55:41 +02:00
60474d11c7 Merge branch 'master' into id-remap 2016-04-25 16:41:26 +02:00
6e1fdd6f2d Actually hook async job of asset updating! 2016-04-20 17:11:14 +02:00
6cdc7c9587 Add 'ensure_uuids' callback to API, fix some flags in RNA code. 2016-04-20 17:08:42 +02:00
8154ee7bb2 Make opening .blend file use new async 'check asset updates' operator.
Nothing much exciting really, just not blocking anymore.
2016-04-20 16:44:07 +02:00
68eaa00290 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2016-04-19 23:21:05 +02:00
8055eae905 Merge branch 'master' into id-remap
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2016-04-19 23:03:53 +02:00
7cb1438035 Asset update: WIP proof-of-concept async (job-based) update code.
Builds, but not tested nor hoocked to anything yet!
2016-04-19 13:07:33 +02:00
e1c0b2ff25 Merge branch 'master' into asset-engine 2016-04-16 15:02:16 +02:00
54307d778d Merge branch 'master' into id-remap 2016-04-16 14:59:16 +02:00
1d40cfafea Move core of update check to BKE's asset area, add an operator for that too. 2016-04-15 10:38:49 +02:00
f36307db4b Merge branch 'master' into asset-engine 2016-04-12 12:30:40 +02:00
9437647f5d Merge branch 'master' into id-remap 2016-04-12 12:21:00 +02:00
9804f9181f Make 'check update' async, and add possibilities for engines to make async callbacks 'immediate'.
So now, jobs callback (async ones) of asset may return a specific job id value in case they actually
complete (or fail) on the first run.

This allows engines that do not need slow async stuff to perform an action to use simpler code
(e.g. imagine an engine able to list its assets from a cached DB, in most cases its list_dir
callback can execute instantaneously (from a user PoV), no need for a listing job then).
2016-04-11 17:35:31 +02:00
09f134aa6c Make asset engine's load_pre callback mandatory now.
Reason is, even if paths returned by `list_dir` are OK, we will also use `load_pre`
during 'reload'/'update' scenarii, where we only have uuids, to retrieve final
.blend datablock paths.
2016-04-11 16:14:05 +02:00
cb926ab6c9 Merge branch 'master' into asset-engine 2016-04-09 15:44:26 +02:00
28382bad00 Merge branch 'master' into id-remap 2016-04-09 15:41:46 +02:00
5b67ec9c9f Always reset to default asset engine (i.e. regular filebrowser code) when opening a new browser.
Else we'd have the last used engine even when saving a .blend or picture, ugly!
2016-04-07 16:35:34 +02:00
7dea5c2462 Finish implementing 'reports' in asset engine (not used yet). 2016-04-07 16:18:42 +02:00
f53c4dd29e Some minor fixes/updates of AE API comments. 2016-04-07 15:50:53 +02:00
1e3d75604d Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/blender.c
2016-04-07 15:26:32 +02:00
897249b254 Merge branch 'id-remap' into asset-experiments 2016-04-07 15:25:42 +02:00
718f8fe55f Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/BKE_library_query.h
	source/blender/blenkernel/intern/blender.c
	source/blender/blenkernel/intern/library_query.c
2016-04-07 15:25:23 +02:00
698b15538b Fix issue with uuid generation in Amber. 2016-04-06 18:05:02 +02:00
aec80da8f8 More or less finished shell of 'update' code.
Code only reports which datablocks/assets shall be reloaded etc. so far, actual
reloading needs id-remap code (and hence will be implemented in asset-experiment
branch later).
2016-04-06 17:38:12 +02:00
9a31359e07 Merge branch 'master' into asset-engine 2016-04-06 15:23:45 +02:00
b111e0f645 Merge branch 'master' into id-remap 2016-04-06 15:16:39 +02:00
8b81b71cf2 Merge branch 'master' into asset-engine 2016-04-04 14:45:52 +02:00
46206fd9a5 Merge branch 'master' into id-remap 2016-04-04 14:39:59 +02:00
96aa445527 Add a 'check_dir' callback to asset engines, allowing them to control current 'root dir'.
Note that this is hacked around bpyrna incapacity to handle strings as return values of functions callbacks...
2016-03-31 20:50:29 +02:00
d63895ee30 Merge branch 'master' into asset-engine 2016-03-30 21:39:09 +02:00
f820643e9f Merge branch 'master' into id-remap 2016-03-30 21:37:49 +02:00
e9d7c741ca Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2016-03-30 21:31:21 +02:00
826ba124b6 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2016-03-30 21:10:10 +02:00
0ab784332a Merge branch 'libquery-recursive' into asset-engine 2016-03-23 17:16:52 +01:00
cab4bd90c1 Merge branch 'master' into asset-engine 2016-03-23 17:16:45 +01:00
c1452617fb Merge branch 'libquery-recursive' into id-remap 2016-03-23 17:08:32 +01:00
50d2c7f8f4 Merge branch 'master' into id-remap 2016-03-23 17:08:26 +01:00
f0f46e9ef6 Rework library_query foreach looper - add optional recursivity.
This commit:
* Fixes bad handling of 'stop iteration' (by adding a status flag, so that we can actually
  stop in helper functions too, and jumping to a finalize label instead of raw return, to
  allow propper clean up).
* Adds optional recursion into 'ID tree' - callback can also decide to exclude current id_pp
  from recursion. Note that this implies 'readonly', modifying IDs while recursing is not
  something we want to support!
* Changes callback signature/expected behavior: return behavior is now handled through flags,
  and 'parent' ID of id_pp is also passed (since it may not always be root id anymore).

Used this new recursive behavior in ID preview generation as an example, would obviously be committed separately.

Reviewers: sergey, campbellbarton

Differential Revision: https://developer.blender.org/D1869
2016-03-23 13:15:41 +01:00
be5c2a5266 Finish RNA flags for asset UUIDs! 2016-03-17 14:54:29 +01:00
484f1bc226 Merge branch 'libquery-recursive' into asset-engine 2016-03-17 12:52:10 +01:00
97cb96720c Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenkernel/intern/blender.c
2016-03-17 12:51:53 +01:00
37c4db1125 Merge branch 'libquery-recursive' into id-remap 2016-03-17 12:26:34 +01:00
cb770e58ad Merge branch 'master' into id-remap 2016-03-17 12:26:25 +01:00
09444bca5f Merge branch 'master' into libquery-recursive 2016-03-17 12:23:42 +01:00
a639446614 More WIP work towards designing Updated feature for assets/engines. 2016-03-09 20:33:38 +01:00
22f5772b44 Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/creator/creator.c
2016-03-07 16:42:19 +01:00
8403577397 Merge branch 'id-remap' into asset-experiments 2016-03-07 15:37:43 +01:00
ebe52b71a5 Merge branch 'libquery-recursive' into asset-experiments 2016-03-07 15:37:35 +01:00
59aeb07895 Merge branch 'master' into asset-experiments
Conflicts:
	source/creator/creator.c
2016-03-07 15:37:22 +01:00
b0a541a76c Slightly modified way to check for assets on loadfile.
Since we now build a list of assets and their dependencies in Library datablocks, use it!
2016-03-07 15:03:28 +01:00
c93a86909c Merge branch 'libquery-recursive' into asset-engine 2016-03-06 14:57:20 +01:00
204ec489b8 Merge branch 'master' into asset-engine 2016-03-06 14:57:10 +01:00
873e90be65 Merge branch 'libquery-recursive' into id-remap 2016-03-06 14:54:06 +01:00
30b90cbb01 Merge branch 'master' into id-remap 2016-03-06 14:53:57 +01:00
f500019eac Merge branch 'master' into libquery-recursive 2016-03-06 14:51:03 +01:00
3cfea6eadc Merge branch 'libquery-recursive' into asset-engine 2016-03-04 14:35:18 +01:00
304cdfa476 Merge branch 'master' into asset-engine 2016-03-04 14:35:05 +01:00
cea847738a Merge branch 'libquery-recursive' into id-remap 2016-03-04 14:25:27 +01:00
bb3d3cc9cf Merge branch 'master' into id-remap 2016-03-04 14:25:20 +01:00
3d4ac80157 Merge branch 'master' into libquery-recursive 2016-03-04 14:24:59 +01:00
8b4997c6c7 WIP dummy code to update assets on file (re)load.
Actual code will be implemented in asset-experiment (we need id-remap code for this),
but will first try to define dummy API in this branch.
2016-03-01 16:58:31 +01:00
beff4ca725 Merge branch 'libquery-recursive' into asset-engine 2016-02-29 15:33:21 +01:00
982dd93357 Merge branch 'master' into asset-engine 2016-02-29 15:33:07 +01:00
2fa8db4ec6 Merge branch 'libquery-recursive' into id-remap 2016-02-29 15:21:54 +01:00
fa4d7deac0 Merge branch 'master' into id-remap 2016-02-29 15:21:39 +01:00
2a09cb62e2 Merge branch 'master' into libquery-recursive 2016-02-29 15:15:49 +01:00
0588ca9c08 Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/readfile.c
	source/blender/windowmanager/intern/wm_operators.c
2016-02-25 15:07:27 +01:00
bb75900289 Merge branch 'id-remap' into asset-experiments 2016-02-25 14:55:56 +01:00
49e2a441cb Merge branch 'libquery-recursive' into asset-engine 2016-02-25 14:45:49 +01:00
ae9ae24c95 Merge branch 'libquery-recursive' into id-remap 2016-02-25 14:43:04 +01:00
d1dd9b6261 Merge branch 'master' into id-remap 2016-02-25 14:42:55 +01:00
5b5f55067b Merge branch 'master' into libquery-recursive 2016-02-25 14:21:30 +01:00
37f58ffec9 Forgot to include AnimationData into new recursive libquery foreach... 2016-02-25 14:20:58 +01:00
59a1340714 Add asset dependencies (re)build.
Is rebuilt when we link a new asset, or when we (re)load a .blend file.
Runtime data only, not saved in .blend file.
2016-02-24 20:42:58 +01:00
adfd89d9bd Merge branch 'libquery-recursive' into asset-engine 2016-02-24 10:35:00 +01:00
85959e8b4a Merge branch 'master' into asset-engine 2016-02-24 10:34:50 +01:00
c448d4422e Merge branch 'libquery-recursive' into id-remap 2016-02-24 10:34:14 +01:00
3dfd063697 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library.c
2016-02-24 10:26:50 +01:00
e714e1c5ef Merge branch 'master' into libquery-recursive 2016-02-24 10:18:38 +01:00
3054a8a91b Merge branch 'master' into libquery-recursive 2016-02-20 18:06:13 +01:00
dc34313dc9 Merge branch 'libquery-recursive' into asset-engine 2016-02-19 10:53:52 +01:00
afdf2a3fb2 Merge branch 'master' into asset-engine 2016-02-19 10:53:38 +01:00
aabe83d4c0 Merge branch 'libquery-recursive' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2016-02-19 10:50:26 +01:00
9bb32dd445 Merge branch 'master' into id-remap 2016-02-19 10:48:24 +01:00
87a385b838 Cleanup (remove some useless diff compared to master). 2016-02-19 10:47:32 +01:00
3652a0e7da Merge branch 'master' into libquery-recursive 2016-02-19 10:29:18 +01:00
b6022f1488 Fix for new libquery callback API. 2016-02-18 23:11:03 +01:00
6a951054d0 Merge branch 'libquery-recursive' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2016-02-18 18:10:57 +01:00
6ec0026f8d Merge branch 'libquery-recursive' into asset-engine 2016-02-18 17:56:58 +01:00
827b1457ca Rework library_query foreach looper - add optional recursivity.
This commit:
* Fixes bad handling of 'stop iteration' (by adding a status flag, so that we can actually
  stop in helper functions too, and jumping to a finalize label instead of raw return, to
  allow propper clean up).
* Adds optional recursion into 'ID tree' - callback can also decide to exclude current id_pp
  from recursion. Note that this implies 'readonly', modifying IDs while recursing is not
  something we want to support!
* Changes callback signature/expected behavior: return behavior is now handled through flags,
  and 'parent' ID of id_pp is also passed (since it may not always be root id anymore).

Used this new recursive behavior in ID preview generation as an example, still needs more testing!
2016-02-18 17:53:42 +01:00
40562d0e11 Merge branch 'master' into asset-engine 2016-02-18 17:35:12 +01:00
cd43bd241f Merge branch 'master' into asset-engine 2016-02-16 14:35:54 +01:00
a9054360c6 Merge branch 'master' into id-remap 2016-02-15 19:46:24 +01:00
66375326b4 Merge branch 'master' into asset-engine 2016-02-15 19:39:57 +01:00
3eefdc0ed7 WIP Add asset sub-data dependency info.
We need that info (knowing which non-asset IDs are used by which asset-IDs),
otherwise managing reloading, updates etc. of assets would be impossible
(or rather, would leave a mess of unused IDs behind them).
Only partially done, non-functional yet.

This commit also adds asset repository references in libraries.
2016-02-15 16:52:12 +01:00
14d11c1609 Merge branch 'asset-engine' into asset-experiments 2016-02-14 20:31:37 +01:00
6b61c25815 Merge branch 'id-remap' into asset-experiments 2016-02-14 20:31:31 +01:00
576eca8ab3 Merge branch 'master' into asset-engine 2016-02-14 20:27:48 +01:00
ad72025611 Merge branch 'master' into id-remap 2016-02-14 20:24:53 +01:00
65e357fe56 Merge branch 'asset-engine' into asset-experiments 2016-02-12 10:06:03 +01:00
46903fbccf Merge branch 'id-remap' into asset-experiments 2016-02-12 10:05:56 +01:00
ac2e25986c Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenkernel/intern/library.c
2016-02-12 10:05:28 +01:00
71b65b417c Merge branch 'master' into id-remap 2016-02-12 09:55:22 +01:00
30db6e0cb7 Merge branch 'master' into asset-engine 2016-02-03 10:06:45 +01:00
2ca8421987 Assets: add uuid to linked data, write and read it from file.
Note that this is only very first steps, I think we'll need to 'propagate'
uuid to all data used/linked by asset itself, otherwise most things won't get
updated/reloaded. Still have to think about this.
2016-02-02 14:14:15 +01:00
11c6fed3ee Merge branch 'master' into asset-engine 2016-02-02 14:10:27 +01:00
f3de9752fd Merge branch 'id-remap' into asset-experiments 2016-02-01 14:05:11 +01:00
1b34246af2 Merge branch 'master' into id-remap 2016-02-01 14:04:48 +01:00
dded3bb21f Merge branch 'asset-engine' into asset-experiments 2016-01-31 15:09:24 +01:00
3f63cb8843 Merge branch 'id-remap' into asset-experiments 2016-01-31 15:09:17 +01:00
d1b4471012 Merge branch 'master' into asset-engine 2016-01-31 15:05:09 +01:00
5b16d59ffc Merge branch 'master' into id-remap 2016-01-31 14:59:57 +01:00
f1fc8959db Assets: add uuid to linked data, write and read it from file.
Note that this is only very first steps, I think we'll need to 'propagate'
uuid to all data used/linked by asset itself, otherwise most things won't get
updated/reloaded. Still have to think about this.
2016-01-21 16:12:08 +01:00
955cb4a8db Merge branch 'asset-engine' into asset-experiments 2016-01-21 09:46:46 +01:00
351f74dee9 Merge branch 'id-remap' into asset-experiments 2016-01-21 09:46:39 +01:00
da81c78fc7 Merge branch 'master' into asset-engine 2016-01-21 09:45:52 +01:00
911095d372 Merge branch 'master' into id-remap
Conflicts:
	source/blender/editors/space_outliner/outliner_tools.c
2016-01-21 09:45:18 +01:00
d9a93eb3bd Merge branch 'asset-engine' into asset-experiments 2016-01-20 15:31:01 +01:00
27470754b6 Merge branch 'id-remap' into asset-experiments 2016-01-20 15:30:53 +01:00
6b1065b11c Merge branch 'master' into asset-engine 2016-01-20 15:02:49 +01:00
1705fd66d8 Merge branch 'master' into id-remap 2016-01-20 15:02:29 +01:00
28adc7d248 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2016-01-20 14:27:45 +01:00
f4214d1d1c Merge branch 'asset-engine' into asset-experiments 2016-01-15 16:31:13 +01:00
48f9931257 Merge branch 'id-remap' into asset-experiments 2016-01-15 16:31:06 +01:00
a0803fabfe Merge branch 'master' into asset-engine 2016-01-15 16:24:55 +01:00
6eec8eaa57 Merge branch 'master' into id-remap 2016-01-15 15:26:34 +01:00
498b712a37 Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2016-01-14 20:32:03 +01:00
0fa187e4b5 Fix handling of asset uuid in WMLinkAppendDataItem helper struct.
We need a pointer here (reduces mem footprint, and allows to say 'we have no uuid' with a NULL value!).
2016-01-14 20:29:40 +01:00
a9284fd093 Merge branch 'asset-engine' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/library.c
2016-01-12 16:23:06 +01:00
8af7d783c7 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/library.c
2016-01-12 16:21:34 +01:00
a7cfb5fc22 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenkernel/intern/library.c
2016-01-12 16:08:05 +01:00
a414edc0af Merge branch 'master' into id-remap 2016-01-12 16:01:17 +01:00
4c535c07c6 Fix & cleanup in outliner area.
Now all new entries in items' menus should behave correctly!
2016-01-07 21:47:47 +01:00
22f5a17b9c Fix some bad id->flag/tag mismatch from not-so-recent merge with master... 2016-01-07 16:14:16 +01:00
07b8b90f39 Fix assert when deleting obdata.
Issue here is again with NEVER_NULL usages: obdata (& co) would be dereferenced twice.

I'm not totally happy with this solution, ideally remap should never leave Main
in invalid state, but for now it will do...
2016-01-07 16:11:14 +01:00
5a65830830 Fix a crash when deleting a lib featuring some proxyob source... 2016-01-07 14:51:37 +01:00
f2db96fbaf Merge branch 'master' into id-remap 2016-01-07 10:28:55 +01:00
2e8297108d Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/BKE_library_query.h
	source/blender/blenkernel/intern/library_query.c
	source/blender/makesrna/intern/rna_ID.c
2016-01-06 21:40:12 +01:00
eaa892c14f Merge branch 'asset-engine' into asset-experiments 2016-01-04 20:41:15 +01:00
f3077f411d Merge branch 'id-remap' into asset-experiments 2016-01-04 20:41:08 +01:00
46e6f3b420 Merge branch 'master' into asset-engine 2016-01-04 20:35:05 +01:00
fc7f086f4b Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library.c
2016-01-04 20:34:31 +01:00
74393f8f15 Merge branch 'asset-engine' into asset-experiments 2016-01-04 12:10:26 +01:00
9c3e0b558c Merge branch 'id-remap' into asset-experiments 2016-01-04 12:10:19 +01:00
e49966dd96 Merge branch 'master' into asset-engine 2016-01-04 11:55:56 +01:00
e921ecabaf Merge branch 'master' into id-remap 2016-01-04 10:58:39 +01:00
e58cae1b7a Merge branch 'asset-engine' into asset-experiments 2015-12-31 12:56:53 +01:00
e28986aa8f Merge branch 'id-remap' into asset-experiments 2015-12-31 12:56:45 +01:00
19e6c23b75 Merge branch 'master' into asset-engine 2015-12-31 12:50:34 +01:00
9ae928ff9d Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/BKE_library.h
	source/blender/blenkernel/BKE_material.h
2015-12-31 12:50:08 +01:00
b40d4ba517 Merge branch 'asset-engine' into asset-experiments 2015-12-27 13:09:54 +01:00
8d3129cba2 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/library.c
	source/blender/windowmanager/intern/wm_operators.c
2015-12-27 13:09:42 +01:00
009ccfecb6 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/blenkernel/intern/library.c
	source/blender/windowmanager/intern/wm_operators.c
2015-12-27 13:06:34 +01:00
f4e7fec73c Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenloader/intern/readfile.c
	source/blender/makesdna/DNA_ID.h
2015-12-27 12:54:57 +01:00
a6e9aba17f Merge branch 'master' into id-remap 2015-12-20 15:41:27 +01:00
b9c5da9ba8 Merge branch 'master' into id-remap
Conflicts:
	source/blender/editors/space_outliner/outliner_edit.c
	source/blender/editors/space_outliner/outliner_intern.h
	source/blender/editors/space_outliner/outliner_tools.c
2015-12-18 22:17:25 +01:00
4eaa6c4a7b Merge branch 'master' into id-remap 2015-12-18 21:23:27 +01:00
b46b921738 Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/blenloader/BLO_readfile.h
	source/blender/blenloader/intern/readfile.c
2015-12-17 19:39:05 +01:00
dab1a1dd5f Merge main remap funcs' bool parameters into a single bitflag.
Too much bools kill bools.
2015-12-17 19:32:33 +01:00
24556b3c3d More cleanup - remove unused stuff, some simplifications. 2015-12-17 14:56:15 +01:00
817fee305f Cleanup: mostly removes useless diff from master. 2015-12-17 13:21:18 +01:00
613bf6755e Merge branch 'id-remap' into asset-experiments
Conflicts:
	source/blender/blenloader/BLO_readfile.h
	source/blender/blenloader/intern/readfile.c
	source/blender/windowmanager/intern/wm_operators.c
2015-12-16 22:28:31 +01:00
f2ce01f844 Merge branch 'asset-engine' into asset-experiments 2015-12-16 21:50:17 +01:00
3de18048b3 Merge branch 'master' into asset-experiments 2015-12-16 21:50:02 +01:00
d02c201814 Merge branch 'master' into asset-engine 2015-12-16 21:39:49 +01:00
c089f28504 Merge branch 'master' into id-remap 2015-12-16 21:34:04 +01:00
cddbeaeec8 Merge branch 'master' into asset-engine 2015-12-14 16:26:49 +01:00
d0b037d0ef Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/text.c
	source/blender/editors/space_outliner/outliner_edit.c
	source/blender/editors/space_outliner/outliner_tools.c
2015-12-14 16:26:14 +01:00
8bbfd2729a Merge branch 'master' into id-remap 2015-12-07 17:45:41 +01:00
6dffedc75e Fix several issues with logic of core id-remap:
* We need to clear the 'user-one' flags and potential usercount for old_id.
* We need to consider ID usages inside a same lib as **never** being indirect ones.

Also re-enabled proxy checking for now (not sure why I commented it, think testing stuff or so...).
2015-12-07 17:33:35 +01:00
49b67b58aa Fix id-remap looper not 'freeing' 'use-one' id usercount. 2015-12-07 15:54:03 +01:00
67cc51d32d Merge branch 'master' into id-remap 2015-12-07 11:01:09 +01:00
574d63cf65 Merge branch 'master' into asset-engine
Conflicts:
	source/blender/editors/space_file/file_intern.h
	source/blender/editors/space_file/file_ops.c
2015-12-07 11:00:38 +01:00
05bd9572a6 Some more fixes, and make Outliner's delete available for all IDs, not only libraries! 2015-12-04 17:48:00 +01:00
56679ae31c Merge branch 'master' into id-remap 2015-12-04 17:24:43 +01:00
705a247e2e Better handling of usercount during ID deletion, also add this to ID RNA API.
Seems to work for simple cases, but deletion of complex libs from complex files
(Gooseberry ones) still generates lots of assert failures, and crashes in some cases.
2015-12-03 16:34:11 +01:00
e8b46461e6 Merge branch 'master' into id-remap 2015-12-03 14:25:05 +01:00
9584c88b6b Fix a bunch of more stuff, more correct handling of ID/Lib deletion...
Still have some usercount issues here, though things seems to start working...
2015-12-01 21:37:25 +01:00
84d25cb87a Merge branch 'master' into id-remap.
Also, changing how library delete works (not functional currently).

Conflicts:
	source/blender/editors/space_outliner/outliner_edit.c
	source/blender/editors/space_outliner/outliner_ops.c
	source/blender/editors/space_outliner/outliner_tools.c
2015-12-01 17:45:22 +01:00
1da2edfb25 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library_query.c
2015-11-30 15:38:42 +01:00
6f90aa2016 Fix issue when reloading a lib with selected object. 2015-11-30 10:48:55 +01:00
81edad9966 Merge branch 'master' into id-remap 2015-11-28 21:45:12 +01:00
3319e460e6 Merge branch 'master' into id-remap 2015-11-28 15:00:57 +01:00
f66e14611d Attempt to fix RNA nightmare with ListBase used as Collection return type for functions.
This is hacky to make work on Linux, and seems to totally break on Windows.

So now, instead, we define a CollectionListBase (exact copy of ListBase), to be used inside RNA...

Seems to work nicely on Linux, lets see what win buildbot says.
2015-11-26 15:26:05 +01:00
7ce594b544 Merge branch 'master' into id-remap 2015-11-26 15:04:45 +01:00
a0df6ce03b Merge branch 'master' into id-remap 2015-11-26 12:42:56 +01:00
df10b4d7a8 Fix mysterious AC IDs refcount issue when reloading some gooseberry files' libs.
Turned out our libquery ID looper was ignoring constraints' 'reference' parameter in callback, grrr...
2015-11-26 12:00:50 +01:00
bfad4bba7a Add helpers to BKE_library_query to find which datablocks are using/referencing a given ID.
Also expose this in RNA. Priceless to debug ID usages...
2015-11-25 20:48:22 +01:00
d35d72893e Merge branch 'master' into id-remap 2015-11-25 16:23:22 +01:00
b47b035f57 Merge branch 'master' into id-remap 2015-11-25 15:16:26 +01:00
0c161e23d9 Merge branch 'master' into id-remap 2015-11-25 12:48:38 +01:00
a6df054b02 Merge branch 'master' into id-remap 2015-11-24 15:52:04 +01:00
7fa92ad950 Merge branch 'master' into id-remap 2015-11-24 09:50:29 +01:00
91be63e127 Merge branch 'master' into id-remap 2015-11-23 14:21:50 +01:00
387b120579 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenloader/intern/readfile.c
2015-11-19 22:39:11 +01:00
f1a7118c04 Add missing AnimData ID to foreach_ID_loop.
Atempt to fix missing action remapping, but no luck so far. :|
2015-11-12 11:50:01 +01:00
c9df632175 Merge branch 'master' into id-remap 2015-11-12 09:54:20 +01:00
11d4cbb04c Merge branch 'master' into id-remap 2015-11-11 20:22:02 +01:00
e74ce5bd86 Merge branch 'master' into id-remap 2015-11-11 19:53:14 +01:00
ab5a591f91 Do not try to reload directly non-linkable datablocks (shapekeys),
those will get reloaded by 'owner' mesh anyway.

Why, why, why are shapekeys datablocks???
2015-11-11 18:12:08 +01:00
483247d756 Fix Text usage by TextEditor (USER_REAL, not USER_ONE). 2015-11-11 17:43:26 +01:00
ded1333f3c Rework a bit IDRemap struct to separate input flags from output status, and fix
issues with unlinking ParticleSettings.

We now have the option to still decrement user count of old_id, even if we could not
replace it with NULL new_id (aka unlinking), needed to keep proper user count when
unlinking and ID from datablocks it uses, to delete it.
2015-11-11 16:52:15 +01:00
4cf00de7d4 Merge branch 'master' into id-remap 2015-11-11 16:15:53 +01:00
61bad3cfe0 Merge branch 'master' into id-remap 2015-11-11 15:06:32 +01:00
75c5f6135c Silence a bit debug prints! 2015-11-11 12:44:47 +01:00
73c8d3abcc Merge branch 'master' into id-remap 2015-11-11 12:43:51 +01:00
12292d441d Merge branch 'master' into id-remap 2015-11-11 11:49:33 +01:00
9e6cdd8e3a Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/BKE_library.h
	source/blender/blenkernel/intern/library.c

Also clears now useless 'bool is_user_one' flag from editors' ID remap callback.
2015-11-11 10:48:11 +01:00
7a62ac4127 Some minor tweaks. 2015-11-10 20:15:01 +01:00
d2913c1409 Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/object.c
2015-11-10 19:59:44 +01:00
5f0299898d Hopefully fix the 'real user' nightmare.
Idea is to add two new flags, one saying 'we need to ensure a real user exists',
the other 'we had to increment user count to ensure we have a real user'.

This allows us to easily control the extra user in release/delete/remap cases,
and also fixes the infamous 'add new image to texture, open image in ImageEditor,
delete image from texture, have a zero-user red image in Image Editor' issue.

There is still much to be done here, more places where we can use those flags,
also clear them when we force usercount to zero, etc.

All this allows us to fix unsolvable issues (like Group being ensure_user'ed
in loading code, but only if they do have objects in them), and to avoid returning
ugly bool from editors' callbacks (this is still to be cleaned up in the branch too).

Bad news - this means we cannot use short ID->flag anymore (not enough flags), for now
added a new int ID->flag2 (replacing pad int), not sure how to best manage change here,
maybe for 2.8 we can totally wipe ID->flag? But this would totally break forward compat.
2015-11-10 16:56:54 +01:00
9ddc60bc10 Merge branch 'master' into id-remap 2015-11-10 16:21:37 +01:00
959e2e8cfe Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/library.c
2015-11-10 14:51:42 +01:00
965d9649c4 Minor update/cleanup on usercount, from work done in master. 2015-11-10 14:47:38 +01:00
033a89957c Merge branch 'master' into id-remap
Conflicts:
	source/blender/blenkernel/intern/curve.c
	source/blender/blenkernel/intern/linestyle.c
	source/blender/blenkernel/intern/material.c
	source/blender/blenkernel/intern/mball.c
	source/blender/blenkernel/intern/mesh.c
	source/blender/blenkernel/intern/object.c
	source/blender/blenkernel/intern/particle.c
	source/blender/blenkernel/intern/scene.c
	source/blender/blenkernel/intern/world.c
2015-11-10 12:45:42 +01:00
e43d70a60f Merge branch 'master' into id-remap 2015-11-08 17:59:08 +01:00
7f53cbb556 Cleanup: get rid of bmain in foreach ID callback.
messing with depsgraph here is not a good idea I think... and makes things simpler!
2015-11-07 11:31:28 +01:00
8b6928b2fb Merge branch 'master' into id-remap 2015-11-07 10:54:48 +01:00
f0c6c85788 Attempt to fix the 'user_one' mess...
Seems to work (though will need much more tests), but makes code more ugly. :|
2015-11-06 18:00:09 +01:00
0c8b1a8c37 Merge branch 'master' into id-remap 2015-11-06 12:35:45 +01:00
77231eeb2f Merge branch 'master' into asset-engine 2015-11-02 19:27:48 +01:00
9521d71735 Merge branch 'master' into id-remap 2015-11-02 19:22:14 +01:00
3ad17b9405 Merge branch 'master' into asset-engine 2015-10-27 15:05:17 +01:00
6bf915e925 Merge branch 'master' into id-remap 2015-10-27 15:04:51 +01:00
c7f48be47c Merge branch 'master' into asset-engine 2015-10-17 11:47:35 +02:00
2d7bc36462 Merge branch 'missing-libs' into id-remap 2015-10-17 11:39:48 +02:00
177295f856 Merge branch 'master' into missing-libs 2015-10-17 11:34:29 +02:00
06b38491f1 Merge branch 'master' into asset-engine 2015-10-15 17:13:29 +02:00
de71f7ab8a Fix deadlock. Would be really cool if Main spinlock could be re-entrant. :| 2015-10-15 17:03:54 +02:00
6da735e81c Merge branch 'missing-libs' into id-remap 2015-10-15 16:55:43 +02:00
59ff3b5498 Merge branch 'master' into missing-libs 2015-10-15 16:12:57 +02:00
9a9796564a Fix broken ID placeholder code (from recent merges).
Here we need a bit different handling than in missing-lib branch...
2015-10-15 15:33:24 +02:00
a2aafbe656 Merge branch 'master' into asset-engine 2015-10-15 14:29:50 +02:00
d899710952 Merge branch 'missing-libs' into id-remap
Huge load of conflicts, hope it did not break too much things...
Current code build, but crashes easily :|
2015-10-14 21:24:14 +02:00
a6028f8e6b Merge branch 'master' into id-remap 2015-10-14 20:38:27 +02:00
3ffc5c9209 Moar cleanup. 2015-10-14 20:24:05 +02:00
f15741f830 Merge branch 'master' into missing-libs 2015-10-14 17:17:30 +02:00
b89530845a Cleanup. 2015-10-14 16:22:57 +02:00
4dac0afa9c Merge branch 'free-refcount-ids' into missing-libs 2015-10-13 15:48:18 +02:00
168604ecbe Revert to master - those changes are globally valid, but remain incomplete,
and total new code is being done in id-remap anyway, not worth bothering with this for now...
2015-10-13 15:44:58 +02:00
9d5cdf92b2 Merge branch 'master' into free-refcount-ids 2015-10-13 15:41:54 +02:00
67d922f61a Merge branch 'master' into free-refcount-ids 2015-10-13 14:41:33 +02:00
4ed3a36e31 Merge branch 'missing-libs' into id-remap 2015-10-12 21:01:53 +02:00
9442a43853 Merge branch 'free-refcount-ids' into id-remap 2015-10-12 21:00:47 +02:00
13faefaf6a Merge branch 'master' into id-remap 2015-10-12 21:00:02 +02:00
5f2276a553 Merge branch 'free-refcount-ids' into missing-libs 2015-10-12 20:46:28 +02:00
e95ba11ce6 Merge branch 'master' into free-refcount-ids 2015-10-12 20:31:39 +02:00
7d1e429d7c Attempt to fix the NodeTree issue.
So, idea is, since mat/tex/scene/etc. nodetrees are owned by their respective IDs
(those nodetree do not exist in Main, they are systematically freed with their ower IDs, etc.),
we should not treat them as IDs in IDlooper, but rather as mere sub-data, and hence directly
loop over the IDs of those nodetrees.

From quick check it seems to work, but this needs to be confirmed as a valid idea!
2015-10-08 20:35:47 +02:00
cb08f47121 Merge branch 'master' into id-remap 2015-10-08 15:18:08 +02:00
84c6bcac0d Merge branch 'master' into id-remap 2015-10-08 13:15:29 +02:00
74ac2beba2 Again, fix for stupid broken relinking of Objects... 2015-10-08 13:07:06 +02:00
741ceed378 Fix stupid crash... 2015-10-08 12:54:10 +02:00
f0ffe42858 Merge branch 'missing-libs' into id-remap 2015-10-08 12:45:48 +02:00
d8a171f8a7 Merge branch 'lib-link-rework-temp' into id-remap 2015-10-08 12:44:35 +02:00
d4b5b8f1bc Merge branch 'free-refcount-ids' into id-remap 2015-10-08 12:44:28 +02:00
e0c7dcba5b Merge branch 'master' into id-remap 2015-10-08 12:43:41 +02:00
6188d17623 Merge branch 'lib-link-rework-temp' into missing-libs 2015-10-08 12:13:43 +02:00
a219728914 Merge branch 'free-refcount-ids' into missing-libs 2015-10-08 12:13:28 +02:00
92bcc7dd19 Merge branch 'master' into missing-libs 2015-10-08 12:08:29 +02:00
32d9f75660 Merge branch 'master' into lib-link-rework-temp 2015-10-08 12:06:57 +02:00
249aa6c649 Merge branch 'master' into free-refcount-ids 2015-10-08 12:03:03 +02:00
f2293df9a6 Replace 'do_id_user' param of BKE_xxx_free() funcs by generic BKE_libblock_relink().
Heavily simplfies that freeing area, but again a rather risky and likely-to-break change.

At least, NodeTree is known to be a trouble-maker here, due to how it seems to be
'owned' by its mat/tex/sce/etc. Have to dig deeper here, this is still quite unclear
what exactly happens with those, and how to handle them correctly.
2015-10-07 23:15:03 +02:00
1daa502f87 Add BKE_libblock_relink(), which works as _libblock_remap(), but only over one given ID
(instead of whole Main content).

Could replace maybe things like constraint, rigisbody world, etc. '_relink' func,
but for now it's only intended to replace custom 'id releasing' code in _free()
funcs of all IDs!
2015-10-07 21:56:27 +02:00
06c6492d7d Avoid fexplicit conversion to ID * for remap parameters (use void pointers instead).
Also found another missing ID in foreach_id (sound pointer of sequences).
2015-10-07 21:10:50 +02:00
6ed0fcc187 Merge branch 'master' into id-remap 2015-10-07 20:56:54 +02:00
dca705d1c3 Huuuuuuuge commit - replace ugly scene/object/group_unlink by new generic libblock_unlink.
Previous situation was pretty much horrible, a few data types having their own coocking to
unlink, often doing more than only unlinking, often doing the same thing two times or more,
often messing with areas they should not have touched (like editors from withing BKE)...

Now we hope to have something generic, working the same way for all ID types
(we do have to add some specific handling for groups/objects/scene unfortunately,
but this remains reasonable).

Needless to say such a change is calling for troubles - I tried to follow and reproduce
as best as I could previous code, but most likely some areas will become buggy. Do not think
previous code was 100% correct anyway, things like Objects have a really big and complicated
usage of IDs...

Also, foreach_id tool has been enhanced, again for complex types like objects & co, we should
cover much better all possible IDs now (e.g. rigidbody & logic bricks were
totally missing from there).

And there is more to come...
2015-10-07 20:32:59 +02:00
ad8fa268a4 Adding game sensors/controllers/actuators to foreachid libquery.
Those were totally missing, cannot see a good reason for it...
Seems to work OK, but only very quickly tested code.
2015-10-07 10:31:36 +02:00
34c608d010 Make use of new IDWALK_REFCOUNTED flag in our ID remap code.
Think core of the system is getting pretty much OK, now we'll likely have to deal
with tons of specific cases, given how Blender is totally inconsistent when it comes to
handling user counts (e.g. spaceimage...).

Also, still have to make generic ID_unlink and ID_release_datablocks func to replace
redundant code in BKE we have currently.
2015-10-06 14:47:35 +02:00
b8e224507f Merge branch 'missing-libs' into id-remap 2015-10-06 12:25:56 +02:00
f3e2e92f5c Merge branch 'lib-link-rework-temp' into id-remap 2015-10-06 12:25:49 +02:00
64f0cd7b33 Merge branch 'free-refcount-ids' into id-remap 2015-10-06 12:25:38 +02:00
7a7b5bc6d3 Merge branch 'master' into missing-libs 2015-10-06 12:23:50 +02:00
2a3e261554 Merge branch 'master' into lib-link-rework-temp 2015-10-06 12:20:57 +02:00
913938514d Merge branch 'master' into free-refcount-ids 2015-10-06 12:19:29 +02:00
bb6da9cbea ID foreach: add support for modifiers to indicate whether given ID pointer is refcounted or not. 2015-10-05 16:30:33 +02:00
45b83f6fd5 Merge branch 'master' into id-remap 2015-10-05 16:00:33 +02:00
650efcf2d9 Update foreach ID (add a few missing IDs, and add new flag, REFCOUNTED, to indicate when a given ID pointer affects id->us count).
Still missing: at least modifiers (have to change all modifiers callbacks, yuck).
AFAIK constraints never refcount thier IDs so we can keep current code here.
2015-10-05 15:04:39 +02:00
09dcfbbe46 Merge branch 'free-refcount-ids' into id-remap 2015-10-05 13:58:49 +02:00
a33cc08a99 Fix for object freeing. 2015-10-05 13:58:21 +02:00
5327de0f40 Merge branch 'missing-libs' into id-remap 2015-10-05 12:32:19 +02:00
e0adc0b705 Merge branch 'lib-link-rework-temp' into id-remap 2015-10-05 12:32:10 +02:00
0548a1dc6f Merge branch 'free-refcount-ids' into id-remap 2015-10-05 12:32:00 +02:00
3b37921e01 Merge branch 'master' into id-remap 2015-10-05 12:31:52 +02:00
8bb7031dec Minor cleanup. 2015-10-05 12:17:51 +02:00
d7d236ce5c Merge branch 'master' into lib-link-rework-temp 2015-10-05 12:09:19 +02:00
a5d1709771 Merge branch 'master' into missing-libs 2015-10-05 12:05:50 +02:00
794a977bad Merge branch 'master' into free-refcount-ids 2015-10-05 12:05:00 +02:00
44e62635c5 Cleanup , and remove public '_release_datablocks' funcs for now.
On second thaought, will end up doing this differently in id-remap branch,
so for now just make this branch a cleanup, consistency-fixing one.
2015-10-05 10:59:38 +02:00
f00f3496a0 Merge branch 'master' into free-refcount-ids 2015-10-05 09:23:08 +02:00
d5f35c6c4e Merge branch 'free-refcount-ids' into id-remap 2015-10-03 19:22:35 +02:00
e2aab5750b Merge branch 'master' into asset-engine 2015-10-03 19:03:38 +02:00
a4c3d645ed Add note about object release func... 2015-10-01 17:44:02 +02:00
b63872cd5e Free IDs: MovieClip & Mask.
Mask freeing was doing really bad (as in, not consistent with other ID freeing code) things (unlinking, and even not freeing animdata!).
2015-10-01 17:38:04 +02:00
e734bef9d6 Free IDs: Nodes & Groups. 2015-10-01 17:13:16 +02:00
105c6a6c26 Free IDs: Action & Armature. 2015-10-01 16:57:28 +02:00
45f25c6241 Free IDs: Sound & Speaker.
Also cleanup, removed horrible `BKE_sound_delete()`!
2015-10-01 16:47:12 +02:00
1a8727fea0 Free IDs: vfont & text. 2015-10-01 16:34:09 +02:00
ad6495d14b ID free: another round of cleanup & fixes (mostly insconsitancies among IDs code)... 2015-09-30 21:59:24 +02:00
fe3c796c31 Free ID: Brush & World. 2015-09-30 21:34:57 +02:00
099eb3111e ID free: GP & particles... 2015-09-30 21:15:20 +02:00
dd266202b0 ID free: freestylelinestyle & other minor types, some cleanups (mostly use MEM_SAFE_FREE where possible). 2015-09-30 20:52:33 +02:00
1636b12d4d Merge branch 'master' into free-refcount-ids 2015-09-30 20:23:47 +02:00
9e64ad1ad5 Merge branch 'lib-link-rework-temp' into missing-libs 2015-09-30 20:23:14 +02:00
6fb87bc545 Merge branch 'master' into missing-libs 2015-09-30 20:23:07 +02:00
919a887399 Merge branch 'master' into lib-link-rework-temp 2015-09-30 20:22:37 +02:00
921a86b51f Free IDs; lattice & camera. 2015-09-27 15:50:28 +02:00
5b02b2429a Free IDs: images & lamps. 2015-09-27 15:28:57 +02:00
2282a80697 ID freeing: materials and textures. 2015-09-27 15:12:27 +02:00
931570b480 ID free: tackle Scene (and Library, but not much to do there). 2015-09-27 14:43:49 +02:00
063aea9124 Merge branch 'asset-experiments' into asset-engine 2015-09-27 11:30:21 +02:00
b5ee93c1a3 Merge branch 'master' into asset-engine 2015-09-27 11:30:08 +02:00
e6fa18cebf Merge branch 'master' into asset-experiments 2015-09-27 11:29:39 +02:00
0b4439994f Merge branch 'missing-libs' into id-remap 2015-09-27 11:28:20 +02:00
f330da10db Merge branch 'lib-link-rework-temp' into id-remap 2015-09-27 11:28:15 +02:00
53c28a790b Merge branch 'master' into id-remap 2015-09-27 11:28:07 +02:00
ff7b6d36e3 Merge branch 'master' into free-refcount-ids 2015-09-27 11:26:46 +02:00
0b8a47d1b0 Merge branch 'lib-link-rework-temp' into missing-libs 2015-09-27 11:24:50 +02:00
9960295484 Merge branch 'master' into missing-libs 2015-09-27 11:24:42 +02:00
113979e658 Merge branch 'master' into lib-link-rework-temp 2015-09-27 11:19:31 +02:00
c4a3c9d006 Merge branch 'free-refcount-ids' into id-remap 2015-09-24 20:49:58 +02:00
a7e540d7c8 Clean up BKE_object_free() and add BKE_object_release_datablocks().
Similar changed to those done for mesh/curve/mball.

Also, systematically nullify pointers in `_free()` functions, this does not cost
much and can help troubleshooting later.

And tag `BKE_object_unlink()` as an horrible piece of code...
2015-09-24 20:43:35 +02:00
56dae06c56 Cleanup of free/unlink/release of ID: mesh/curve/mball.
Renamed their `_unlink()` functions to `_release_datablocks()`, since they do not
unlink anything (not in the sense `BKE_object_unklink()` does, at least)!

Also, added a `const bool do_id_user` to their `_free()`, for consistency, now
relevant `_release_datablocks()` func only gets called when this option is set.
2015-09-24 19:53:38 +02:00
2cdd19de0b Merge branch 'missing-libs' into id-remap 2015-09-24 13:19:08 +02:00
96092913fb Merge branch 'lib-link-rework-temp' into id-remap 2015-09-24 13:18:59 +02:00
6e88990a4b Merge branch 'master' into id-remap 2015-09-24 13:18:51 +02:00
19f05f274a Merge branch 'lib-link-rework-temp' into missing-libs 2015-09-24 13:15:24 +02:00
4c486c075e Merge branch 'master' into missing-libs 2015-09-24 13:14:48 +02:00
6b49cc1221 Merge branch 'master' into lib-link-rework-temp 2015-09-24 13:13:02 +02:00
4058333c49 Half-working workaround for image refcount in SpaceImage.
Our ID refcount handling is really flacky in many places, this is going to be a serious
issue for this work I'm afraid... :/
2015-09-24 13:10:20 +02:00
d5c69ffeb9 Fix bad handling of non-linkable IDs on reload.
They would be removed from bmain, but never added again nor freed - in this case
we can simply explicitely reload them in fact, non-linkable is only a user-related status...
2015-09-22 21:26:41 +02:00
8da4413ba3 Merge branch 'missing-libs' into id-remap 2015-09-22 10:03:37 +02:00
fc3822988c Merge branch 'lib-link-rework-temp' into id-remap 2015-09-22 10:03:23 +02:00
2665b3ee83 Merge branch 'master' into id-remap 2015-09-22 10:01:20 +02:00
5186e5a0c9 Merge branch 'lib-link-rework-temp' into missing-libs 2015-09-22 10:00:28 +02:00
cf7e75ad53 Merge branch 'master' into missing-libs 2015-09-22 10:00:20 +02:00
1b75f74086 We do not require anymore linking datablocks grouped by types, makes code even simpler. 2015-09-22 09:58:59 +02:00
7a5edf3b45 Merge branch 'master' into lib-link-rework-temp 2015-09-22 09:49:24 +02:00
2c0faad6d5 Minor picky fix... 2015-09-22 09:44:14 +02:00
a508d49e33 Better handling of missing datablocks in reload case.
We need to generate a placeholder for those here... Also, enhances handling
of direct/indirect flags & co.
2015-09-21 21:57:54 +02:00
5bc6608ea5 Merge branch 'missing-libs' into id-remap 2015-09-21 21:37:49 +02:00
06eb69b892 Correct handling of name in placeholder generator (this is a name, not an idname...). 2015-09-21 21:37:05 +02:00
9b9dbb5865 Merge branch 'missing-libs' into id-remap 2015-09-21 21:27:25 +02:00
f0d843cf56 Sort placeholder in its listbase! 2015-09-21 21:25:28 +02:00
47328499cb Merge branch 'missing-libs' into id-remap 2015-09-21 21:09:21 +02:00
62fdf030c6 Change ID placeholder generator to not need an ID as reference (we only need type, name and flag here). 2015-09-21 21:08:25 +02:00
db33f64a89 Fix cases where previously indirect lib becomes direct one after some relocate... 2015-09-21 20:48:31 +02:00
3f9a6f9fea Unlock around core of linking code in reload/relocate context too, for now. 2015-09-21 20:40:46 +02:00
d990888686 Fix for recent merges. 2015-09-21 18:11:26 +02:00
37e21ea855 Merge branch 'missing-libs' into id-remap 2015-09-21 18:04:38 +02:00
1d75fe5b95 Merge branch 'lib-link-rework-temp' into id-remap 2015-09-21 18:04:17 +02:00
5a53d20efc Merge branch 'master' into id-remap 2015-09-21 18:04:08 +02:00
bcf4cc37ff Make placeholder ID creation its own function (we'll need it too in reload context...). 2015-09-21 18:02:56 +02:00
e6a84d5a48 Merge branch 'lib-link-rework-temp' into missing-libs 2015-09-21 17:50:27 +02:00
3391a5ed2f Merge branch 'master' into missing-libs 2015-09-21 17:48:12 +02:00
e91d614e4e Merge branch 'master' into lib-link-rework-temp 2015-09-21 17:46:09 +02:00
ac797f03ef Fix broken multi-lib linking, and remove Main locking around core linking code for now.
We need to append to linklist, or our library indices would be reversed compared to lib list...

As for locking, we need reentrant one here if we want to use it. :(
2015-09-21 17:42:32 +02:00
c18849bb1b Lock bmain around core part of linking code now, this is much safer imho!
This also means we need to ensure no code called from there tries to lock again bmain
(no reentrant spinlock, arg :/).
2015-09-21 16:35:29 +02:00
8cbc05c1cd Add reload lib code, and various fixes (some to be backported to other working branches actually). 2015-09-21 16:15:21 +02:00
99008d4841 Merge branch 'lib-link-rework-temp' into id-remap 2015-09-21 15:11:17 +02:00
d02aa8c4fd Merge branch 'missing-libs' into id-remap 2015-09-21 15:11:10 +02:00
0e62a00bc4 Merge branch 'master' into id-remap 2015-09-21 15:11:00 +02:00
33b7772563 Merge branch 'master' into missing-libs 2015-09-21 15:10:39 +02:00
f7a3ead1c7 Merge branch 'master' into lib-link-rework-temp 2015-09-21 15:10:20 +02:00
c7d931b6d2 Merge branch 'lib-link-rework-temp' into id-remap 2015-09-20 15:46:38 +02:00
2e564ce19c Merge branch 'missing-libs' into id-remap 2015-09-20 15:46:30 +02:00
1d4e36a4c9 Merge branch 'master' into lib-link-rework-temp 2015-09-20 15:41:37 +02:00
bcbbee4f73 Merge branch 'master' into missing-libs 2015-09-20 14:54:33 +02:00
f5b0c53531 Relocate: remove old lib datablocks after relocate, if no ID comes from it anymore. 2015-09-19 20:03:25 +02:00
aaab73d54d Attempt to handle correctly LIB_EXTERN vs. LIB_INDIRECT ID flags.
This is far from simple, and most likely not yet fully working, but we have a base...
2015-09-19 19:56:43 +02:00
38670bc9a9 Some fixes, add basic wrapper code needed for reload feature (not yet implemented). 2015-09-19 18:26:36 +02:00
98efbb312c Merge branch 'lib-link-rework-temp' into id-remap
Also, fix some issues in previous code.
2015-09-18 22:42:05 +02:00
5ac9844083 Some naming cleanup. 2015-09-18 22:27:35 +02:00
856ef065b2 Rework a bit new liblink code, to use our beloved memarena instead of ugly pile of malloc.
Performances are not an issue at all here, but it makes code slightly simpler, avoids
a loop over ghash of libs, avoids some potential mem fragmentation, and will be easier
with lib relocate code too in future...
2015-09-18 22:22:56 +02:00
f011cdcc11 Consider proxy objects as 'linked' ones when it comes to ID remapping.
Reason is, on next fileread, proxy will be assigned with its target's data again...
Note that this may not be true about all its datablocks pointers - but proxy objects
are really brittle in current code anyway, they could use a serious work as well.
2015-09-18 21:31:56 +02:00
32ea612fcc Moar cleanup, some fixes towards sanier handling of remap & indirect data...
Proxy are still not correctly handled here though.
2015-09-18 18:09:13 +02:00
80ddd9afd9 Merge branch 'master' into asset-engine 2015-09-18 16:20:21 +02:00
5d8b0a8bcc Merge branch 'lib-link-rework-temp' into id-remap 2015-09-18 16:12:58 +02:00
33a4a4ed8f Merge branch 'missing-libs' into id-remap 2015-09-18 16:12:40 +02:00
7df45b2a49 Merge branch 'master' into id-remap 2015-09-18 16:12:31 +02:00
1ba2646706 Some cleanup & tweaks. 2015-09-18 16:11:55 +02:00
c7e14ac1f8 Merge branch 'master' into lib-link-rework-temp 2015-09-18 15:47:07 +02:00
87a3de5852 Merge branch 'master' into missing-libs 2015-09-18 15:44:10 +02:00
f9eef9a678 Some cleanup & tweaks. 2015-09-18 15:01:59 +02:00
185c216743 Relocate library: first working code.
Basics seem to be working, proving idea is valid. There is much to do yet though,
handling correctly all possible scenarii (especially those including indirect libs
used by several libraries, or libs used both directly and indirectly, etc.)
is not going to be a piece of cake...
2015-09-18 14:44:08 +02:00
4ee210857a Merge branch 'lib-link-rework-temp' into id-remap 2015-09-17 21:00:55 +02:00
49156ee77b Serious rework (again) of append/link code, to make it more generic.
Making the code in WM area more generic (will be used by relocate libs feature too in future).
And multi-append/link shall no more close & re-open lib files for each and every idcode!

Also, serious cleanup of BLO_append_... API (renamed BLO_link_..., since it links and never appends!),
main real changes there are removing the bContext arg in favor of scene/v3d (a bit more verbose, but does
not requires a valid context anymore to be able to instanciate ob/groups!). And logic behind instanciating
or not has been simplified, previous code was really obscure and sometimes redondant, from quick tests
it still works as expected.

This is temp branch for until 2.76 is over, shall be merged in master asap then.
2015-09-17 20:45:51 +02:00
0df9a4ae3d Merge branch 'master' into id-remap 2015-09-17 19:12:01 +02:00
18cddb58c4 Merge branch 'master' into id-remap 2015-09-17 13:54:36 +02:00
3cce86e4d3 Merge branch 'master' into id-remap 2015-09-16 17:46:32 +02:00
ab9126b7b5 Move most of (currently NoP) relocate code to WM area. 2015-09-16 15:28:19 +02:00
2622e4b208 More work towards relocate operator for libraries (still pretty much empty shell).
Note that this op will have to be moved to WM area in fact, it's way too generic for Outliner only...
and we need to re-use most of append/link operator code!
2015-09-15 22:14:35 +02:00
258725cf49 Merge branch 'master' into id-remap 2015-09-15 14:24:44 +02:00
962751c1a0 Outliner: add a dedicated ID_LI operation handler, and add skeletton for 'relocate' tool... 2015-09-14 22:30:48 +02:00
2f43d7a099 Merge branch 'master' into id-remap 2015-09-14 15:55:15 +02:00
648ce6a080 Some minor fixes and refactor of core id-remap code. Will also allow us to call it when bmain is already locked higher in code. 2015-09-13 15:41:13 +02:00
b428df5408 Merge branch 'missing-libs' into id-remap 2015-09-13 15:19:53 +02:00
6fda73fe0e Merge branch 'master' into missing-libs 2015-09-13 15:19:31 +02:00
68096bb8e8 Merge branch 'missing-libs' into id-remap 2015-09-13 15:19:11 +02:00
8f496e7ebf Add remaining missing id_remap editors' callbacks.
This is far from being done though... :/
2015-09-12 17:15:06 +02:00
8ae125e946 Merge branch 'master' into id-remap 2015-09-12 15:40:35 +02:00
5c029b1628 Add support id-remap for 3Dview bgpic and Image space.
SpaceImage seems to have a weird handling of image ID user count :/
2015-09-11 17:22:40 +02:00
15f08697e7 Rework our 'space id remapping' code by adding a new 'id_remap' callback to SpaceType, and add one for View3D.
Think it's much cleaner this way.

View3D new id_remap only handles camera/ob_center pointers for now, images will need some more work I think...
2015-09-11 16:27:42 +02:00
efb2d755c1 Merge branch 'master' into id-remap 2015-09-11 15:53:37 +02:00
07136e6176 Merge branch 'master' into id-remap 2015-09-10 22:47:25 +02:00
0abb0ee156 Merge branch 'master' into missing-libs 2015-09-10 22:39:39 +02:00
1fd6979bdb Some minor UI updates... 2015-09-10 14:35:49 +02:00
13d9d33158 Merge branch 'asset-experiments' into asset-engine 2015-09-10 14:14:25 +02:00
93fb699e20 Merge branch 'master' into asset-experiments 2015-09-10 14:13:57 +02:00
6d2519250a Add some (mostly commented) debug prints... 2015-09-10 14:13:18 +02:00
06f937c9b1 Fix nasty hidden RNA/bool related bug.
**NEVER** pass a boolean as address (pointer) to a RNA property function - it will read (or write) it as an integer!
2015-09-10 14:08:36 +02:00
8094de89ce Fix filelist_file_create_entry() adding the generated entry twice to the cached list in AE case. 2015-09-10 13:01:37 +02:00
b4861a9ec1 Merge branch 'asset-experiments' into asset-engine 2015-09-09 21:45:37 +02:00
283da2a596 Merge branch 'master' into asset-experiments 2015-09-09 21:38:07 +02:00
2d861d68a7 Merge branch 'asset-experiments' into asset-engine 2015-09-09 17:25:22 +02:00
ec99859c44 Merge branch 'master' into asset-experiments 2015-09-09 17:20:14 +02:00
a77cd3e953 Fix 3DView and others not updating after ID remapping.
Notifiers usage could really use a good cleanup imho...
2015-09-03 17:56:03 +02:00
3f22fbf32b Merge branch 'master' into id-remap 2015-09-03 16:16:50 +02:00
65a108cf35 Merge branch 'master' into missing-libs 2015-09-03 16:16:26 +02:00
62ff31971a Merge branch 'master' into id-remap 2015-08-30 12:06:02 +02:00
75db37e80f Merge branch 'master' into missing-libs 2015-08-30 11:55:38 +02:00
baa1513603 Merge branch 'asset-experiments' into asset-engine 2015-08-30 11:44:35 +02:00
2420f8a32e Merge branch 'master' into asset-experiments 2015-08-30 11:40:49 +02:00
e8af25479d Merge branch 'asset-experiments' into asset-engine 2015-08-30 11:29:03 +02:00
aa4896317d Merge branch 'master' into id-remap 2015-08-23 18:45:13 +02:00
031aab8d0c Some minor tweaks & cleanup. 2015-08-23 16:34:19 +02:00
317474e231 Merge branch 'master' into id-remap 2015-08-23 15:08:17 +02:00
b9110048f9 Merge branch 'master' into id-remap 2015-08-22 15:38:58 +02:00
6711e9d15f Merge branch 'master' into missing-libs 2015-08-22 15:11:32 +02:00
173ffb140a Minor tweak: adjust icon size to thumbnail size.
Avoids too big 'data type' icon in tiny display...
2015-08-19 22:38:27 +02:00
211ef292ba Merge branch 'master' into asset-experiments 2015-08-19 21:54:20 +02:00
f5140d4e82 Merge branch 'asset-experiments' into asset-engine 2015-08-18 14:51:52 +02:00
03829f7c48 Merge branch 'master' into asset-experiments 2015-08-18 14:35:56 +02:00
9fc2d1e35b Merge branch 'master' into asset-experiments 2015-08-18 13:24:09 +02:00
f5f06db832 Merge branch 'master' into asset-experiments 2015-08-18 12:43:35 +02:00
3a21279bc8 Merge branch 'master' into asset-experiments 2015-08-18 12:24:06 +02:00
0baa1469d0 Merge branch 'master' into asset-experiments 2015-08-11 12:01:12 +02:00
dc659c05d4 Merge branch 'master' into asset-experiments 2015-08-10 18:04:13 +02:00
47e73e6b72 Merge branch 'master' into asset-experiments 2015-08-10 17:47:00 +02:00
67282959af Fix bug in preview generator. 2015-08-10 17:21:11 +02:00
979d22b361 Some cleanup re master... 2015-08-10 15:52:18 +02:00
53312d1fac Merge branch 'master' into asset-experiments 2015-08-10 15:44:20 +02:00
a2a3e40cf1 Merge branch 'master' into asset-experiments 2015-08-10 15:10:16 +02:00
2aab8c7a95 Some ultimate cleanups. 2015-08-10 14:36:39 +02:00
14786d653a Merge branch 'master' into asset-experiments 2015-08-10 14:18:23 +02:00
386efee483 Minor tweak - adapt a bit number of preview workers to number of available physical threads! 2015-08-09 18:08:33 +02:00
9ebdab0e17 Merge branch 'master' into asset-experiments 2015-08-09 16:09:23 +02:00
6b34b4f066 Merge branch 'master' into id-remap 2015-08-02 18:02:16 +02:00
d2bdc66143 Merge branch 'master' into missing-libs 2015-08-02 17:50:29 +02:00
231237f1b5 Merge branch 'asset-experiments' into asset-engine 2015-08-02 17:17:57 +02:00
37e679772e Merge branch 'master' into asset-experiments 2015-08-02 17:13:42 +02:00
574a7da03e Fix several issues, add a quick and dirty new action in Outliner to remap IDs.
We have to take care of Object->data aside from main foreach loop, since we can
only replace that pointer if object is **not** in Edit mode!

Also, added a "Remap" action to ID context menu of outliner. This is **very far**
from nice and pretty code/feature, but it allows to quickly test the code.

Only did very quick tests with meshes so far...
2015-07-21 22:42:06 +02:00
1ebdfb4d45 Fix some dummy mistake, add simple RNA callback to 'remap' IDs.
Also, added Object.data to BKE_library_foreach_ID_link(), wonder if there was a good reason
for this to not be here???
2015-07-21 22:42:06 +02:00
df50b8cabf Add main 'ID remap' function.
Theoretical code, compiles, but needs to be tested!
2015-07-21 22:42:06 +02:00
f2d6e85212 ID remapping: first step - modify some editors callback to not only support ID freeing, but also ID remapping.
This seems to be OK, but will obviously need much more testing - and is useless as-is, we need
the big ID remapping code itself still.

Also, Nodetrees' remapping of Scene IDs is still TODO, not sure yet how to do this.
2015-07-21 22:42:06 +02:00
313fabd310 Merge branch 'master' into missing-libs 2015-07-21 08:07:42 +02:00
93563c5522 Merge branch 'asset-experiments' into asset-engine 2015-07-21 08:01:47 +02:00
c1589b71c5 Merge branch 'master' into asset-experiments 2015-07-21 07:55:51 +02:00
aee44d5070 Merge branch 'master' into missing-libs 2015-07-17 21:13:03 +02:00
09787f03b7 Merge branch 'master' into missing-libs 2015-07-16 19:53:31 +02:00
4e2f5a6461 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/file_ops.c
2015-07-16 19:46:35 +02:00
f37adc4312 Merge branch 'master' into asset-experiments 2015-07-16 19:45:22 +02:00
2bfd60e54f Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_ops.c
2015-07-16 16:53:55 +02:00
610a04ab5d Fix rebase mess :/ 2015-07-15 20:38:51 +02:00
222a199f99 Add outliner's visualization for broken libs, and also tag lib ID itself as missing. 2015-07-15 20:36:22 +02:00
82d166df72 Add remaning 'init' callbacks for needed ID types.
Note all this remains a bit theoretical, some cases (ID types) are a bit delicate to handle here.7
Time and tests will say if it's OK as is.
2015-07-15 20:36:22 +02:00
83dd16a6d6 Add some checks in BKE_xxx_init() that data is really NULLified.
Needed, since trying to (re)init data already set could lead to many issues,
and handling this is not in the scope of this function.

Note that definition of BLI_memcmp_null stuff is rather bad currently, no good idea where to place this. :|
2015-07-15 20:36:22 +02:00
4181f35014 Handling missing libs: changed idea, now adding 'real' empty data.
Just having 'NULL' data as placeholder is not really possible, too much places
to check against that.

WIP commit, still much to be done!

See T43351 for details.

Differential Revision: https://developer.blender.org/D1394
2015-07-15 20:36:22 +02:00
266f0d3e77 Very first step to handle missing libs/datablocks when reading a file.
Idea is, instead of ignoring completely missing linked datablocks, to
create void placeholders for them.

That way, you can work on your file, save it, and find again your missing data once
lib becomes available again.

Plans are also to be able to locate missing libs and reload them at runtime.

To support all that, we must be able to make Blender survive those missing data
(i.e. empty datablocks) all over the place. This commit contains some early work
in that direction, but this will need much much more work!
2015-07-15 20:36:21 +02:00
9a2ae72156 Icons: Add new 'library_data_broken' one. 2015-07-15 20:36:21 +02:00
37a6a92f76 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/file_ops.c
2015-07-11 23:00:56 +02:00
5a16f29700 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenlib/intern/BLI_filelist.c
	source/blender/editors/space_file/file_draw.c
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/filelist.c
2015-07-11 22:51:30 +02:00
80acaa3009 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
2015-07-04 13:16:30 +02:00
05017bc9a3 Merge branch 'master' into asset-experiments 2015-07-04 12:59:37 +02:00
047525019a Expose fewest more generic ID filtering options.
Full precise filtering remains possible in new 'Advanced filter' panel.
2015-07-04 12:56:09 +02:00
6cb2f6e870 UI-fix (bad 'recusion level' value in RNA enum, 1 is only valid in library listing case). 2015-07-04 01:48:43 +02:00
9f176db5ea Merge branch 'master' into asset-experiments 2015-07-04 01:42:37 +02:00
c2049e740e Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenlib/BLI_ghash.h
2015-07-02 21:22:07 +02:00
665ac71aee Add API to IMB_thumb to enable thread safety.
Indeed, though rather unlucky, we may end up handling same source file from
different preview threads, which could lead to conflicts and bugs.

So idea is to add a simple way of locking a given source file path, since
thumb handling of different paths shall never conflict.

Note that this adds some 'generic' stuff to GHash and Threads area, that are to
be committed separately of course.
2015-07-02 13:31:38 +02:00
dd15ef2528 Previews: do not keep preview task and timer running continuously in 'Preview' mode.
The task was not so annoying (workers are just sleeping anyway), but having the timer
always checking for updates was not so nice. This remains quite minor optimization probably...

So now, we do not start anymore preview task when enabling previews. This is deferred
to the moment we really need it (i.e. when we cache block of entries currently visible).
Preview timer is started at the same time.

Further more, when preview task has been inactive for about one second (i.e. all
queued previews have been handled, and no new one have been queued), we free it
(switching to some kind of 'standby' mode).

This also allows to avoid stoping/restarting preview tasks on each redraw when user is scrolling.
2015-07-02 12:01:09 +02:00
effabf0ce7 Remove queing TODO previews when starting preview task, this is already handled
(in a better way) by filelist_file_cache_block().
2015-07-01 17:43:49 +02:00
a1c8d693a8 Fix windows bug with scons builds.
Classical bool vs char value mismatch... Here it was leading to a constant re-filtering
of the list, which invalidates cached previews.

Strange thing is, it would look as if Windows CMake builds are using 'real' bool,
while scons ones are using fake char-based one?
2015-07-01 16:40:07 +02:00
2cac2ec784 Merge branch 'master' into asset-experiments 2015-07-01 16:28:57 +02:00
23c81d8990 Merge branch 'master' into asset-experiments 2015-06-30 19:17:34 +02:00
633e3d2545 Merge branch 'master' into asset-experiments 2015-06-29 14:55:38 +02:00
cd980e85d7 Merge branch 'master' into asset-experiments 2015-06-28 20:22:14 +02:00
857d5f3580 Be much smarter with file size display... 2015-06-28 00:16:14 +02:00
b5a65fd7be Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenlib/intern/BLI_filelist.c
2015-06-27 23:42:06 +02:00
9379b7f968 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
	source/blender/editors/space_file/filelist.c
2015-06-27 23:26:32 +02:00
fb43c07681 Merge branch 'master' into asset-experiments 2015-06-27 23:15:58 +02:00
6c8e34e59b Filebrowser internal listing & UUIDs: simpler & safer UUIDs generation.
Instead of computing MD5sum of paths, just use incremental UUIDs!
There meaning and lifetime for internal listing is very limited anyway,
they shall only be unique for a given listing.

Note about using atomic op here: did it because it's nice use case,
not sure it's worth adding atomic stuff to /editors area though?
2015-06-19 14:31:00 +02:00
011061ab5e Remove copying of preview data for objects and groups datablocks.
Those get temporarily duplicated by renderers (Cycles, Freestyle),
not nice to have useless memory usage here.
2015-06-19 13:04:04 +02:00
7b84fa5927 Various minor cleanup & fixes from review. 2015-06-19 13:01:39 +02:00
6f236221c6 Merge branch 'master' into asset-experiments 2015-06-19 12:33:18 +02:00
c3492716ee Merge branch 'master' into asset-experiments 2015-06-19 11:44:23 +02:00
ae569a4e76 Merge branch 'master' into asset-experiments 2015-06-18 11:53:14 +02:00
924ff970cc Merge branch 'asset-experiments' into asset-engine 2015-06-17 14:28:53 +02:00
d6b5f82bae Merge branch 'master' into asset-experiments 2015-06-17 14:28:24 +02:00
1e1cc1409b Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filelist.h
	source/blender/editors/space_file/space_file.c
2015-06-16 18:11:21 +02:00
9a7d5130ec Cleanup: get rid of ugly bool in structs, replaced by bitflags. 2015-06-16 17:32:46 +02:00
649b09debb Make selection & co really working even during listing process.
This commit replaces `filelist_numfiles()` by `filelist_files_ensure()`. The later
also returns number of visible files (i.e. filtered ones), but also ensures filelist
is filetered and sorted.

Otherwise, during listing process, operators could be executed between an update of the listing job,
and the refresh from the file space - i.e. at a time filelist is virtually empty (from filebrowser PoV).

Also, got rid of 'need_refresh', this ended up being unused...
2015-06-16 16:59:29 +02:00
f616871e62 Selection/UUIDs handling enhancements:
* Do not systematically clear selection_state's uuids GHash when updating filelist
  during listing process - uuids used here should remain valid.
  Allows to not lose selections during listing background job!
* Use new BLI_ghash_lookup_p to handle selection state setting, symbolic optimization but...
2015-06-16 16:19:06 +02:00
3d9da00815 Make imbuf_thumb for .blend a bit less stupid & noisy regarding missing previews.
A file which does not have *any* preview is perfectly valid, error is only when there
are some previews, but not the same number as actual datablocks...
2015-06-16 15:45:52 +02:00
bfb6155466 Fix some fileops operators that could try to get out-of-bound indices.
Also, some minor reordering in full-block-recaching, currently could not create
issues but better be safe & logic here.
2015-06-16 15:40:58 +02:00
edb87ecd75 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_ops.c
2015-06-16 14:24:05 +02:00
bc43854651 Merge branch 'asset-experiments' into asset-engine 2015-06-12 10:43:14 +02:00
5fbd8997c2 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/filelist.c
2015-06-12 10:42:44 +02:00
27ed6ef95c Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-06-11 20:17:30 +02:00
c3866a0fe1 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_ops.c
2015-06-11 20:07:29 +02:00
04f7493588 Fix/adapt new 'keyboard select' code to changes from branch. 2015-06-11 19:58:23 +02:00
a4965036a7 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_draw.c
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/space_file.c

NOTE: Tagged some parts in new code to be fixed, rather do that in a separate commit.
      This means this commit is broken and won't compile.
2015-06-11 18:16:43 +02:00
22abc19145 Merge branch 'asset-experiments' into asset-engine 2015-06-11 16:35:53 +02:00
b5635fb70d Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/idcode.c
2015-06-11 16:31:30 +02:00
7793df2491 Merge branch 'asset-experiments' into asset-engine 2015-06-03 17:11:27 +02:00
edf50e3a5d Fix error when batch-rendering preview of scene with no world. 2015-06-03 17:07:48 +02:00
7cc52cc8dd Fix bad ID preview clearing in RNA API.
Logic here was piece of crap... sigh.
2015-06-03 16:55:35 +02:00
44adb244bc Merge branch 'master' into asset-experiments 2015-06-03 16:48:17 +02:00
e1a3c1d4e7 Arg, missed those in previous 'review' commit. 2015-06-03 16:29:03 +02:00
aab3ec8624 Merge branch 'asset-experiments' into asset-engine 2015-06-03 15:49:33 +02:00
89db98c0be Address new review points. 2015-06-03 15:47:43 +02:00
221142275c Merge branch 'master' into asset-experiments 2015-06-03 14:15:53 +02:00
c436a00372 Fix broken behavior e.g. for 'save as' operator...
We need to set filename/filepath from sfile->params in case operator does not support multi-files!
2015-06-02 15:34:10 +02:00
f2f4c4c93d WIP more work towards inclusion of asset engine/asset uuids in linking process. 2015-06-02 14:04:06 +02:00
d4e5cad70e Merge branch 'asset-experiments' into asset-engine 2015-06-02 10:20:13 +02:00
0f285b566d Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/imbuf/intern/thumbs.c
2015-06-02 10:19:50 +02:00
b57abacd8c Merge branch 'asset-experiments' into asset-engine 2015-05-29 10:56:19 +02:00
7f59c846a7 Add comment about why we need to store fileselection state outside of filelist items now. 2015-05-29 10:38:55 +02:00
21e498acdd Tweaks and fixes in py part (preview handling). 2015-05-29 10:32:31 +02:00
5301ea7b96 Address most points from first reviewing pass.
Nothing new here, just some cleanup and refactor.
2015-05-29 10:12:46 +02:00
2a5d07773e Merge branch 'master' into asset-experiments 2015-05-29 09:30:08 +02:00
ab049a335d More WIP towards integrating AE/assets_uuids in append/link process... 2015-05-28 19:51:25 +02:00
74aeb8ef11 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2015-05-28 14:46:10 +02:00
99a3e09088 Refactor code in multi-append/link operator.
Avoid writing a big chunck of code doing nearly the same thing twice...
2015-05-28 14:42:12 +02:00
b87e275429 WIP more AE/uuid in append/link operator. 2015-05-28 10:37:01 +02:00
a4c5aa208d Merge branch 'asset-experiments' into asset-engine 2015-05-27 15:47:19 +02:00
bae3805edb Merge branch 'master' into asset-experiments 2015-05-27 15:44:38 +02:00
9ab309901d Add asset engine version to uuids list struct. 2015-05-26 21:18:28 +02:00
bd0e78bb23 Add needed asset-related data to Library and ID structs. 2015-05-26 20:47:43 +02:00
f34c098f0c Add 'bl_version' to asset engine type, needed to support asset engine in file read/write! 2015-05-26 17:21:10 +02:00
23beab242a Fix asset engine resetting on every resize!
Only reset AE type to default in `file_init()` if current type is invalid!

Also, better handling of getting default AE type now.
2015-05-26 17:02:45 +02:00
99cf8b2188 Merge branch 'asset-experiments' into asset-engine 2015-05-26 16:32:36 +02:00
180958cb2c Merge branch 'master' into asset-experiments 2015-05-26 15:50:19 +02:00
f6dc0573f8 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
	source/blender/makesrna/intern/rna_space.c
2015-05-25 15:58:24 +02:00
ac516fddb2 Merge branch 'master' into asset-experiments 2015-05-25 15:38:14 +02:00
a5c580c9e4 Some tweaking to UI, try to make filebrowser header a bit more compact... 2015-05-21 15:20:53 +02:00
b5db0c903c Merge branch 'asset-experiments' into asset-engine 2015-05-21 14:37:02 +02:00
59a8cbc49b Merge branch 'master' into asset-experiments 2015-05-21 14:36:41 +02:00
0a52a358fa Better handling of tags in Amber.
Also adds some 'state' flags to AssetEngine, so that custom AE's setting changes
can be notified to filebrowser, as default internal ones are.

For now, we only have 'dirty filtering' and 'dirty sorting'.
2015-05-21 14:15:46 +02:00
223e098ca1 Some minor cleanup in Amber code. 2015-05-20 10:28:46 +02:00
7f7f296475 Merge branch 'asset-experiments' into asset-engine 2015-05-20 09:39:06 +02:00
a9efb6a5ae Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-05-20 09:19:23 +02:00
b5c72b15ed Merge branch 'master' into asset-experiments 2015-05-13 17:14:46 +02:00
85499bb5e8 Fix crash in append/link on windows (sigh). 2015-05-13 17:06:44 +02:00
952ef0fedf Fix newly created dir not going into rename state anymore.
Due to async dir listing...
2015-05-13 14:07:49 +02:00
044398c786 Merge branch 'master' into asset-experiments 2015-05-13 13:58:39 +02:00
b0f1a9e27f Merge branch 'master' into asset-experiments 2015-05-13 12:52:11 +02:00
3bef09f672 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/blenkernel/CMakeLists.txt
2015-05-12 19:39:44 +02:00
9706ec852d Restore drag'n'drop from filebrowser.
We need to store non-static data here, so had to tweak drag and drop button code...
2015-05-12 19:21:13 +02:00
ade786b30c Some cleanup and reducing diff from master. 2015-05-12 17:00:12 +02:00
63d52d7bb1 Merge branch 'master' into asset-experiments 2015-05-12 15:33:32 +02:00
113c17ea76 Merge branch 'asset-experiments' into asset-engine 2015-05-11 17:25:43 +02:00
9346891c3c Merge branch 'master' into asset-experiments 2015-05-11 17:24:24 +02:00
acd076a9f3 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/BKE_icons.h
	source/blender/blenkernel/intern/icons.c
	source/blender/editors/include/UI_interface_icons.h
	source/blender/editors/interface/interface_icons.c
	source/blender/makesrna/intern/rna_ID.c
2015-05-11 17:09:53 +02:00
51a3024f33 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-05-11 09:46:17 +02:00
bf583c8c95 Merge branch 'master' into asset-experiments 2015-05-11 09:36:20 +02:00
f2ceb38ce8 Add variable sliding window for cached filebrowser items.
With big screens and tiny drawing, we can show much more than 1k items at once...
Also allows to reduce number of cached items in case we show few things big!
2015-05-10 17:15:59 +02:00
47a7246a5c Merge branch 'master' into asset-experiments 2015-05-10 15:26:26 +02:00
dd2034623c Merge branch 'asset-experiments' into asset-engine 2015-05-09 16:43:22 +02:00
b1ce5e6772 Fix bad behavior in case of 'refresh' while still listing.
Mismatch in 'owner' of job, not giving right one to stoping helper, sigh.

Note that this was also affecting any 'interrupting' task (like changing level of flat listing...).
2015-05-09 16:42:13 +02:00
c77f3b57bc Fix flickering of previews during listing process.
We cannot keep 'stable' list of items during listing process (each time new
entries are added, we have to filter and sort the whole lot again, which
means rebuilding 'draw' data from scratch - previews included).

Just wait until our filelist is complete to generate/use previews.
2015-05-09 16:06:30 +02:00
abed546672 Fix crash due to some missing final jop update in some rare cases. 2015-05-09 16:00:07 +02:00
71a061bc1a Merge branch 'master' into asset-experiments 2015-05-09 14:29:46 +02:00
6cae0ccded Merge branch 'asset-experiments' into asset-engine 2015-05-07 19:31:48 +02:00
4767de15b8 Fix win build... 2015-05-07 19:30:56 +02:00
97798c6125 Merge branch 'master' into asset-experiments 2015-05-07 19:17:45 +02:00
9d9ee6699a Get rid of nice 'static' in array args of functions, MSVC does not like them. :( 2015-05-06 19:59:02 +02:00
b943f6fd28 Merge branch 'master' into asset-experiments 2015-05-06 18:13:20 +02:00
3745062bf9 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
2015-05-05 17:23:32 +02:00
0e5789c43c Some cleanup and addressing TODOs in ID preview generation module. 2015-05-05 17:18:49 +02:00
ef484c7a59 Expose preview/icon render sizes in bpy.app 2015-05-05 17:18:30 +02:00
d0799901f7 Merge branch 'master' into asset-experiments 2015-05-05 14:26:58 +02:00
fc5adb63a0 Merge branch 'master' into asset-experiments 2015-05-04 21:14:47 +02:00
85406569e1 FileBrowser: enhance handling of most compact drawing by also reducing size of static strings like file size. 2015-05-04 17:00:45 +02:00
54e753f85e Fix size of files not showing in default Filebrowser mode. 2015-05-04 16:23:54 +02:00
0bdf85afde FileBrowser: make (fixed) column size user-configurable (re[ab]using new thumbnail size). 2015-05-04 16:15:12 +02:00
1ca9c549f9 Merge branch 'asset-experiments' into asset-engine 2015-05-04 15:55:56 +02:00
056f11ec8d Merge branch 'master' into asset-engine 2015-05-04 15:55:45 +02:00
bc8ad4c739 Cleanup/reduce needless diff with master. 2015-05-04 15:54:48 +02:00
870c2040bc Merge branch 'master' into asset-experiments 2015-05-04 14:59:13 +02:00
2f477065a0 Merge branch 'asset-experiments' into asset-engine 2015-05-02 17:05:17 +02:00
cc02a0a7e5 Merge branch 'master' into asset-experiments 2015-05-02 17:03:45 +02:00
e0c275e239 Merge branch 'master' into asset-engine 2015-05-02 17:03:22 +02:00
92123e578a Fix T44586: Viet language problem for Blender Interface
We were missing many of the complex diacritics combinations in latin extended additional code block...

Alawyas a pleasure to edit this font... :|
2015-05-02 16:49:12 +02:00
56b3d8d273 Fix stupid crash. 2015-05-02 15:25:35 +02:00
40dd7cbe21 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
2015-05-02 15:10:31 +02:00
756bb6b404 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/filelist.c
	source/blender/makesrna/intern/rna_space.c
2015-05-02 15:01:34 +02:00
839cc7b2a1 Merge branch 'asset-experiments' into asset-engine 2015-04-27 18:25:48 +02:00
59d5f5c253 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/object.c
	source/blender/windowmanager/intern/wm_operators.c
2015-04-27 18:21:59 +02:00
c31c62c7ec Merge branch 'asset-experiments' into asset-engine 2015-04-18 12:20:18 +02:00
863f19431d Merge branch 'master' into asset-experiments 2015-04-18 12:05:23 +02:00
45164ac6e3 WIP work to pass asset data to operator.
Asset engine ID, asset/variant/revision uuids, root path...
First goal is link code!
2015-04-16 18:28:59 +02:00
eca9cb2adb Merge branch 'asset-experiments' into asset-engine 2015-04-16 14:55:58 +02:00
31e89b1fcf Merge branch 'master' into asset-experiments 2015-04-16 14:49:04 +02:00
ba20e06227 Merge branch 'asset-experiments' into asset-engine 2015-04-16 10:46:37 +02:00
b3c8192715 Merge branch 'master' into asset-experiments 2015-04-16 10:45:24 +02:00
00e451015b Merge branch 'asset-experiments' into asset-engine 2015-04-15 19:21:11 +02:00
399b2927df Merge branch 'master' into asset-experiments 2015-04-15 19:18:57 +02:00
a9d5eddc52 Rename RNA's 'IDPreview' to 'Preview' - there is no reason to keep that for IDs only,
we likely will want to use it in other cases...
2015-04-15 19:17:34 +02:00
eb9784dea2 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-15 17:48:26 +02:00
b239c249ac FileBrowser: only generate size/date/time strings when needed!
Also, cleanup remaining cruft from modes/owner stuff.
2015-04-15 17:43:05 +02:00
ab9f937bd8 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
	source/blender/makesrna/intern/rna_space.c
2015-04-15 16:45:35 +02:00
8124e69a91 Backport some changes from asset-engine branch:
* uuids as int[4] instead of char[16];
* move use_library_browsing to params instead of spacefile.
2015-04-15 16:40:52 +02:00
5ffbf49439 AssetEngine: Various fixes and new features:
* Let asset engine draw most of header bar itself!
* Pass whole FileSelectParams to AE's sort_filter function.
* Move 'use_library_browsing' to params level (this way AE's sort_filter can be ware of it too).

Amber:
* Now supports real basic sorting/filtering modes
* Also basic support of tags (needs a way to refresh though, currently).
2015-04-15 16:26:33 +02:00
fde14db489 Switch definitively to int32[4] for uuid's, mixing mixing it with char[16] is confusing at least.
This is only on human-level anyway... And endianess should not be an issue
either, hopefully, that way!
2015-04-15 12:50:04 +02:00
c4a1d5143e Merge branch 'asset-experiments' into asset-engine 2015-04-15 12:23:00 +02:00
163ad29b58 Merge branch 'master' into asset-experiments 2015-04-15 12:20:32 +02:00
52db10355b WIP better/fixed support of uuid's in asset engines.
Still not working as expected it seems... Not having a real bytes type in RNA is a real PITA. :/
2015-04-14 22:49:28 +02:00
68bab334e0 More fixes...
Amber engine seems to be running nice again in new system, pfew!
2015-04-14 16:58:38 +02:00
18f18ec8b3 Fix issue in final selection in some cases. 2015-04-14 16:23:26 +02:00
80c0f3da22 Merge branch 'asset-experiments' into asset-engine 2015-04-14 16:10:00 +02:00
63318a2a4c Merge branch 'master' into asset-experiments 2015-04-14 16:07:04 +02:00
476a1b9eff Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-13 22:13:16 +02:00
2842949e13 Add uuids ghash to filelist's cache. 2015-04-13 21:54:37 +02:00
b3ad658b45 Merge branch 'master' into asset-experiments 2015-04-13 21:19:53 +02:00
449e1d8074 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c

... And fixes for code specific to that branch.
2015-04-13 20:22:27 +02:00
11ef8d9797 Small refactor (will allow better factorization with AE listing code). 2015-04-13 17:40:32 +02:00
2feeea8328 Caching of FileDirEntry: simplify things, fix some more mem bugs. 2015-04-13 17:36:11 +02:00
026f967dff Various fixes with asset engine and new code...
Still not working completely, and need small rework in asset-experiments first.
2015-04-13 17:27:06 +02:00
6adc839e40 Fix stupid freeing issues. 2015-04-13 16:20:24 +02:00
e39242c4ce Merge branch 'asset-experiments' into asset-engine 2015-04-13 15:55:30 +02:00
0e3a9530da Merge branch 'master' into asset-experiments 2015-04-13 15:53:37 +02:00
23bba70da5 Merge branch 'asset-experiments' into asset-engine 2015-04-10 23:43:20 +02:00
bf19bf0110 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenlib/intern/BLI_filelist.c
	source/blender/imbuf/IMB_thumbs.h
	source/blender/imbuf/intern/thumbs.c
2015-04-10 23:42:43 +02:00
eb8b2413de Merge branch 'master' into asset-experiments 2015-04-10 14:27:18 +02:00
336c7f9ba5 AssetEngine WIP support of new filelisting behavior in filebrowser...
Nearly working, still have some mem issues to fix.
2015-04-09 20:35:36 +02:00
96f060d32d Merge branch 'asset-experiments' into asset-engine 2015-04-09 12:05:47 +02:00
126e1aa60a Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenlib/intern/BLI_filelist.c
	source/blender/editors/space_file/filelist.c
2015-04-09 12:05:09 +02:00
bfb977534f Merge branch 'asset-experiments' into asset-engine 2015-04-08 14:38:44 +02:00
57786fda42 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-08 14:38:18 +02:00
9763ba8f72 Merge branch 'asset-experiments' into asset-engine 2015-04-08 14:21:32 +02:00
990598e60c Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_draw.c
	source/blender/editors/space_file/filelist.c
	source/blender/imbuf/IMB_thumbs.h
	source/blender/imbuf/intern/thumbs.c
	source/blender/imbuf/intern/thumbs_blend.c
2015-04-08 14:21:00 +02:00
485a9abf29 Merge branch 'asset-experiments' into asset-engine 2015-04-07 15:40:34 +02:00
d9c690b559 Misc cleanup, fix previews memleak. 2015-04-07 15:38:06 +02:00
a2b4d96b65 Merge branch 'asset-experiments' into asset-engine 2015-04-07 15:07:47 +02:00
b3de44cc01 Cleanup: get rid of preview handling in lib listing code. 2015-04-07 15:07:09 +02:00
6e8cc0bc05 Move handling of ID blocks previews in thumbnail handler.
this is mandatory, since we do not keep previews for all listed items anymore
(with 10k datablocks would start to take too much mem). So we now generate (read)
them from thumbnailing threaded task as any other image, has several advantages:
* Quicker initial listing of data from .blend files.
* Since thumbnails are cached on disk, re-generating them is rather quick.
* General consistency!

Note thumbnail generation of datablocks could (should!) be enhanced, right now
it reads all previews for a given datatype in a file each time it has to generate
a single datablock thumbnail, we should generate all of those previews in a single
run. But this means handling cache dirty things (TBH_FAIL, outdating, etc.) on another
level so need some more work.

Also, still some memleaks issues with thumbnails, have to track those dose!
2015-04-07 15:00:40 +02:00
b6ef6da231 Merge branch 'master' into asset-experiments 2015-04-07 09:30:50 +02:00
fc543da843 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-06 20:27:04 +02:00
eaf71f7f17 Some minor tweaks for asset-engine branch... 2015-04-06 20:23:22 +02:00
bdf2e64255 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-06 20:15:29 +02:00
5cee945744 Merge branch 'master' into asset-experiments 2015-04-06 19:51:34 +02:00
c539aaf19d FileBrowser: internal listing: use own, much lighter struct to store whole list.
Since with internal listing we have no choice but to list everything, store
those data in the smallest possible struct - note we do not even store preview
here, these are only handled in full FileDirEntry cache (re-loading them from
cached thumbnails is really quick anyway).

Still not complete, have to re-do ID previews now, among other things...
And some memleaks again with previews, ugh.
2015-04-06 19:51:07 +02:00
979d16e52f BLI filelist: get rid of strings for size/time/mode/etc.
Those were eating quite a bit of bites, not neglectable with thousands of entries...
Also, useless to print those info most of the time, they are not used!

So now, we only store 'raw' stat data, and expose funcs to convert them to readable
strings on demand.
2015-04-05 15:47:59 +02:00
718e84201a Merge branch 'master' into asset-experiments 2015-04-05 11:49:35 +02:00
5e593dd851 Resurrect filelist_selection_get()...
Still not working though.
2015-04-04 15:14:03 +02:00
75ef507e70 Merge branch 'asset-experiments' into asset-engine 2015-04-04 15:07:21 +02:00
51bb1cef39 FileBrowser: add dummy accessor to entries from their uuid.
Needed for assets branch, to be rework seriously later of course.
2015-04-04 15:06:23 +02:00
6704abce7f Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-04 13:19:25 +02:00
868a4288ab FileBrowser: block caching: minor tweak (mostly needed in ae branch actually). 2015-04-04 13:17:43 +02:00
4696bce257 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filelist.h
2015-04-04 13:15:17 +02:00
bbfe0652eb FileBrowser: rewrite 'entry selection' code.
Since we do not store anymore ell entries, we cannot use them to hold selection status.

So we now use a ghash in FileList struct, with entry UUID's as keys.

Also cleanuped up / refactored selection handling, filelist.c now features a nice intern
api and all other code uses it instead of accessing directly entries' selflag!
2015-04-04 12:43:53 +02:00
c0748c4292 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenlib/intern/storage.c
	source/blender/editors/space_file/filesel.c
2015-04-04 10:50:17 +02:00
e836c116ac Internal FileListing: generate a valid UUID, we'll need this for things like selection state... 2015-04-02 20:12:18 +02:00
f2e55db040 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-04-02 17:34:47 +02:00
e75c5c35cc FileBrowser Preview: enhance handling of previews when modifying cache of entries... 2015-04-02 17:29:31 +02:00
744c029d01 AssetEngine: Add needed API for new 'on demand' entries listing from FileBrowser.
Also use that new API in filebrowser - only partially for now, at least
it does not crash anymore even if 100% empty...
2015-04-02 17:11:33 +02:00
0d4ac96da0 Fixes needed to make it compile again. Remains broken though! 2015-04-02 15:29:21 +02:00
e70139964d Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filelist.h
	source/blender/makesrna/intern/rna_internal.h

Notes:
* asset-experiments branch still needs some work (e.g. entires selection is to be reworked too),
  but was more than time to do a first merge...
* This is raw merge, code is hence broken and needs more fixes to take into account new changes!
2015-04-02 15:20:52 +02:00
6ec52ce5eb Merge branch 'master' into asset-experiments 2015-04-02 14:53:27 +02:00
d07aeb2fce FileBrowser: cleanup.
Get rid of cache iterator code (not needed, and don't think we'll need it later,
easy to add back if needed). Also comment some debug prints.

New preview (thumbnails) handling seems to be working pretty nice now.
2015-04-02 14:41:19 +02:00
7bfe994093 FileBrowser: Fix stupid cache clear on each redraw while previews where updating.
Missing 'need filter' flag clearing...
2015-04-02 14:06:56 +02:00
d8169c2db7 FileBrowser - fix two crashers.
* Full path is no more static, so we need dynamic tooltips to use it (still an
  issue with drag stuff here :| ).
* Remove timer would attempt to free timer's customdata, which is mere int-in-pointer
  in case of new notifier timer, so we need a special tweak on remove here.
2015-04-02 13:51:13 +02:00
a592525a7e FileBrowser: cleanup (remove) all the thumbnails job stuff, no more needed. 2015-04-02 10:38:19 +02:00
c61d6e36ba FileBrowser: Fix sorting/filtering (we need to clear the cache in those cases!). 2015-04-02 10:27:07 +02:00
49951df23d Merge branch 'master' into asset-experiments 2015-04-02 10:17:11 +02:00
0dc6b92fe6 FileBrowser new preview code: bunch of fixes.
Start to looks good... This commit adds a new timer helper, that only send notifiers
(kind of very restricted subset of wm_job stuff), since using jobs for previews
would be now counter-productive and way too much heavy.

Also fix/enhance how previews are generated (order), etc. etc.

Still WIP though, having some weird crashes and such lurking around.
2015-04-01 22:26:25 +02:00
ce3a8f9f5b Merge branch 'master' into asset-experiments 2015-04-01 15:07:24 +02:00
46d777f017 FileBrowser previews: first fixing round.
Nearly working now (no more freeze or huge mem leak), still need to
find a way to get refresh as long as all previews have not been generated...
2015-03-31 16:44:46 +02:00
fd5e70fc99 Merge branch 'master' into asset-experiments 2015-03-31 15:43:06 +02:00
f970994cd3 Some minor cleanups. 2015-03-31 15:42:51 +02:00
982fdbf506 FileBrowser: Various fixes...
Stupid useless allocations, memleaks, etc.

WIP, thumbnails still not working.
2015-03-31 15:41:04 +02:00
c1617cccd1 Merge branch 'master' into asset-experiments 2015-03-30 22:02:34 +02:00
e7c7b00fe0 WIP FileBrowser thumbnails: get rid of job here, use lighter threaded tasks.
Fully WIP, compiles but not yet working!
2015-03-30 21:35:56 +02:00
8093c5c2a8 Merge branch 'master' into asset-experiments 2015-03-30 14:59:25 +02:00
bf3bba802d Quick attempt to resume thumbnails generation on cache.
Note this is rather stupid anyway, we need to rewrite this from scratch,
using a	 job for that makes no sense now, we should stick to a lighter
threading schema with a queue, or something like that!
2015-03-30 14:54:31 +02:00
2984d39a46 Fix and use block caching from UI draw code.
Seems to work nice now.
2015-03-30 12:24:00 +02:00
11df07e53f Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/include/UI_interface_icons.h
	source/blender/editors/space_file/filelist.h
2015-03-30 11:56:35 +02:00
ef0367d094 Merge branch 'master' into asset-experiments 2015-03-27 22:23:47 +01:00
188419ac3d WIP cache system for filebrowser entries.
Core part seems to be working, but this is still heavy WIP, much to do
to resume complete features from existing code. Mainly:

* Previews (those should only be ran on cached items now).
* Use block-caching to load in-display entries.
* Rework things like selection (cannot store selected states in entires anymore).

Also, internal listing is stupid currently (since it still stores everything
as FileDirEntry & co), not really crucial currently, but ultimately it'll
use its own, compact struct to keep full listing!

Also did some minor cleanup/renaming.
2015-03-27 22:05:36 +01:00
7a749ebbcf BLI listbase: add an helper to remove a constinuous chunk of the list in a single call. 2015-03-26 17:49:15 +01:00
e7dbb4b217 FileBrowser: First step towards allowing partial "storage" of entries.
That code is currently pretty stupid, but we need to clearly separate
what is handled by filebrowser itself, and what is by listing code
(be it internal one or future asset engines).

Plan/idea is to have a dual cache system (one 'block' of entries - centered
on currently viewed ones -, and one 'random' FIFO for random access to any entry).

This implies filebrowser itself shall now only be aware of the number of (filtered)
entries, and it then requests entries as needed.

Also, made size of columns in filebrowser fixed (ultimately, user configurable),
since it has no more access to the whole list of entries!

Still heavy WIP.
2015-03-26 15:24:03 +01:00
fca4cda7f9 Merge branch 'master' into asset-experiments 2015-03-26 11:04:37 +01:00
26d28b755b Reduce uuids size to 16 (as 'official' ones), more than enough! 2015-03-23 15:55:52 +01:00
9fbec44247 Merge branch 'master' into asset-experiments 2015-03-23 15:25:21 +01:00
a9f02fda07 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/makesdna/DNA_space_types.h
2015-03-21 16:48:34 +01:00
8834875281 Merge branch 'master' into asset-experiments 2015-03-21 16:44:40 +01:00
8bc8015657 WIP Amber: very quick, dirty, primitive and broken first implementation of tags handling.
We cannot do that correctly with current listdir system, have to rework again
in asset-experiments brnach first, so that listing, filtering and sorting is
completely "delocalized" to asset engine (will also try to solve scalability issues).
2015-03-21 16:42:00 +01:00
9553016ec1 WIP 2015-03-19 16:15:42 +01:00
01b6fd1f3e Merge branch 'master' into asset-experiments 2015-03-19 14:01:16 +01:00
3f860e0e73 AssetEngine: add IDProps, and RNA access to actual asset engine from filespace.
Also, some quick dummy test/demo code for that in Amber.
2015-03-17 21:07:57 +01:00
cdfd3c17f5 Merge branch 'asset-experiments' into asset-engine
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-03-17 16:27:39 +01:00
bc40f4852d Fix broken 'sort by type' in filebrowser.
Also, take advantage of blentype stored in entries now,
this greatly simplifies (and make quicker) that sorting
for blendlib items!
2015-03-17 16:02:12 +01:00
99373c918f Add a 'comment' field to listdir revisions.
Also, make clear tags are only informative here.

Reason is, if the project is a success, we have to think big and
imagine asset engines managing catalogs of tens or hundreds of thousands
of entries (web ones e.g.), we cannot hold list of those in filebrowser!
So most of filetring will be 'deffered' to asset-engine.

We'll also probably have to implement a 'chunck listing' behavior
(to only list at most n entries in a row), for same reasons.

This will make things slightly more complicated :|
2015-03-17 15:39:20 +01:00
920bf9f2f3 Merge branch 'master' into asset-experiments 2015-03-17 14:47:54 +01:00
18baac2502 Amber: Some cleanup and atempt to fix repeated entries, not yet working. 2015-03-16 21:23:43 +01:00
9cf2583126 I18n: update for new akward algo names in UI messages... 2015-03-16 20:51:35 +01:00
0661b80aa0 Continue fleshing out Amber.
Start to add real asset engine behavior. Still completely uncomplete and not even half working.
2015-03-16 20:18:42 +01:00
0473ff213e Merge branch 'asset-experiments' into asset-engine 2015-03-16 13:51:42 +01:00
025b502f98 Merge branch 'master' into asset-experiments 2015-03-16 13:48:19 +01:00
f3c6cc9f32 Fix nasty bug preventing any navigation in directories!
Think issue also exists in master code actually, where some op properties
could be left uninitialized in 'params_to_op' helper func... But it does not
backfire like that for sure.
2015-03-15 20:34:42 +01:00
60783fd64e Amber: only list dirs from real filesystem.
Actual data (assets) are to be 'listed' by another way!

Also, fix mem leak.
2015-03-15 17:28:10 +01:00
7059cd538f Merge branch 'asset-experiments' into asset-engine 2015-03-15 15:48:40 +01:00
4621ac3ac1 Merge branch 'master' into asset-experiments 2015-03-15 15:31:10 +01:00
f9adc7fbac Start to make Amber a bit more serious!
Still useless - behaves more or less like a very basic, broken filebrowser.

But basics are here, and listing process seems to be working pretty well.
2015-03-13 22:26:22 +01:00
e615009ae4 Revert "Revert "Merge branch 'asset-engine' into asset-experiments""
This reverts commit f751e34f91.
2015-03-13 15:21:55 +01:00
f751e34f91 Revert "Merge branch 'asset-engine' into asset-experiments"
This reverts commit ccd1479200, reversing
changes made to 8da3bb3885.

Conflicts:
	release/scripts/startup/bl_operators/__init__.py
	release/scripts/startup/bl_operators/amber.py
	source/blender/blenkernel/BKE_asset.h
	source/blender/blenkernel/intern/asset.c
	source/blender/editors/space_file/file_ops.c
	source/blender/makesrna/intern/rna_asset.c
2015-03-13 15:18:24 +01:00
47ce2c5574 Merge branch 'master' into asset-experiments 2015-03-13 14:45:08 +01:00
ec3eec1ac5 Add load_pre callback to RNA, and stupid dummy code in Amber to make quick test of it. 2015-03-12 19:41:12 +01:00
47e3d34d94 RNA listdir: add some more accessors, and ability to remove/clear list of entries (assets). 2015-03-12 15:19:27 +01:00
ab463cb324 Rename 'Flame' to 'Amber'! 2015-03-12 11:07:10 +01:00
ccd1479200 Merge branch 'asset-engine' into asset-experiments 2015-03-12 11:03:40 +01:00
8da3bb3885 Merge branch 'master' into asset-experiments 2015-03-12 11:00:14 +01:00
473e702d5d First step to add 'load_pre' behavior.
This will allow asset engines to:
* Actually ensure requested data is available (downloading it, generating it, etc. as needed).
* Change entries generated for user by actual data paths (allows e.g. to present
  a set of different paths to load as a single 'asset' to user).

As usual, had to change existing filebrowser code... Seems to be working fine
from quick tests (i.e. regular filebrowser not being broken).
2015-03-12 10:59:10 +01:00
da53656be1 Add refcounting and shallow copy to AssetEngine.
Reason is, we want operator to 'inherit' ae instance from spacefile too.
2015-03-10 12:52:25 +01:00
99404d3a70 Fix initialization of AssetEngine type in new filebrowser. 2015-03-10 12:11:07 +01:00
4504d50012 Merge branch 'asset-experiments' into asset-engine 2015-03-09 16:26:04 +01:00
9c6abdff3a Merge branch 'master' into asset-experiments 2015-03-09 15:32:52 +01:00
8f0709f9eb Add more stuff to filelist RNA. 2015-03-05 10:08:33 +01:00
32f4fb952a Cleanup - remove big commented blocks from renderengine initial copy/paste. 2015-03-05 10:08:33 +01:00
5d732ddcae Add some asset engine-aware stuff in filebrowser.
Basically, filelisting code in space_file becomes default, internal 'asset engine',
and user can switch to any other available engine instead.

Note filelisting with asset engines is fully main-thread from C code PoV,
parallelization/asynchronism is responsability of the py code!

Also, added a basic (dummy currently) AssetEngine py implementation.
Not much there, but helps checking things works as expected before
writing whole interface!

All this is very basic early code yet, much much to do before we get anything really usable...
2015-03-05 10:08:33 +01:00
9f61207b23 Minor updates to asset engine API, and add some more basic file listing stuff to RNA. 2015-03-05 10:08:33 +01:00
1dcff09045 Further rework of file listing handling - complete decouple from OS-related direntry.
Remove everything not really related to OS representation of file entries.

FileBrowser will now use a complete decoupled version of file representation,
much easier to keep sane behavior this way, easy integration with RNA, etc.
2015-03-05 10:08:33 +01:00
7142e653b6 Add RNA structs for assets listing (with variants, revisions, etc.). 2015-03-05 10:08:33 +01:00
f6c3f08690 WIP start defining asset engine API. 2015-03-05 10:08:33 +01:00
beee21d045 Void skeleton of asset engine.
Mostly copied from RenderEngines code. Compiles, now we have to flesh this!
2015-03-05 10:08:33 +01:00
c5fde2845e Merge branch 'master' into asset-experiments 2015-03-05 09:48:28 +01:00
f2bff41cd5 Merge branch 'master' into asset-experiments 2015-03-03 17:10:30 +01:00
65b49051fb Add name/description fields to entries themselves too.
This allows us to greatly simplifies sorting (and avoid recomputing UI name each and everytime!).
Also, correctly free entries/variants names/descriptions.
2015-03-01 11:42:28 +01:00
de58d865b6 Spread (future assets) uuid over entries/variants/revisions.
Makes more sense this way, and will probably save memory in the end even.
2015-03-01 11:21:01 +01:00
6771aeeff5 Merge branch 'master' into asset-experiments 2015-03-01 10:54:02 +01:00
02c09be238 Merge branch 'master' into asset-experiments 2015-02-28 15:21:44 +01:00
25e0d0d63d Filelisting: switch from mere arrays to listbases.
Was not sure about that (adds two pointers to entries, variants **and** revisions :/ ),
but with the incremental process of listing we are using now, it makes things sooooo
much easy to handle (and also avoids tons of (deep)copy and mem (re)alloc), that it's
definitively worth it.

And since most (if not all) of 'public' access to filelist is done through filtered ones,
we can easily keep this a mere array of pointers, and hence keep quick index lookup.

Also, quite noticiably simplified the whole listing code (less functions, less levels of subcalls...).

Note: for now we stick to mere alloc, we may benefit from either memarena or mempool,
but those are not threadsafe (which means we could not so easily pass mem from worker
thread to main one), so not quite sure it would be worth it.

Note: thumbnail stuff is to be reworked from scratch too, have the feeling it's not yet
100% thread safe, and using a job here is probably way overkill, since we do not show
any progress in UI.
2015-02-27 19:18:33 +01:00
543984ffff Merge branch 'master' into asset-experiments 2015-02-27 14:23:37 +01:00
a35de360d0 Merge branch 'master' into asset-experiments 2015-02-26 15:38:59 +01:00
ae294763aa Merge branch 'master' into asset-experiments 2015-02-24 20:15:13 +01:00
52d3e71302 Move back path, image etc. to FileDirEntry.
Also, reduce revision's uuid to 64bytes, should be more than enough!

Thing is, we can expect tens (if not hundreds) of thousands of revisions from a
big assets repository with history storage (vcs). So we want that struct
to be as small as possible.

Also, we do not expect to handle several variants/revisions of a same asset within
a same 'context' (there is always only one active variant & rev). So storing
path & co at entry level shall be enough. And helps make code simpler/nicer.
2015-02-24 16:20:19 +01:00
21ae02a327 Get rid of abspath storage, this is storing twice the same data, not nice memory-wise.
We may suffer a little performance loss here, but would not expect it to be really important,
since rebuilding a full abspath is not needed that often.
2015-02-24 14:46:45 +01:00
da7092ff7d Restore size/date sorting.
Also, get rid of modes/owner crap, this is quite advanced UNIX fs info, not much to
do in our filebrowser imho, and takes time, UI space and Mem space!
2015-02-24 14:14:27 +01:00
cf89c7aa28 Merge branch 'master' into asset-experiments 2015-02-24 12:48:23 +01:00
f7f71bb152 Merge branch 'master' into asset-experiments 2015-02-23 16:13:26 +01:00
fb94004e6f Merge branch 'master' into asset-experiments 2015-02-23 15:08:14 +01:00
29d3cbc6f9 Filelisting: First step of sanitanization...
Move typeflag and selflag back to FileDirEntry, and add blentype there too,
this will be needed by asset engines, and avoids rechecking lib ID types over and over!

There's much more to do here though. Also, FileDirEntryRevision is going to be
used quite higly, we want to keep it as light as possible (much lighter than
its current state for sure!). Think we can move back to FileDirEntry paths
(and try to get rid of abspath on the run, too), but also most likely
preview (we won't store a preview for all possible revisions anyway),
owner/permissions, etc.

Rev should probably only have its uuid, and date/time.

Also, simplified filetype generation (from extensions for real files, and BLO helpers
for libdata), now it's nicely encapsulated into each reading callback.
2015-02-23 14:47:34 +01:00
156c5bc41e Merge branch 'master' into asset-experiments 2015-02-23 12:27:29 +01:00
e08fd1ebe5 Merge branch 'master' into asset-experiments 2015-02-22 15:21:38 +01:00
b32de3eaff Merge branch 'master' into asset-experiments 2015-02-19 15:30:51 +01:00
a759d0190b Big refactor of filelisting in filebrowser - decouple os/fs-related direntry from actual blender listing.
Main idea is that direntry had quite a bit of things already absolutely useless
in the mere 'file listing' context (image pointer, void 'data' pointer, etc.).

On the other end, to handle future asset stuff, we need *more* 'meta data' for our 'files'
(tags, variants, revisions...).

Further more, we need all this to be easily usable through RNA, i.e. we need it to
be defined in DNA.

So instead of trying to use direntry in DNA, mixing low-level system stuff like stat
where we do not want to see it, we define our own 'file' representation,
with only what we really need (who cares about chars or block or dev files in filebrowser?
we only need to know whether it's a regular file or a directory, period).

That way, low-level dirlisting remains clean, and we can easily extend our own
data as needed.

Note this new code works, does not crash (so far...) nor memleak, but it
needs quite a bit of work still, we are still storing useless stuff in direntry
(all those strings representing modes, size etc.!), and mem handling
during dir/lib listing is confusing at best (would like to use a memarena
or mempool here, but it's not that easy).
2015-02-18 21:36:48 +01:00
3e6aa7bd08 Merge branch 'master' into asset-experiments 2015-02-18 19:30:06 +01:00
a35ced0b97 Merge branch 'master' into asset-experiments 2015-02-17 15:37:20 +01:00
14ff7cdf76 Merge branch 'master' into asset-experiments 2015-02-16 16:21:28 +01:00
ecb79a5bd5 Preview generation on Windows: attempt to fix mysterious error by using even more ID's names.
Passing around ID's themselves is not safe - they may change their mem addresses.

Yet, I had no issue on linux, but on win build this is still not enough,
have to use a super strange hack (add an 'import sys' line just before where error happens)
to get things running...
2015-02-16 14:54:19 +01:00
d893c9f198 Merge branch 'master' into asset-experiments 2015-02-16 14:01:44 +01:00
07042a8d5d Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_draw.c
	source/blender/editors/space_file/filelist.c
2015-02-15 16:54:08 +01:00
d78819caf9 Cleanup of ugly allocation stuff (cast of void pointer, not-so-safe sizeof()'s, etc.). 2015-02-15 15:28:43 +01:00
ec071eb76a Merge branch 'master' into asset-experiments 2015-02-15 15:10:34 +01:00
5e25fdd514 Merge branch 'master' into asset-experiments 2015-02-15 10:39:38 +01:00
fb2c646dee Rework job multi-level listing - factorize even more and avoid recursion.
This is much cleaner than previous code...
2015-02-13 22:28:36 +01:00
3e603b606c Merge branch 'master' into asset-experiments 2015-02-13 19:47:00 +01:00
4c02644a58 Merge branch 'master' into asset-experiments 2015-02-12 19:45:25 +01:00
c6ea9e8f48 Merge branch 'master' into asset-experiments 2015-02-12 19:35:41 +01:00
05390dc4b5 Cleanup. 2015-02-12 18:01:02 +01:00
09a09c1010 Merge branch 'master' into asset-experiments 2015-02-12 17:55:07 +01:00
5144dcaeab Add previews to scenes, and enhance batch preview generation.
Batch preview generation can now also generate 'internal' previews (materials, textures etc.),
as well as scene ones. Also, some basic Cycles handling is there now.
You can now chose which kind of data to generate previews for, and whether the files are
trusted or not (for py autorun and drivers).
And rendering happens in background again, issue was actually a bug in creator.c, fixed in master.
Main TODOs reamining here: OpenGL rendering, and find a way to prevent '.blend1' when
saving over (either as a new option of save op, or simply by removing those files in script?).

Added a batch cleanup of previews too.

Also, added path of files as their tooltip 'image' button in main filebrowser view,
quite useful with the 'recursive' option...
2015-02-12 17:53:00 +01:00
e9484fa25e Merge branch 'master' into asset-experiments 2015-02-11 17:32:41 +01:00
92ef1b997b Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/space_file.c
2015-02-11 11:18:42 +01:00
6f603ea0d2 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/versioning_270.c
	source/blender/editors/include/ED_fileselect.h
	source/blender/editors/interface/interface_intern.h
	source/blender/editors/interface/interface_templates.c
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/fsmenu.c
	source/blender/editors/space_file/space_file.c
	source/blender/makesrna/intern/rna_space.c
2015-02-11 11:14:42 +01:00
67eb234783 Merge branch 'master' into asset-experiments 2015-02-10 12:40:24 +01:00
ec4b79fb60 Merge branch 'master' into asset-experiments 2015-02-09 10:15:02 +01:00
08bccfed6c Merge branch 'master' into asset-experiments 2015-02-09 09:20:39 +01:00
d8567fc45d Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/versioning_270.c
2015-02-06 17:31:55 +01:00
51bc0a2b5d Fix crash when appending/linking (double free...). 2015-02-04 20:41:13 +01:00
8374fe855e Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/versioning_270.c
2015-02-04 20:14:04 +01:00
399ae5d41a Make 'recursion' work as expected.
Now, recursion  0 = previous behavior,
     recursion  1 = only show content of immediate .blend files, do not recurse in actual dir hierarchy,
     recursion >1 = complete recursion!
2015-02-03 21:47:51 +01:00
ad1399acc4 Flat listing of libs: do not show the 'categories' directories unless we are
inside a single .blend lib in this case, useless and heavily clutters space.
2015-02-03 21:18:07 +01:00
d04a0baae7 Merge branch 'master' into asset-experiments 2015-02-03 20:45:25 +01:00
c0d0b3db66 Merge branch 'master' into asset-experiments 2015-02-02 12:16:00 +01:00
8b19837b83 Cleanup: add 'ED_' prefix to public fsmenu functions... 2015-02-01 21:02:29 +01:00
f6b9cad064 Cleanup: get rid of unused stuff! 2015-02-01 20:49:45 +01:00
9a4eb983be Merge branch 'master' into asset-experiments 2015-02-01 20:35:48 +01:00
93da0a8187 Prepare assets UI: switch filebrowser to tools + tool props areas, instead of channels.
This will allow us to keep op panel independent, and have tabs for future assets tools!

Note 'conversion' from previous file area (channels) is not perfect, you have to hit 'T'
twice currently if you had a filebrowser in your .blend file...
2015-01-30 18:38:02 +01:00
b3cd561032 Merge branch 'master' into asset-experiments 2015-01-30 13:58:45 +01:00
8ebe85f733 Merge branch 'master' into asset-experiments
Conflicts:
	release/scripts/startup/bl_operators/wm.py
2015-01-29 19:37:50 +01:00
9efd36bac0 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/windowmanager/intern/wm_operators.c
2015-01-27 19:51:35 +01:00
d41e1c00e6 Merge branch 'master' into asset-experiments 2015-01-27 12:02:40 +01:00
1c83d9ddbb Fix filtering in new UIList bookmarks & co. 2015-01-26 21:41:31 +01:00
ce765ad441 Better sorting when we are displaying several levels at once, for 'lib' append/link.
Consider blendfiles and 'categories' inside them as regular dirs, but with this hierachy:
    real dir > blende file lib > category in a blend lib.

This gives a much better sorting (among other things, gives more importance to
blend files!).
2015-01-26 21:30:00 +01:00
b3c0b59825 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/readfile.c
	source/blender/editors/space_file/file_draw.c
	source/blender/editors/space_file/file_ops.c
	source/blender/editors/space_file/filelist.c
2015-01-26 17:38:16 +01:00
6f1e2e562d Merge branch 'master' into asset-experiments 2015-01-26 12:28:00 +01:00
6199ce89a8 Reworked from scratch 'icon over previews' feature.
Previous implementation was horribly complicated in the end... sigh.
2015-01-25 15:30:46 +01:00
bdda315260 Fix crasher (Looks like PointerRNA->type can be NULL...). 2015-01-25 14:59:04 +01:00
50d25aa395 Merge branch 'master' into asset-experiments 2015-01-25 12:43:36 +01:00
b1a885ab16 Merge branch 'master' into asset-experiments 2015-01-20 14:07:41 +01:00
8ff6e455fa Merge branch 'master' into asset-experiments 2015-01-18 18:50:31 +01:00
f1d1073046 Merge branch 'master' into asset-experiments 2015-01-17 20:09:37 +01:00
956d8e0ddd Fix for Windows - 'foobar.blend\' is a valid file path to that OS, sigh...
Also, store temp nullified pathsep in chars now, better.
2015-01-17 20:08:12 +01:00
03b7104b72 Fix stupid UI/py bug after recent refactor. 2015-01-17 00:04:06 +01:00
2d98ce2e72 Merge branch 'master' into asset-experiments 2015-01-17 00:03:33 +01:00
de3fd8a45c Merge branch 'master' into asset-experiments 2015-01-15 16:23:19 +01:00
d7b0bc9522 Merge branch 'master' into asset-experiments 2015-01-13 16:44:36 +01:00
548029c000 Merge branch 'master' into asset-experiments
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
2015-01-13 16:42:33 +01:00
0715b73e18 Recursive listdir: let user set level of recursion... 2015-01-13 15:41:10 +01:00
912cdb2acb Merge branch 'master' into asset-experiments 2015-01-13 14:57:27 +01:00
5fccc64f6d Merge branch 'master' into asset-experiments 2015-01-13 14:15:01 +01:00
c944362fcd Merge branch 'master' into asset-experiments 2015-01-12 19:58:43 +01:00
27ce761880 Reorganization:
* Make 'clear preview' a C operator;
* Move 'object preview generator' op in wm namespace;
* Add those two to file-> data preview submenu.
2015-01-12 17:45:45 +01:00
517b06c296 Reorganization: move ID filters to DNA_ID.h, and add helpers in bke's idcode.c to convert between idcode and idfilter. 2015-01-12 17:44:44 +01:00
3118756854 Merge branch 'master' into asset-experiments 2015-01-12 15:50:35 +01:00
d35bbc2a15 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/intern/group.c
	source/blender/blenkernel/intern/object.c
2015-01-10 10:18:23 +01:00
2c7ee72167 Add moving around bookmarks (same system as for vgroups etc.). 2015-01-07 21:13:45 +01:00
884603573a Merge branch 'master' into asset-experiments 2015-01-07 14:22:12 +01:00
67231a22a2 Merge branch 'master' into asset-experiments 2015-01-07 12:47:51 +01:00
e53cdbf62f Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/include/UI_interface_icons.h
	source/blender/editors/interface/interface_icons.c
	source/blender/windowmanager/intern/wm_files.c
2015-01-07 12:44:45 +01:00
d46c9b876c Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/filelist.c
2015-01-07 12:05:23 +01:00
dbd766f827 Nearly finished 'UIList for bookmarks'.
Got completely rid of C code for those panels.

Added full path in ttips of each 'bookmark' entry, as in current master.
Note this forced me to make tip in uiBut dynamic (like label). Not so sure
about this, but seems to me forcing tooltips to be static is actually quite
bad and limitating? we'll see...

Only remaining TODO (new feature) is reordering of bookmarks, should be easy now.

Also fixed some stupid (again!) mistake with RNA access to paths of bookmark entries.
2015-01-05 21:12:23 +01:00
de229b4085 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/space_file.c
2015-01-05 16:15:37 +01:00
3993965bd7 Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/file_draw.c
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filesel.c
	source/blender/makesdna/DNA_space_types.h
	source/blender/windowmanager/intern/wm_operators.c
2015-01-04 18:43:08 +01:00
97a00b9199 Merge branch 'master' into asset-experiments
Conflicts:
	release/scripts/startup/bl_ui/space_filebrowser.py
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filelist.h
	source/blender/editors/space_file/space_file.c
	source/blender/makesdna/DNA_space_types.h
	source/blender/makesrna/intern/rna_space.c
2015-01-03 22:05:01 +01:00
d237ac45fe Get rid of this stupid string len def, RNA knows this better! 2015-01-03 21:34:17 +01:00
0f44f5506f Fix some issues with image previews.
* When overlaying icon, we have to also ensure background pict is always the same size
  (else you get usgly icon size changes). Still not perfect though, suspect some more issues
  in filrdraw code, probably should systematiacally run the 'ensure size' code during thumbnail
  generation?
* Sharing of img ImBuf between thumbnail job and main thread could still happen,
  leading to random crashes.
2015-01-03 18:43:51 +01:00
d730ff663b Fix py script generating obj/group previews after recent merge. 2015-01-03 17:39:23 +01:00
8f4d6f62ea Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenkernel/BKE_camera.h
	source/blender/blenkernel/intern/camera.c
	source/blender/blenlib/BLI_fileops.h
	source/blender/blenlib/intern/storage.c
	source/blender/editors/space_file/filelist.c
	source/blender/makesrna/intern/rna_object_api.c
	tests/gtests/blenlib/BLI_path_util_test.cc
2015-01-03 17:07:16 +01:00
55c792df8e Add 'dup_poin' callback param to new BLI_duplicate_filelist() func, to allow handling direntry's poin if needed. 2015-01-02 17:38:25 +01:00
7b05fd5830 Merge branch 'master' into asset-experiments 2015-01-02 17:24:39 +01:00
67040e08d3 Fix issues when giving a non-existent dir to filebrowser.
Note: unlike in current master, path is checked immediately when setting it
into filelist (simpler now that filelist building itself is threaded).
`filelist_setdir()` modifies in place given path if this one is not valid.
2015-01-01 16:58:30 +01:00
87518faa20 Use new BLI fnmatch helpers to fix wrong update in some cases when editing
string search filter.
2015-01-01 15:30:02 +01:00
e660793896 Add BLI helpers for fnmatch head/tail wildcards handling.
`BLI_fnmatch_strncpy_add_endswildcards()` will copy and add '*' wildcards on both ends of given string, if needed.

`BLI_fnmatch_strcmp_ignore_endswildcards()` is same as strcmp, but ignores any '*' wildcards on both ends of given strings.
2015-01-01 15:23:16 +01:00
224eb0025f Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/interface/interface_icons.c
2015-01-01 15:18:38 +01:00
31043d87cd Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filelist.h
	source/blender/editors/space_file/space_file.c
2015-01-01 11:35:21 +01:00
de0b270014 Merge branch 'master' into asset-experiments 2015-01-01 11:11:10 +01:00
0fa91e1723 SpaceFile: Cleanup: fix stupid indices in filelist_from_main()
Dead code (currently), but still...
2015-01-01 11:10:12 +01:00
aa336809fa Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/editors/space_file/filelist.c
	source/blender/editors/space_file/filelist.h
	source/blender/editors/space_file/space_file.c
2015-01-01 11:08:21 +01:00
425e8119de SpaceFile: Tweak thumbnail to avoid restarting the job needlessly. 2014-12-31 20:45:39 +01:00
4f241d3d36 SpaceFile: Refactor sorting and filtering of filelist.
New code shall be more easy to maintain and extend.
Sorting is now handled quite the same as filtering, and all filtering parameters
are now packed into a sub-struct to help extending it later.

Also done some optimizations in filelist refresh, and sorting/filtering area.
Now we should avoid re-sorting and re-filtering too often, also removed
calls to those in read_xxx funcs.

Note thumbnail job is still started basically on each call to `file_refresh()`,
will be addressed in next commit.
2014-12-31 20:13:21 +01:00
6a7076c9d4 SpaceFile: Filelist: reorder a bit things, also cleanup some unused and pure-private funcs. 2014-12-31 19:25:41 +01:00
ba0294cfe0 Merge branch 'master' into asset-experiments 2014-12-31 12:00:06 +01:00
0350111424 Merge branch 'master' into asset-experiments 2014-12-29 16:50:37 +01:00
8fa24594ce Merge branch 'master' into asset-experiments 2014-12-28 12:52:52 +01:00
1d42f07d58 Change timer of readdir job to 10ms, this gives an 'immediate' listing for most
usual cases, as in current master.
2014-12-28 12:49:24 +01:00
dc0a4fde63 Merge branch 'master' into asset-experiments 2014-12-27 17:26:17 +01:00
00cb0035a7 Fix one more issue - we need a string length callback too, for pure 'virtual' RNA strings... 2014-12-26 21:50:36 +01:00
4e19102964 Fix a mem leak in file listing threaded code, and another bug in fsmenu.c (new named bookmarks). 2014-12-26 19:58:08 +01:00
3c52c4ab0a Merge branch 'master' into asset-experiments
Conflicts:
	release/scripts/startup/bl_ui/__init__.py
	source/blender/editors/interface/interface_utils.c
2014-12-26 18:37:01 +01:00
0357a4928f Fix some 'minor' errors in fsmenuentry RNA name handling.
Still have a nice mem leak somewhere too... :/
2014-12-22 16:01:19 +01:00
4b1f410012 Add buttons to add/remove bookmarks, and to reset recent list. 2014-12-22 15:20:33 +01:00
cfc61a9337 Filebrowser uilist bookmarks: add icons as expected. 2014-12-22 14:47:12 +01:00
acaa5b2748 You can now edit bookmarks (and recent) names... 2014-12-22 14:39:54 +01:00
aa87764d13 WIP UILists for filebrowser: add access to three remaining types.
This also change update of active bookmark indices to happen in file_refresh().

Still not fully working, of course.
2014-12-22 12:25:40 +01:00
1a5caea321 Merge branch 'master' into asset-experiments 2014-12-22 10:26:07 +01:00
242fdf5e60 WIP: merge work on local branch about using UILists for bookmarks, be able to rename them, etc.
Doing it mostly because I need some update work done here so far to get py uilists/bookmarks working.

This exposes/moves part of bookmark code to ED_ area, so that it becomes available from e.g. RNA.
And adds RNA struct and such to represent a bookmark entry.

Also, Bookmark format is ammended to store optional custom names.

All this is still *very* crappy, should probably take some time soon to cleanup the whole branch!

See also T42777.
2014-12-21 16:02:12 +01:00
b734d9bf17 Merge branch 'master' into asset-experiments 2014-12-21 15:20:21 +01:00
4478ddc3d9 Add group preview generation too. 2014-12-20 16:47:41 +01:00
aa24a7d0a5 Merge branch 'master' into asset-experiments 2014-12-20 13:44:41 +01:00
d1743e3783 Fix stupid error (CMake install does not clean removed files it seems :/ ) 2014-12-19 14:54:35 +01:00
1dab208eb8 Various improvements to obj preview generation:
* Do not render cameras, lamps etc. for now.
* Generate bbox in camera local space, gives much better results.
* Add an op to clear previews from files.
2014-12-19 14:29:06 +01:00
db9310ac67 Merge branch 'master' into asset-experiments 2014-12-19 13:59:13 +01:00
d0187bf624 Merge branch 'master' into asset-experiments 2014-12-18 19:38:29 +01:00
baeeacc62d First basic pyscripts to generate previews for objects.
Much to be done still, but with it you can select some blender file,
and generate a basic rendered preview of each object.
2014-12-18 19:36:51 +01:00
88ffc9767c Finalized working new 'fit in camera view' code.
Now for any object, we have an rna func to call with a set of (flatten :/)
coordinates, and we get back location this object should be to 'see'
all given points.

Would need more refinements, but will do for now.
2014-12-18 15:26:34 +01:00
95b103c73b Merge branch 'master' into asset-experiments 2014-12-18 12:37:32 +01:00
a79a8fa111 Full WIP work to get better control regarding 'camera' aspect of objects.
First expose a method in Object RNA to get camera projection matrix (done).

Then, expose a method to get camera position (and scale for ortho) so that
it fits a given set of coordinates (still unfinished).

this among other things implied rewriting `BKE_camera_view_frame_fit_to_scene()`
underlying logic so that it uses `CameraParams` system, instead of `BKE_camera_view_frame()` one.
2014-12-17 21:56:09 +01:00
5cc7df849f Fix stupid merge error. 2014-12-17 10:43:31 +01:00
12e3347a5a Merge branch 'master' into asset-experiments
Conflicts:
	source/blender/blenloader/intern/writefile.c
2014-12-17 10:42:52 +01:00
c440c22d18 RNA access to previews (image and icons).
Note since this gives python possibility to change those previews,
we add flags to PreviewImage to tag as user_defined.

TODO: replace all those shorts-used-as-bools by bitflags!
2014-12-16 18:03:28 +01:00
46d6d74386 Merge branch 'master' into asset-experiments 2014-12-16 16:59:01 +01:00
e1a345b3fe Ensure previews are up to date when saving .blend file.
Previuosly, we would only write existing data - and big previews were
nearly never generated by default.

Now, if saving previews is enabled, `wm_file_write()` will ensure
all 'common' previewable datablocks do have up-to-date previews
(brushes remain TODO here for now, they have both a preview **and**
an icon_imbuf, sigh...).

This implied adding an 'immediate' non-job-background version of
`ED_preview_icon_job()`.

Note this does not include objects/groups/etc. It's not simple to generate
previews for those, will probably go for a user-launched py operator here...

Also, cleanup some debug prints!
2014-12-16 14:41:44 +01:00
3c738b301f Never write preview data when doing memsave (i.e. undo).
Takes useless space, and they even could easily get out of sync.

Also, some minor preparative work to (re)generate previews on file write,
if needed!
2014-12-16 11:50:15 +01:00
b3b362a212 Reshufle a bit icon/preview size defines.
We now have a _RENDER_ variant of those, used when creating the previews,
so that we create 32x32 icons needed for those special screens...
2014-12-16 11:12:14 +01:00
9516d3fafc Some minor refinement regarding overlayed icons.
Note, even when unpremultiplying alpha, we still have 'breadcrumbs' around
icons, not sure why...
2014-12-16 09:56:57 +01:00
ddf519096d Merge branch 'master' into asset-experiments 2014-12-16 09:18:45 +01:00
02290ec582 A bit crappy, but working 'ID icons' over previews. 2014-12-15 19:55:15 +01:00
b36d5570c8 Refactor 'immediate search'
Previous implementation was uglyly relying on button using a specific
icon (VIEWZOOM) to enable this feature. Now we have a dedicated button flag
(UI_BUT_TEXTEDIT_UPDATE) and a dedicated RNA subtype (PROP_SEARCH) for that.

Also, if no icon is specified, it automatically set VIEWZOOM for it,
which saves us explicitely defining it in UI py code!

NOTE: this is to be committed asap in master, but has to wait for
after 2.73, so storing it here for now.
2014-12-15 14:52:10 +01:00
66f3def3b4 Cleanup: use ICON_DEFAULT_HEIGHT everywhere for ICON_SIZE_ICON
If we need bigger icon size for previews (like 32 instead of 16), then
it should be handled everywhere!
2014-12-15 13:02:54 +01:00
05926f7253 Do not set filetype to IMAGEFILE when we get a preview, this is absolutely stupid! 2014-12-15 12:28:17 +01:00
002e71f255 Merge branch 'master' into asset-experiments 2014-12-15 12:02:07 +01:00
f12f6ddd04 Fix stupid buggy behavior when init (root) dir had no trailing slash. 2014-12-15 11:19:43 +01:00
dfe8884e7a Add missing 'ID' icons, and a 'blenlib' filter to filetypes. 2014-12-15 11:03:44 +01:00
4f2e8c0315 Merge branch 'master' into asset-experiments 2014-12-15 09:37:56 +01:00
812f40c493 More borring boiling code for ob/group previews.
Also, try to make brushes also save their previews.

Anyway, something fishy is going on here, in theory we should get
previews for brushes, worlds, lamps... for free, but so far looks like
lib 'peek' code only handles mat/texture previews correctly?
2014-12-13 15:48:18 +01:00
3c634400a0 Add preview pointers to Object and Group, with read/write logic.
Doing nothing useful yet, though!

Note: ultimately we may want to move that preview stuff to ID struct,
so that we get a real basic generic handling of it, but for now
simpler to keep it as is.
2014-12-13 15:14:04 +01:00
8058d7d04f Merge branch 'master' into asset-experiments 2014-12-13 14:25:59 +01:00
35554d43b1 Merge branch 'master' into asset-experiments 2014-12-11 20:10:47 +01:00
8644862fac Add progressbar to dirlist job.
Progressbar value is quite chaotic currently, will check that later.

Also, fixed G.main still being used in job, and factorized once more time code.
2014-12-11 20:07:32 +01:00
5cf39b228d More cleanup, rename and commentting.
Also, definitively removed 'G.main.name protection' from lib reading
code. I do absolutely not see how listing a separate blend file handle
could possibly affect that anyway - and we do not want to access
G from non-main thread I'd bet...
2014-12-11 18:37:58 +01:00
b81d5a194a Atomic Cleanup: get rid of 'old' stuff no more used (mostly non-job read/list funcs)! 2014-12-11 18:16:32 +01:00
d211c58856 Merge branch 'master' into asset-experiments 2014-12-11 17:49:47 +01:00
7cb8a89aa0 Fix that stupid memleak in job-dir-listing code. 2014-12-11 17:46:46 +01:00
cb0272ceab Full rework of job (background) filereading code.
Now it works reasonably OK for filesystem, and also for .blend libs.

Code is even quite simpler than previous one. Now it needs some serious cleanup,
and find where (new) memleak comes from too.
2014-12-11 17:33:16 +01:00
9a7ff0f4fe Merge branch 'master' into asset-experiments 2014-12-11 09:57:06 +01:00
769de4ff1e Merge branch 'master' into asset-experiments 2014-12-10 21:16:42 +01:00
5d3ee3d695 WIP code to make readfilelists jobs.
Only very partially working in this state, still needs some work.
Proof of concept seems rather interesting though.

Also, only pure filesystem stuff is implemented for now.
2014-12-10 21:14:26 +01:00
3ff51cd5df Merge branch 'master' into asset-experiments 2014-12-10 17:05:04 +01:00
e4d9f9b772 Merge branch 'master' into asset-experiments 2014-12-10 15:58:39 +01:00
09b3e44b22 Reduce recursion to one level (.blend libs do not take that into account anyway).
Quicker, and in most cases I think this will be enough for libs and file browsing.

Real asset handling is another question.
2014-12-10 11:51:25 +01:00
c5fccb7caf Merge branch 'master' into asset-experiments 2014-12-10 11:40:01 +01:00
0add26e60b Merge branch 'master' into asset-experiments 2014-12-09 17:46:10 +01:00
c725d868af Filter completely 'dot-files', even when hidden in paths. 2014-12-09 17:44:29 +01:00
8f1df9fbba Fix wrong update when switching 'flat' state, also fix remaining memleak. 2014-12-09 17:23:32 +01:00
f06ed97ce7 Do not show ID-types filtering when we are not browsing libs! 2014-12-09 14:56:30 +01:00
f13f85676d Merge branch 'master' into asset-experiments 2014-12-09 14:15:35 +01:00
21030e3ae6 Merge branch 'master' into asset-experiments 2014-12-09 11:10:35 +01:00
677c716c0f Fix two very stupid bugs! 2014-12-08 19:21:39 +01:00
e28fb66186 More sorting fixes and tweaks (things should work rather OK now). 2014-12-08 18:51:38 +01:00
da7f20e385 Merge branch 'master' into asset-experiments 2014-12-08 17:37:49 +01:00
6b07e8e31d Take IDTypes into account when sorting by types.
Also:
* Changed BLO_library_path_explode, now r_group and r_name must be pointers of char pointer,
  if found they will point to right place in r_dir 'memspace'.
* Select everything in IDTypes filtering by default.
2014-12-08 16:40:43 +01:00
ffb0fc35a9 Get rid of BLO_is_a_library. 2014-12-08 13:59:32 +01:00
4e96fe77b1 Add ID-types filtering. 2014-12-08 12:45:54 +01:00
337d7b2a6a Merge branch 'master' into asset-experiments 2014-12-08 10:56:15 +01:00
f92e64f207 Merge branch 'master' into asset-experiments 2014-12-06 18:12:09 +01:00
5eaa8739c5 Moar fixes (re ;ostly filtering mixed lib/data and regular files). 2014-12-06 18:10:59 +01:00
c689af14d8 Make 'append/link' code handle data from several different sources at once.
Nothing really magic here, just grouping the imports by libfile/grouptype.
We could probably get better code (loop less on given list of 'files' to import)
but not sure it'd be worth it, this is not supposed to be a performance-critical point.
2014-12-06 18:05:54 +01:00
951dbff60e Moar fixes to sorting code and such. 2014-12-06 15:40:00 +01:00
53148b5ebc Some flatmode fixes:
* Delete filelist when changing flat setting (so that we get immediate update when changing that setting).
* Disable flat when going up in tree (we ;ight actually want to do this everytime).
2014-12-06 14:50:03 +01:00
429cc6072f Merge branch 'master' into asset-experiments 2014-12-06 12:57:54 +01:00
b3e2cbac79 Merge branch 'master' into asset-experiments 2014-12-05 16:47:05 +01:00
9939e783a9 Reworked 'flat' mode, added it outside of blendfiles (libraries).
Note this is WIP, it 'breaks' load/append/etc. operators to some points,
and many other 'details' that need to be addressed.
2014-12-05 16:43:57 +01:00
276286aa85 Merge branch 'master' into asset-experiments 2014-12-05 12:45:31 +01:00
5ceec532b7 Merge branch 'master' into asset-experiments 2014-12-04 18:46:11 +01:00
9ea42ae3ba Add basic 'glob' filter by name feature.
Not much to add, we'll likely add more filtering options (tags, categories...) later,
maybe for now we just need an 'exclude' option for name filter...
2014-12-04 18:43:17 +01:00
f8f82821ef Refactor: do not filter each item twice! Mem usage here is not really an issue anyway. 2014-12-04 17:45:55 +01:00
d9b4186e6e Refactor filtering code, should be easier to add new filter options now. 2014-12-04 17:30:51 +01:00
c728f537ae Fix issues when data name have slash inside.
Adding `BLO_library_path_explode` simplies things. We might end getting rid of
`BLO_is_a_library` (or rather, merge back both things) later, though.
2014-12-04 16:51:46 +01:00
1089d97f04 Fix stupid mistake preventing 'traditional' append/link 2014-12-04 15:23:56 +01:00
d00d1d5622 Cleanup: more. 2014-12-04 15:03:33 +01:00
f02bc0cda8 Cleanup, remove tons of debug prints 2014-12-04 14:53:55 +01:00
b65d8de56a Add icons to datatypes (IDs) in browser, when appending/linking.
Not yet previews, but still better than anonymous icon!
2014-12-04 14:48:56 +01:00
158e6fd7f3 Merge branch 'master' into asset-experiments 2014-12-04 11:19:31 +01:00
ff1ff9823d Merge branch 'master' into asset-experiments 2014-12-04 11:11:33 +01:00
ca70271876 Append/link from 'global' level works.
Note I had to implement 'relative' path handling for 'filenames' in
append/link op, we may want to do this a bit differently later?
2014-12-03 18:55:07 +01:00
b29258922f Fix name issue (stupid really), show them better in UI. 2014-12-03 16:39:05 +01:00
99a1f8172b Do not shoz/consider at all inner '..'
Also more debug code that'll need to be cleaned up
2014-12-03 16:07:28 +01:00
74ae847cfa First (awful) tests to get a whole blend file content shown flat
Main goal is to see whether we can use existing filelist to handle that
(by default it is 100% tree-oriented).

Also, getting some strange issues with ID name currently...
2014-12-03 15:29:18 +01:00
66 changed files with 4866 additions and 422 deletions

View File

@@ -642,6 +642,10 @@ class RenderEngine(StructRNA, metaclass=RNAMeta):
__slots__ = ()
class AssetEngine(StructRNA, metaclass=RNAMeta):
__slots__ = ()
class KeyingSetInfo(StructRNA, metaclass=RNAMeta):
__slots__ = ()

View File

@@ -51,6 +51,8 @@ _modules = [
"wm",
]
_modules.append("amber")
import bpy
if bpy.app.build_options.freestyle:

View File

@@ -0,0 +1,718 @@
# ##### 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# Note: This will be a simple addon later, but until it gets to master, it's simpler to have it
# as a startup module!
import bpy
from bpy.types import (
AssetEngine,
Panel,
PropertyGroup,
UIList,
)
from bpy.props import (
StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
EnumProperty,
CollectionProperty,
)
import binascii
import concurrent.futures as futures
import hashlib
import json
import os
import stat
import struct
import time
AMBER_DB_NAME = "__amber_db.json"
AMBER_DBK_VERSION = "version"
##########
# Helpers.
# Notes about UUIDs:
# * UUID of an asset/variant/revision is computed once at its creation! Later changes to data do not affect it.
# * Collision, for unlikely it is, may happen across different repositories...
# Doubt this will be practical issue though.
# * We keep eight first bytes of 'clear' identifier, to (try to) keep some readable uuid.
def _uuid_gen_single(used_uuids, uuid_root, h, str_arg):
h.update(str_arg.encode())
uuid = uuid_root + h.digest()
uuid = uuid[:23].replace(b'\0', b'\1') # No null chars, RNA 'bytes' use them as in regular strings... :/
if uuid not in used_uuids: # *Very* likely, but...
used_uuids.add(uuid)
return uuid
return None
def _uuid_gen(used_uuids, uuid_root, bytes_seed, *str_args):
h = hashlib.md5(bytes_seed)
for arg in str_args:
uuid = _uuid_gen_single(used_uuids, uuid_root, h, arg)
if uuid is not None:
return uuid
# This is a fallback in case we'd get a collision... Should never be needed in real life!
for i in range(100000):
uuid = _uuid_gen_single(used_uuids, uuid_root, h, i.to_bytes(4, 'little'))
if uuid is not None:
return uuid
return None # If this happens...
def uuid_asset_gen(used_uuids, path_db, name, tags):
uuid_root = name.encode()[:8] + b'|'
return _uuid_gen_single(used_uuids, uuid_root, path_db.encode(), name, *tags)
def uuid_variant_gen(used_uuids, asset_uuid, name):
uuid_root = name.encode()[:8] + b'|'
return _uuid_gen_single(used_uuids, uuid_root, asset_uuid, name)
def uuid_revision_gen(used_uuids, variant_uuid, number, size, time):
uuid_root = str(number).encode() + b'|'
return _uuid_gen_single(used_uuids, uuid_root, variant_uuid, str(number), str(size), str(timestamp))
def uuid_unpack_bytes(uuid_bytes):
return struct.unpack("!iiii", uuid_bytes.ljust(16, b'\0'))
def uuid_unpack(uuid_hexstr):
return uuid_unpack_bytes(binascii.unhexlify(uuid_hexstr))
def uuid_unpack_asset(uuid_repo_hexstr, uuid_asset_hexstr):
return uuid_unpack_bytes(binascii.unhexlify(uuid_repo_hexstr).ljust(8, b'\0') +
binascii.unhexlify(uuid_asset_hexstr).ljust(8, b'\0'))
def uuid_pack(uuid_iv4):
print(uuid_iv4)
return binascii.hexlify(struct.pack("!iiii", *uuid_iv4))
# XXX Hack, once this becomes a real addon we'll just use addons' config system, for now store that in some own config.
amber_repos_path = os.path.join(bpy.utils.user_resource('CONFIG', create=True), "amber_repos.json")
amber_repos = None
if not os.path.exists(amber_repos_path):
with open(amber_repos_path, 'w') as ar_f:
json.dump({}, ar_f)
with open(amber_repos_path, 'r') as ar_f:
amber_repos = {uuid_unpack(uuid): path for uuid, path in json.load(ar_f).items()}
assert(amber_repos != None)
def save_amber_repos():
ar = {uuid_pack(uuid).decode(): path for uuid, path in amber_repos.items()}
with open(amber_repos_path, 'w') as ar_f:
json.dump(ar, ar_f)
#############
# Amber Jobs.
class AmberJob:
def __init__(self, executor, job_id):
self.executor = executor
self.job_id = job_id
self.status = {'VALID'}
self.progress = 0.0
class AmberJobList(AmberJob):
@staticmethod
def ls_repo(db_path):
repo = None
with open(db_path, 'r') as db_f:
repo = json.load(db_f)
if isinstance(repo, dict):
repo_ver = repo.get(AMBER_DBK_VERSION, "")
if repo_ver != "1.0.1":
# Unsupported...
print("WARNING: unsupported Amber repository version '%s'." % repo_ver)
repo = None
else:
repo = None
if repo is not None:
# Convert hexa string to array of four uint32...
# XXX will have to check endianess mess here, for now always use same one ('network' one).
repo_uuid = repo["uuid"]
repo["uuid"] = uuid_unpack(repo_uuid)
new_entries = {}
for euuid, e in repo["entries"].items():
new_variants = {}
for vuuid, v in e["variants"].items():
new_revisions = {}
for ruuid, r in v["revisions"].items():
new_revisions[uuid_unpack(ruuid)] = r
new_variants[uuid_unpack(vuuid)] = v
v["revisions"] = new_revisions
ruuid = v["revision_default"]
v["revision_default"] = uuid_unpack(ruuid)
new_entries[uuid_unpack_asset(repo_uuid, euuid)] = e
e["variants"] = new_variants
vuuid = e["variant_default"]
e["variant_default"] = uuid_unpack(vuuid)
repo["entries"] = new_entries
#~ print(repo)
return repo
@staticmethod
def ls(path):
repo = None
ret = [".."]
tmp = os.listdir(path)
if AMBER_DB_NAME in tmp:
# That dir is an Amber repo, we only list content define by our amber 'db'.
repo = AmberJobList.ls_repo(os.path.join(path, AMBER_DB_NAME))
if repo is None:
ret += tmp
#~ time.sleep(0.1) # 100% Artificial Lag (c)
return ret, repo
@staticmethod
def stat(root, path):
st = os.lstat(root + path)
#~ time.sleep(0.1) # 100% Artificial Lag (c)
return path, (stat.S_ISDIR(st.st_mode), st.st_size, st.st_mtime)
def start(self):
self.nbr = 0
self.tot = 0
self.ls_task = self.executor.submit(self.ls, self.root)
self.status = {'VALID', 'RUNNING'}
def update(self, repository, dirs):
self.status = {'VALID', 'RUNNING'}
if self.ls_task is not None:
if not self.ls_task.done():
return
paths, repo = self.ls_task.result()
self.ls_task = None
self.tot = len(paths)
repository.clear()
dirs.clear()
if repo is not None:
repository.update(repo)
for p in paths:
self.stat_tasks.add(self.executor.submit(self.stat, self.root, p))
done = set()
for tsk in self.stat_tasks:
if tsk.done():
path, (is_dir, size, timestamp) = tsk.result()
self.nbr += 1
if is_dir:
# We only list dirs from real file system.
uuid = uuid_unpack_bytes((path.encode()[:8] + b"|" + self.nbr.to_bytes(4, 'little')))
dirs.append((path, size, timestamp, uuid))
done.add(tsk)
self.stat_tasks -= done
self.progress = self.nbr / self.tot
if not self.stat_tasks and self.ls_task is None:
self.status = {'VALID'}
def __init__(self, executor, job_id, root):
super().__init__(executor, job_id)
self.root = root
self.ls_task = None
self.stat_tasks = set()
self.start()
def __del__(self):
# Avoid useless work!
if self.ls_task is not None:
self.ls_task.cancel()
for tsk in self.stat_tasks:
tsk.cancel()
###########################
# Main Asset Engine class.
class AmberTag(PropertyGroup):
name = StringProperty(name="Name", description="Tag name")
priority = IntProperty(name="Priority", default=0, description="Tag priority")
def include_update(self, context):
if self.use_include:
self.use_exclude = False
context.space_data.asset_engine.is_dirty_filtering = True
use_include = BoolProperty(name="Include", default=False, description="This tag must exist in filtered items",
update=include_update)
def exclude_update(self, context):
if self.use_exclude:
self.use_include = False
context.space_data.asset_engine.is_dirty_filtering = True
use_exclude = BoolProperty(name="Exclude", default=False, description="This tag must not exist in filtered items",
update=exclude_update)
class AssetEngineAmber(AssetEngine):
bl_label = "Amber"
bl_version = (0 << 16) + (0 << 8) + 4 # Usual maj.min.rev version scheme...
tags = CollectionProperty(name="Tags", type=AmberTag, description="Filtering tags")
active_tag_index = IntProperty(name="Active Tag", options={'HIDDEN'})
def __init__(self):
self.executor = futures.ThreadPoolExecutor(8) # Using threads for now, if issues arise we'll switch to process.
self.jobs = {}
self.repos = {}
self.reset()
self.job_uuid = 1
def __del__(self):
# XXX This errors, saying self has no executor attribute... Suspect some py/RNA funky game. :/
# Even though it does not seem to be an issue, this is not nice and shall be fixed somehow.
# XXX This is still erroring... Looks like we should rather have a 'remove' callback or so. :|
#~ executor = getattr(self, "executor", None)
#~ if executor is not None:
#~ executor.shutdown(wait=False)
pass
########## Various helpers ##########
def reset(self):
print("Amber Reset!")
self.root = ""
self.repo = {}
self.dirs = []
self.sortedfiltered = []
def entry_from_uuid(self, entries, euuid, vuuid, ruuid):
e = self.repo["entries"][euuid]
entry = entries.entries.add()
entry.uuid = euuid
entry.name = e["name"]
entry.description = e["description"]
entry.type = {e["file_type"]}
entry.blender_type = e["blen_type"]
act_rev = None
if vuuid == (0, 0, 0, 0):
for vuuid, v in e["variants"].items():
variant = entry.variants.add()
variant.uuid = vuuid
variant.name = v["name"]
variant.description = v["description"]
if vuuid == e["variant_default"]:
entry.variants.active = variant
for ruuid, r in v["revisions"].items():
revision = variant.revisions.add()
revision.uuid = ruuid
#~ revision.comment = r["comment"]
revision.size = r["size"]
revision.timestamp = r["timestamp"]
if ruuid == v["revision_default"]:
variant.revisions.active = revision
if vuuid == e["variant_default"]:
act_rev = r
else:
v = e["variants"][vuuid]
variant = entry.variants.add()
variant.uuid = vuuid
variant.name = v["name"]
variant.description = v["description"]
entry.variants.active = variant
if ruuid == (0, 0, 0, 0):
for ruuid, r in v["revisions"].items():
revision = variant.revisions.add()
revision.uuid = ruuid
#~ revision.comment = r["comment"]
revision.size = r["size"]
revision.timestamp = r["timestamp"]
if ruuid == v["revision_default"]:
variant.revisions.active = revision
act_rev = r
else:
r = v["revisions"][ruuid]
revision = variant.revisions.add()
revision.uuid = ruuid
#~ revision.comment = r["comment"]
revision.size = r["size"]
revision.timestamp = r["timestamp"]
variant.revisions.active = revision
act_rev = r
if act_rev:
entry.relpath = act_rev["path"]
# print("added entry for", entry.relpath)
def pretty_version(self, v=None):
if v is None:
v = self.bl_version
return "%d.%d.%d" % ((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF)
########## PY-API only ##########
# UI header
def draw_header(self, layout, context):
st = context.space_data
params = st.params
# can be None when save/reload with a file selector open
if params:
is_lib_browser = params.use_library_browsing
layout.prop(params, "display_type", expand=True, text="")
layout.prop(params, "sort_method", expand=True, text="")
layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN')
layout.prop(params, "use_filter", text="", icon='FILTER')
row = layout.row(align=True)
row.active = params.use_filter
if params.filter_glob:
#if st.active_operator and hasattr(st.active_operator, "filter_glob"):
# row.prop(params, "filter_glob", text="")
row.label(params.filter_glob)
else:
row.prop(params, "use_filter_blender", text="")
row.prop(params, "use_filter_backup", text="")
row.prop(params, "use_filter_image", text="")
row.prop(params, "use_filter_movie", text="")
row.prop(params, "use_filter_script", text="")
row.prop(params, "use_filter_font", text="")
row.prop(params, "use_filter_sound", text="")
row.prop(params, "use_filter_text", text="")
if is_lib_browser:
row.prop(params, "use_filter_blendid", text="")
if (params.use_filter_blendid) :
row.separator()
row.prop(params, "filter_id_category", text="")
row.separator()
row.prop(params, "filter_search", text="", icon='VIEWZOOM')
########## C (RNA) API ##########
def status(self, job_id):
if job_id:
job = self.jobs.get(job_id, None)
return job.status if job is not None else set()
return {'VALID'}
def progress(self, job_id):
if job_id:
job = self.jobs.get(job_id, None)
return job.progress if job is not None else 0.0
progress = 0.0
nbr_jobs = 0
for job in self.jobs.values():
if 'RUNNING' in job.status:
nbr_jobs += 1
progress += job.progress
return progress / nbr_jobs if nbr_jobs else 0.0
def kill(self, job_id):
if job_id:
self.jobs.pop(job_id, None)
return
self.jobs.clear()
def list_dir(self, job_id, entries):
job = self.jobs.get(job_id, None)
#~ print(entries.root_path, job_id, job)
if job is not None and isinstance(job, AmberJobList):
if job.root != entries.root_path:
self.reset()
self.jobs[job_id] = AmberJobList(self.executor, job_id, entries.root_path)
self.root = entries.root_path
else:
job.update(self.repo, self.dirs)
elif self.root != entries.root_path:
self.reset()
job_id = self.job_uuid
self.job_uuid += 1
self.jobs[job_id] = AmberJobList(self.executor, job_id, entries.root_path)
self.root = entries.root_path
if self.repo:
uuid_repo = self.repo["uuid"]
if amber_repos.get(uuid_repo, None) != self.root:
amber_repos[uuid_repo] = self.root # XXX Not resistant to uuids collisions (use a set instead)...
save_amber_repos()
self.repos[uuid_repo] = self.repo
entries.nbr_entries = len(self.repo["entries"])
valid_tags = set()
for name, prio in sorted(self.repo["tags"].items(), key=lambda i: i[1], reverse=True):
tag = self.tags.get(name)
if tag is None:
tag = self.tags.add()
tag.name = name
tag.priority = prio
valid_tags.add(name)
for name in (set(self.tags.keys()) - valid_tags):
del self.tags[name]
else:
entries.nbr_entries = len(self.dirs)
self.tags.clear()
return job_id
def update_check(self, job_id, uuids):
# do nothing for now, no need to use actual job...
if uuids.asset_engine_version != self.bl_version:
print("Updating asset uuids from Amber v.%s to amber v.%s" %
(self.pretty_version(uuids.asset_engine_version), self.pretty_version()))
for uuid in uuids.uuids:
repo_uuid = uuid.uuid_asset[:2] + (0, 0)
if repo_uuid not in amber_repos or not os.path.exists(os.path.join(amber_repos[repo_uuid], AMBER_DB_NAME)):
uuid.is_asset_missing = True
continue
# Here in theory here we'd reload given repo (async process) and check for asset's status...
uuid.use_asset_reload = True
return self.job_id_invalid
def load_pre(self, uuids, entries):
# Not quite sure this engine will need it in the end, but for sake of testing...
if uuids.asset_engine_version != self.bl_version:
print("Updating asset uuids from Amber v.%s to amber v.%s" %
(self.pretty_version(uuids.asset_engine_version), self.pretty_version()))
# print(entries.entries[:])
for uuid in uuids.uuids:
repo_uuid = tuple(uuid.uuid_asset)[:2] + (0, 0)
assert(repo_uuid in amber_repos)
repo = self.repos.get(repo_uuid, None)
if repo is None:
repo = self.repos[repo_uuid] = AmberJobList.ls_repo(os.path.join(amber_repos[repo_uuid], AMBER_DB_NAME))
euuid = tuple(uuid.uuid_asset)
vuuid = tuple(uuid.uuid_variant)
ruuid = tuple(uuid.uuid_revision)
e = repo["entries"][euuid]
v = e["variants"][vuuid]
r = v["revisions"][ruuid]
entry = entries.entries.add()
entry.type = {e["file_type"]}
entry.blender_type = e["blen_type"]
# archive part not yet implemented!
entry.relpath = os.path.join(amber_repos[repo_uuid], r["path"])
# print("added entry for", entry.relpath)
entry.uuid = euuid
var = entry.variants.add()
var.uuid = vuuid
rev = var.revisions.add()
rev.uuid = ruuid
var.revisions.active = rev
entry.variants.active = var
entries.root_path = ""
return True
def check_dir(self, entries):
# Stupid code just for test...
#~ entries.root_path = entries.root_path + "../"
#~ print(entries.root_path)
pass
def sort_filter(self, use_sort, use_filter, params, entries):
# print(use_sort, use_filter)
if use_filter:
filter_search = params.filter_search
self.sortedfiltered.clear()
if self.repo:
if params.use_filter:
file_type = set()
blen_type = set()
tags_incl = {t.name for t in self.tags if t.use_include}
tags_excl = {t.name for t in self.tags if t.use_exclude}
if params.use_filter_image:
file_type.add('IMAGE')
if params.use_filter_blender:
file_type.add('BLENDER')
if params.use_filter_backup:
file_type.add('BACKUP')
if params.use_filter_movie:
file_type.add('MOVIE')
if params.use_filter_script:
file_type.add('SCRIPT')
if params.use_filter_font:
file_type.add('FONT')
if params.use_filter_sound:
file_type.add('SOUND')
if params.use_filter_text:
file_type.add('TEXT')
if params.use_filter_blendid and params.use_library_browsing:
file_type.add('BLENLIB')
blen_type = params.filter_id
for key, val in self.repo["entries"].items():
if filter_search and filter_search not in (val["name"] + val["description"]):
continue
if params.use_filter:
if val["file_type"] not in file_type:
continue
if params.use_library_browsing and val["blen_type"] not in blen_type:
continue
if tags_incl or tags_excl:
tags = set(val["tags"])
if tags_incl and ((tags_incl & tags) != tags_incl):
continue
if tags_excl and (tags_excl & tags):
continue
self.sortedfiltered.append((key, val))
elif self.dirs:
for path, size, timestamp, uuid in self.dirs:
if filter_search and filter_search not in path:
continue
if not params.show_hidden and path.startswith(".") and not path.startswith(".."):
continue
self.sortedfiltered.append((path, size, timestamp, uuid))
use_sort = True
entries.nbr_entries_filtered = len(self.sortedfiltered) + (1 if self.repo else 0)
if use_sort:
if self.repo:
if params.sort_method == 'FILE_SORT_TIME':
self.sortedfiltered.sort(key=lambda e: e[1]["variants"][e[1]["variant_default"]]["revisions"][e[1]["variants"][e[1]["variant_default"]]["revision_default"]]["timestamp"])
elif params.sort_method == 'FILE_SORT_SIZE':
self.sortedfiltered.sort(key=lambda e: e[1]["variants"][e[1]["variant_default"]]["revisions"][e[1]["variants"][e[1]["variant_default"]]["revision_default"]]["size"])
elif params.sort_method == 'FILE_SORT_EXTENSION':
self.sortedfiltered.sort(key=lambda e: e[1]["blen_type"])
else:
self.sortedfiltered.sort(key=lambda e: e[1]["name"].lower())
else:
if params.sort_method == 'FILE_SORT_TIME':
self.sortedfiltered.sort(key=lambda e: e[2])
elif params.sort_method == 'FILE_SORT_SIZE':
self.sortedfiltered.sort(key=lambda e: e[1])
else:
self.sortedfiltered.sort(key=lambda e: e[0].lower())
return True
return False
def entries_block_get(self, start_index, end_index, entries):
# print(entries.entries[:])
if self.repo:
if start_index == 0:
entry = entries.entries.add()
entry.type = {'DIR'}
entry.relpath = '..'
variant = entry.variants.add()
entry.variants.active = variant
rev = variant.revisions.add()
variant.revisions.active = rev
else:
start_index -= 1
end_index -= 1
#~ print("self repo", len(self.sortedfiltered), start_index, end_index)
for euuid, e in self.sortedfiltered[start_index:end_index]:
self.entry_from_uuid(entries, euuid, (0, 0, 0, 0), (0, 0, 0, 0))
else:
#~ print("self dirs", len(self.sortedfiltered), start_index, end_index)
for path, size, timestamp, uuid in self.sortedfiltered[start_index:end_index]:
entry = entries.entries.add()
entry.type = {'DIR'}
entry.relpath = path
# print("added entry for", entry.relpath)
entry.uuid = uuid
variant = entry.variants.add()
entry.variants.active = variant
rev = variant.revisions.add()
rev.size = size
rev.timestamp = timestamp
variant.revisions.active = rev
return True
def entries_uuid_get(self, uuids, entries):
# print(entries.entries[:])
if self.repo:
for uuid in uuids.uuids:
self.entry_from_uuid(entries, tuple(uuid.uuid_asset), tuple(uuid.uuid_variant), tuple(uuid.uuid_revision))
return True
return False
##########
# UI stuff
class AMBER_UL_tags_filter(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.AmberTag))
ae_amber = data
tag = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
split = layout.split(0.66, False)
split.prop(tag, "name", text="", emboss=False, icon_value=icon)
row = split.row(align=True)
sub = row.row(align=True)
sub.active = tag.use_include
sub.prop(tag, "use_include", emboss=False, text="", icon='ZOOMIN')
sub = row.row(align=True)
sub.active = tag.use_exclude
sub.prop(tag, "use_exclude", emboss=False, text="", icon='ZOOMOUT')
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class AmberPanel():
@classmethod
def poll(cls, context):
space = context.space_data
if space and space.type == 'FILE_BROWSER':
ae = space.asset_engine
if ae and space.asset_engine_type == "AssetEngineAmber":
return True
return False
class AMBER_PT_options(Panel, AmberPanel):
bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOLS'
bl_category = "Asset Engine"
bl_label = "Amber Options"
def draw(self, context):
layout = self.layout
space = context.space_data
ae = space.asset_engine
row = layout.row()
class AMBER_PT_tags(Panel, AmberPanel):
bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOLS'
bl_category = "Filter"
bl_label = "Tags"
def draw(self, context):
ae = context.space_data.asset_engine
# Note: This is *ultra-primitive*!
# A good UI will most likely need new widget option anyway (template). Or maybe just some UIList...
#~ self.layout.props_enum(ae, "tags")
self.layout.template_list("AMBER_UL_tags_filter", "", ae, "tags", ae, "active_tag_index")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -28,11 +28,16 @@ class FILEBROWSER_HT_header(Header):
layout = self.layout
st = context.space_data
params = st.params
is_lib_browser = params and params.use_library_browsing
layout.template_header()
layout.separator()
row = layout.row()
row.separator()
if is_lib_browser:
row = layout.row()
row.prop(st, "asset_engine_type", text="")
layout.separator()
row = layout.row(align=True)
row.operator("file.previous", text="", icon='BACK')
@@ -41,55 +46,57 @@ class FILEBROWSER_HT_header(Header):
row.operator("file.refresh", text="", icon='FILE_REFRESH')
layout.separator()
layout.operator_context = 'EXEC_DEFAULT'
layout.operator("file.directory_new", icon='NEWFOLDER', text="")
layout.separator()
if st.asset_engine and is_lib_browser:
draw_header = getattr(st.asset_engine, "draw_header", None)
if draw_header:
draw_header(layout, context)
else:
layout.operator_context = 'EXEC_DEFAULT'
layout.operator("file.directory_new", icon='NEWFOLDER', text="")
layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
params = st.params
layout.operator_context = 'INVOKE_DEFAULT'
# can be None when save/reload with a file selector open
if params:
is_lib_browser = params.use_library_browsing
# can be None when save/reload with a file selector open
if params:
layout.prop(params, "recursion_level", text="")
layout.prop(params, "recursion_level", text="")
layout.prop(params, "display_type", expand=True, text="")
layout.prop(params, "display_type", expand=True, text="")
layout.prop(params, "display_size", text="")
layout.prop(params, "display_size", text="")
layout.prop(params, "sort_method", expand=True, text="")
layout.prop(params, "sort_method", expand=True, text="")
layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN')
layout.prop(params, "use_filter", text="", icon='FILTER')
layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN')
layout.prop(params, "use_filter", text="", icon='FILTER')
row = layout.row(align=True)
row.active = params.use_filter
row = layout.row(align=True)
row.active = params.use_filter
row.prop(params, "use_filter_folder", text="")
row.prop(params, "use_filter_folder", text="")
if params.filter_glob:
# if st.active_operator and hasattr(st.active_operator, "filter_glob"):
# row.prop(params, "filter_glob", text="")
row.label(params.filter_glob)
else:
row.prop(params, "use_filter_blender", text="")
row.prop(params, "use_filter_backup", text="")
row.prop(params, "use_filter_image", text="")
row.prop(params, "use_filter_movie", text="")
row.prop(params, "use_filter_script", text="")
row.prop(params, "use_filter_font", text="")
row.prop(params, "use_filter_sound", text="")
row.prop(params, "use_filter_text", text="")
if params.filter_glob:
# if st.active_operator and hasattr(st.active_operator, "filter_glob"):
# row.prop(params, "filter_glob", text="")
row.label(params.filter_glob)
else:
row.prop(params, "use_filter_blender", text="")
row.prop(params, "use_filter_backup", text="")
row.prop(params, "use_filter_image", text="")
row.prop(params, "use_filter_movie", text="")
row.prop(params, "use_filter_script", text="")
row.prop(params, "use_filter_font", text="")
row.prop(params, "use_filter_sound", text="")
row.prop(params, "use_filter_text", text="")
if is_lib_browser:
row.prop(params, "use_filter_blendid", text="")
if params.use_filter_blendid:
row.separator()
row.prop(params, "filter_id_category", text="")
if is_lib_browser:
row.prop(params, "use_filter_blendid", text="")
if params.use_filter_blendid:
row.separator()
row.prop(params, "filter_id_category", text="")
row.separator()
row.prop(params, "filter_search", text="", icon='VIEWZOOM')
row.separator()
row.prop(params, "filter_search", text="", icon='VIEWZOOM')
layout.template_running_jobs()

View File

@@ -68,6 +68,16 @@ class INFO_HT_header(Header):
row.label(bpy.app.autoexec_fail_message)
return
if (bpy.app.assets_fail or bpy.app.assets_need_reload) and not bpy.app.assets_quiet:
row.operator("script.assets_warn_clear", text="Ignore")
if bpy.app.assets_need_reload is True and bpy.app.assets_quiet is False:
#~ row.label(icon='SCREEN_BACK', text="Reload Assets")
row.operator("wm.assets_reload", icon='SCREEN_BACK', text="Reload Assets")
row.label("Some assets have to be reloaded", icon='INFO')
if bpy.app.assets_fail is True and bpy.app.assets_quiet is False:
row.label("Some asset engine(s) failed to retrieve updated data about their assets...", icon='ERROR')
return
row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
row.label(text=scene.statistics(), translate=False)

View File

@@ -0,0 +1,246 @@
/*
* ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BKE_asset_engine.h
* \ingroup bke
*/
#ifndef __BKE_ASSET_ENGINE_H__
#define __BKE_ASSET_ENGINE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "DNA_space_types.h"
struct AssetEngine;
struct AssetEngineType;
struct AssetUUIDList;
struct FileDirEntryArr;
struct FileDirEntry;
struct FileDirEntryVariant;
struct FileDirEntryRevision;
struct ExtensionRNA;
struct ID;
struct IDProperty;
struct ListBase;
struct Main;
struct ReportList;
struct uiLayout;
enum {
AE_STATUS_VALID = 1 << 0, /* Asset engine is "OK" (if unset engine won't be used). */
AE_STATUS_RUNNING = 1 << 1, /* Asset engine is performing some background tasks... */
};
#define AE_FAKE_ENGINE_ID "NONE"
extern ListBase asset_engines;
/* AE instance/job is valid, is running, is idle, etc. */
typedef int (*ae_status)(struct AssetEngine *engine, const int job_id);
/* Report progress ([0.0, 1.0] range) of given job. */
typedef float (*ae_progress)(struct AssetEngine *engine, const int job_id);
/* To force end of given job (e.g. because it was cancelled by user...). */
typedef void (*ae_kill)(struct AssetEngine *engine, const int job_id);
/* ***** All callbacks below shall be non-blocking (i.e. return immediately). ***** */
/* Those callbacks will be called from a 'fake-job' start *and* update functions (i.e. main thread, working one will
* just sleep).
*
* If given id is not AE_JOB_ID_UNSET, engine should update from a running job if available, otherwise it should
* start a new one.
* It is the responsability of the engine to start/stop background processes to actually perform tasks as/if needed.
*
* If the engine returns AE_JOB_ID_INVALID as job id, then code assumes whole execution was done in that single first
* call (i.e. allows engine that do not need it to not bother with whole async crap - they should then process
* the whole request in a very short amount of time (typically below 100ms).
*/
#define AE_JOB_ID_UNSET 0
#define AE_JOB_ID_INVALID -1
/* FILEBROWSER - List everything available at given root path - only returns numbers of entries! */
typedef int (*ae_list_dir)(struct AssetEngine *engine, const int job_id, struct FileDirEntryArr *entries_r);
/* 'update' hook, called to prepare updating of given entries (typically after a file (re)load).
* Engine should check whether given assets are still valid, if they should be updated, etc.
* uuids tagged as needing reload will then be reloaded as new ones
* (ae_load_pre, then actual lib loading, then ae_load_post).
* \warning This callback is expected to handle **real** UUIDS (not 'users' filebrowser ones),
* i.e. calling ae_load_pre with those shall **not** alters them in returned direntries
* (else 'link' between old IDs and reloaded ones would be broken). */
typedef int (*ae_update_check)(struct AssetEngine *engine, const int job_id, struct AssetUUIDList *uuids);
/* Ensure given assets (uuids) are really available for append/link (some kind of 'anticipated loading'...).
* Note: Engine should expect any kind of UUIDs it produced here
* (i.e. real ones as well as 'virtual' filebrowsing ones). */
typedef int (*ae_ensure_uuids)(struct AssetEngine *engine, const int job_id, struct AssetUUIDList *uuids);
/* ***** All callbacks below are blocking. They shall be completed upon return. ***** */
/* FILEBROWSER - Perform sorting and/or filtering on engines' side.
* Note that engine is assumed to feature its own sorting/filtering settings!
* Number of available filtered entries is to be set in entries_r.
*/
typedef bool (*ae_sort_filter)(struct AssetEngine *engine, const bool sort, const bool filter,
struct FileSelectParams *params, struct FileDirEntryArr *entries_r);
/* FILEBROWSER - Return specified block of entries in entries_r. */
typedef bool (*ae_entries_block_get)(struct AssetEngine *engine, const int start_index, const int end_index,
struct FileDirEntryArr *entries_r);
/* FILEBROWSER - Return specified entries from their uuids, in entries_r. */
typedef bool (*ae_entries_uuid_get)(struct AssetEngine *engine, struct AssetUUIDList *uuids,
struct FileDirEntryArr *entries_r);
/* 'pre-loading' hook, called before opening/appending/linking/updating given entries.
* Note first given uuid is the one of 'active' entry, and first entry in returned list will be considered as such too.
* E.g. allows the engine to ensure entries' paths are actually valid by downloading requested data, etc.
* If is_virtual is True, then there is no requirement that returned paths actually exist.
* Note that the generated list shall be simpler than the one generated by ae_list_dir, since only the path from
* active revision is used, no need to bother with variants, previews, etc.
* This allows to present 'fake' entries to user, and then import actual data.
*/
typedef bool (*ae_load_pre)(struct AssetEngine *engine, struct AssetUUIDList *uuids,
struct FileDirEntryArr *entries_r);
/* 'post-loading' hook, called after opening/appending/linking/updating given entries.
* E.g. allows an advanced engine to make fancy scripted operations over loaded items. */
/* TODO */
typedef bool (*ae_load_post)(struct AssetEngine *engine, struct ID *items, const int *num_items);
/* Check if given dirpath is valid for current asset engine, it can also modify it.
* r_dir is assumed to be least FILE_MAX. */
typedef void (*ae_check_dir)(struct AssetEngine *engine, char *r_dir);
typedef struct AssetEngineType {
struct AssetEngineType *next, *prev;
/* type info */
char idname[64]; /* best keep the same size as BKE_ST_MAXNAME */
int version;
char name[64];
int flag;
/* API */
ae_status status;
ae_progress progress;
ae_kill kill;
ae_list_dir list_dir;
ae_sort_filter sort_filter;
ae_entries_block_get entries_block_get;
ae_entries_uuid_get entries_uuid_get;
ae_ensure_uuids ensure_uuids;
ae_load_pre load_pre;
ae_load_post load_post;
ae_update_check update_check;
ae_check_dir check_dir;
/* RNA integration */
struct ExtensionRNA ext;
} AssetEngineType;
typedef struct AssetEngine {
AssetEngineType *type;
void *py_instance;
/* Custom sub-classes properties. */
IDProperty *properties;
int flag;
int refcount;
struct ReportList *reports;
} AssetEngine;
/* AssetEngine->flag */
enum {
AE_DIRTY_FILTER = 1 << 0,
AE_DIRTY_SORTING = 1 << 1,
};
/* Engine Types */
void BKE_asset_engines_init(void);
void BKE_asset_engines_exit(void);
AssetEngineType *BKE_asset_engines_find(const char *idname);
AssetEngineType *BKE_asset_engines_get_default(char *r_idname, const size_t len);
/* Engine Instances */
AssetEngine *BKE_asset_engine_create(AssetEngineType *type, struct ReportList *reports);
AssetEngine *BKE_asset_engine_copy(AssetEngine *engine);
void BKE_asset_engine_free(AssetEngine *engine);
struct AssetUUIDList *BKE_asset_engine_entries_load_pre(AssetEngine *engine, struct FileDirEntryArr *r_entries);
struct FileDirEntryArr *BKE_asset_engine_uuids_load_pre(AssetEngine *engine, struct AssetUUIDList *r_uuids);
/* File listing utils... */
typedef enum FileCheckType {
CHECK_NONE = 0,
CHECK_DIRS = 1 << 0,
CHECK_FILES = 1 << 1,
CHECK_ALL = CHECK_DIRS | CHECK_FILES,
} FileCheckType;
void BKE_filedir_revision_free(struct FileDirEntryRevision *rev);
void BKE_filedir_variant_free(struct FileDirEntryVariant *var);
void BKE_filedir_entry_free(struct FileDirEntry *entry);
void BKE_filedir_entry_clear(struct FileDirEntry *entry);
struct FileDirEntry *BKE_filedir_entry_copy(struct FileDirEntry *entry);
void BKE_filedir_entryarr_clear(struct FileDirEntryArr *array);
#define ASSETUUID_SUB_COMPARE(_uuida, _uuidb, _member) \
(memcmp((_uuida)->_member, (_uuidb)->_member, sizeof((_uuida)->_member)) == 0)
#define ASSETUUID_COMPARE(_uuida, _uuidb) \
(ASSETUUID_SUB_COMPARE(_uuida, _uuidb, uuid_asset) && \
ASSETUUID_SUB_COMPARE(_uuida, _uuidb, uuid_variant) && \
ASSETUUID_SUB_COMPARE(_uuida, _uuidb, uuid_revision))
/* Various helpers */
unsigned int BKE_asset_uuid_hash(const void *key);
bool BKE_asset_uuid_cmp(const void *a, const void *b);
void BKE_asset_uuid_print(const struct AssetUUID *uuid);
#ifdef __cplusplus
}
#endif
#endif /* __BKE_ASSET_ENGINE_H__ */

View File

@@ -104,6 +104,10 @@ typedef struct Global {
/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_FACE_SEL) */
#define G_ASSETS_NEED_RELOAD (1 << 10)
#define G_ASSETS_FAIL (1 << 11)
#define G_ASSETS_QUIET (1 << 12)
#define G_SCRIPT_AUTOEXEC (1 << 13)
#define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
#define G_SCRIPT_AUTOEXEC_FAIL (1 << 15)

View File

@@ -38,6 +38,8 @@ extern "C" {
#include "BLI_compiler_attrs.h"
struct AssetEngineType;
struct AssetUUID;
struct BlendThumbnail;
struct ListBase;
struct ID;
@@ -127,6 +129,20 @@ void BKE_library_free(struct Library *lib);
void BKE_library_make_local(
struct Main *bmain, const struct Library *lib, const bool untagged_only, const bool set_fake);
void BKE_library_asset_repository_init(struct Library *lib, const struct AssetEngineType *aet, const char *repo_root);
void BKE_library_asset_repository_clear(struct Library *lib);
void BKE_library_asset_repository_free(struct Library *lib);
struct AssetRef *BKE_library_asset_repository_asset_add(struct Library *lib, const void *idv);
void BKE_library_asset_repository_asset_remove(struct Library *lib, const void *idv);
struct AssetRef *BKE_library_asset_repository_asset_find(struct Library *lib, const void *idv);
void BKE_library_asset_repository_subdata_add(struct AssetRef *aref, const void *idv);
void BKE_library_asset_repository_subdata_remove(struct AssetRef *aref, const void *idv);
void BKE_libraries_asset_subdata_remove(struct Main *bmain, const void *idv);
void BKE_libraries_asset_repositories_clear(struct Main *bmain);
void BKE_libraries_asset_repositories_rebuild(struct Main *bmain);
struct AssetRef *BKE_libraries_asset_repository_uuid_find(struct Main *bmain, const struct AssetUUID *uuid);
struct Library *BKE_library_asset_virtual_ensure(struct Main *bmain, const struct AssetEngineType *aet);
/* use when "" is given to new_id() */
#define ID_FALLBACK_NAME N_("Untitled")

View File

@@ -70,6 +70,7 @@ set(SRC
intern/appdir.c
intern/armature.c
intern/armature_update.c
intern/asset_engine.c
intern/autoexec.c
intern/blender.c
intern/blender_copybuffer.c
@@ -118,6 +119,7 @@ set(SRC
intern/lamp.c
intern/lattice.c
intern/library.c
intern/library_asset.c
intern/library_idmap.c
intern/library_query.c
intern/library_remap.c
@@ -194,6 +196,7 @@ set(SRC
BKE_animsys.h
BKE_appdir.h
BKE_armature.h
BKE_asset_engine.h
BKE_autoexec.h
BKE_blender.h
BKE_blender_copybuffer.h

View File

@@ -696,7 +696,7 @@ void BKE_pose_eval_flush(EvaluationContext *UNUSED(eval_ctx),
void BKE_pose_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
BLI_assert(ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from != NULL);
BLI_assert(ID_IS_LINKED(ob) && ob->proxy_from != NULL);
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
printf("Proxy copy error, lib Object: %s proxy Object: %s\n",

View File

@@ -0,0 +1,428 @@
/*
* ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/asset_engine.c
* \ingroup bke
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_types.h"
#include "BLT_translation.h"
#include "BLI_fileops_types.h"
#include "BLI_hash_mm2a.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "PIL_time.h"
#include "BKE_asset_engine.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "IMB_imbuf.h"
#include "DNA_space_types.h"
#ifdef WITH_PYTHON
#include "BPY_extern.h"
#endif
/* Asset engine types (none intern!). */
ListBase asset_engines = {NULL, NULL};
void BKE_asset_engines_init(void)
{
/* We just add a dummy engine, which 'is' our intern filelisting code from space_file! */
AssetEngineType *aet = MEM_callocN(sizeof(*aet), __func__);
BLI_strncpy(aet->idname, AE_FAKE_ENGINE_ID, sizeof(aet->idname));
BLI_strncpy(aet->name, "None", sizeof(aet->name));
BLI_addhead(&asset_engines, aet);
}
void BKE_asset_engines_exit(void)
{
AssetEngineType *type, *next;
for (type = asset_engines.first; type; type = next) {
next = type->next;
BLI_remlink(&asset_engines, type);
if (type->ext.free) {
type->ext.free(type->ext.data);
}
MEM_freeN(type);
}
}
AssetEngineType *BKE_asset_engines_find(const char *idname)
{
AssetEngineType *type;
type = BLI_findstring(&asset_engines, idname, offsetof(AssetEngineType, idname));
return type;
}
AssetEngineType *BKE_asset_engines_get_default(char *r_idname, const size_t len)
{
AssetEngineType *type = asset_engines.first;
BLI_assert(type);
if (r_idname) {
BLI_strncpy(r_idname, type->idname, len);
}
return type;
}
/* Asset engine instances. */
/* Create, Free */
AssetEngine *BKE_asset_engine_create(AssetEngineType *type, ReportList *reports)
{
AssetEngine *engine;
BLI_assert(type);
engine = MEM_callocN(sizeof(AssetEngine), __func__);
engine->type = type;
engine->refcount = 1;
/* initialize error reports */
if (reports) {
engine->reports = reports; /* must be initialized already */
}
else {
engine->reports = MEM_mallocN(sizeof(ReportList), __func__);
BKE_reports_init(engine->reports, RPT_STORE | RPT_FREE);
}
return engine;
}
/** Shalow copy only (i.e. memory is 100% shared, just increases refcount). */
AssetEngine *BKE_asset_engine_copy(AssetEngine *engine)
{
engine->refcount++;
return engine;
}
void BKE_asset_engine_free(AssetEngine *engine)
{
if (engine->refcount-- == 1) {
#ifdef WITH_PYTHON
if (engine->py_instance) {
BPY_DECREF_RNA_INVALIDATE(engine->py_instance);
}
#endif
if (engine->properties) {
IDP_FreeProperty(engine->properties);
MEM_freeN(engine->properties);
}
if (engine->reports && (engine->reports->flag & RPT_FREE)) {
BKE_reports_clear(engine->reports);
MEM_freeN(engine->reports);
}
MEM_freeN(engine);
}
}
/* API helpers. */
static void asset_engine_load_pre(AssetEngine *engine, AssetUUIDList *r_uuids, FileDirEntryArr *r_entries)
{
FileDirEntry *en;
AssetUUID *uuid;
const int nbr_entries = r_entries->nbr_entries ? r_entries->nbr_entries : r_uuids->nbr_uuids;
if (r_entries->nbr_entries) {
BLI_assert(r_uuids->uuids == NULL);
r_uuids->uuids = MEM_mallocN(sizeof(*r_uuids->uuids) * nbr_entries, __func__);
r_uuids->nbr_uuids = nbr_entries;
r_uuids->asset_engine_version = engine->type->version;
for (en = r_entries->entries.first, uuid = r_uuids->uuids; en; en = en->next, uuid++) {
FileDirEntryVariant *var = BLI_findlink(&en->variants, en->act_variant);
memcpy(uuid->uuid_asset, en->uuid, sizeof(uuid->uuid_asset));
BLI_assert(var);
memcpy(uuid->uuid_variant, var->uuid, sizeof(uuid->uuid_variant));
memcpy(uuid->uuid_revision, en->entry->uuid, sizeof(uuid->uuid_revision));
}
}
BKE_filedir_entryarr_clear(r_entries);
if (!engine->type->load_pre(engine, r_uuids, r_entries)) {
/* If load_pre returns false (i.e. fails), clear all paths! */
/* TODO: report!!! */
BKE_filedir_entryarr_clear(r_entries);
MEM_freeN(r_uuids->uuids);
r_uuids->uuids = NULL;
r_uuids->nbr_uuids = 0;
return;
}
/* load_pre may change things, we have to rebuild our uuids list from returned entries. */
r_entries->nbr_entries = r_uuids->nbr_uuids = BLI_listbase_count(&r_entries->entries);
r_uuids->uuids = MEM_reallocN(r_uuids->uuids, sizeof(*r_uuids->uuids) * r_uuids->nbr_uuids);
for (en = r_entries->entries.first, uuid = r_uuids->uuids; en; en = en->next, uuid++) {
FileDirEntryVariant *var;
FileDirEntryRevision *rev;
memcpy(uuid->uuid_asset, en->uuid, sizeof(uuid->uuid_asset));
var = BLI_findlink(&en->variants, en->act_variant);
BLI_assert(var);
memcpy(uuid->uuid_variant, var->uuid, sizeof(uuid->uuid_variant));
rev = BLI_findlink(&var->revisions, var->act_revision);
BLI_assert(rev);
memcpy(uuid->uuid_revision, rev->uuid, sizeof(uuid->uuid_revision));
}
}
/** Call load_pre for given entries, and return new uuids/entries. */
AssetUUIDList *BKE_asset_engine_entries_load_pre(AssetEngine *engine, FileDirEntryArr *r_entries)
{
AssetUUIDList *uuids = MEM_callocN(sizeof(*uuids), __func__);
asset_engine_load_pre(engine, uuids, r_entries);
return uuids;
}
/** Call load_pre for given uuids, and return new uuids/entries. */
FileDirEntryArr *BKE_asset_engine_uuids_load_pre(AssetEngine *engine, AssetUUIDList *r_uuids)
{
FileDirEntryArr *entries = MEM_callocN(sizeof(*entries), __func__);
asset_engine_load_pre(engine, r_uuids, entries);
return entries;
}
/* FileDirxxx handling. */
void BKE_filedir_revision_free(FileDirEntryRevision *rev)
{
if (rev->comment) {
MEM_freeN(rev->comment);
}
MEM_freeN(rev);
}
void BKE_filedir_variant_free(FileDirEntryVariant *var)
{
if (var->name) {
MEM_freeN(var->name);
}
if (var->description) {
MEM_freeN(var->description);
}
if (!BLI_listbase_is_empty(&var->revisions)) {
FileDirEntryRevision *rev, *rev_next;
for (rev = var->revisions.first; rev; rev = rev_next) {
rev_next = rev->next;
BKE_filedir_revision_free(rev);
}
BLI_listbase_clear(&var->revisions);
}
MEM_freeN(var);
}
void BKE_filedir_entry_clear(FileDirEntry *entry)
{
if (entry->name) {
MEM_freeN(entry->name);
}
if (entry->description) {
MEM_freeN(entry->description);
}
if (entry->relpath) {
MEM_freeN(entry->relpath);
}
if (entry->image) {
IMB_freeImBuf(entry->image);
}
/* For now, consider FileDirEntryRevision::poin as not owned here, so no need to do anything about it */
if (!BLI_listbase_is_empty(&entry->variants)) {
FileDirEntryVariant *var, *var_next;
for (var = entry->variants.first; var; var = var_next) {
var_next = var->next;
BKE_filedir_variant_free(var);
}
BLI_listbase_clear(&entry->variants);
}
else if (entry->entry){
MEM_freeN(entry->entry);
}
memset(entry, 0, sizeof(*entry));
}
void BKE_filedir_entry_free(FileDirEntry *entry)
{
BKE_filedir_entry_clear(entry);
MEM_freeN(entry);
}
/** Perform and return a full (deep) duplicate of given entry. */
FileDirEntry *BKE_filedir_entry_copy(FileDirEntry *entry)
{
FileDirEntry *entry_new = MEM_dupallocN(entry);
if (entry->name) {
entry_new->name = MEM_dupallocN(entry->name);
}
if (entry->description) {
entry_new->description = MEM_dupallocN(entry->description);
}
if (entry->relpath) {
entry_new->relpath = MEM_dupallocN(entry->relpath);
}
if (entry->image) {
entry_new->image = IMB_dupImBuf(entry->image);
}
/* For now, consider FileDirEntryRevision::poin as not owned here, so no need to do anything about it */
entry_new->entry = NULL;
if (!BLI_listbase_is_empty(&entry->variants)) {
FileDirEntryVariant *var;
int act_var;
BLI_listbase_clear(&entry_new->variants);
for (act_var = 0, var = entry->variants.first; var; act_var++, var = var->next) {
FileDirEntryVariant *var_new = MEM_dupallocN(var);
FileDirEntryRevision *rev;
const bool is_act_var = (act_var == entry->act_variant);
int act_rev;
if (var->name) {
var_new->name = MEM_dupallocN(var->name);
}
if (var->description) {
var_new->description = MEM_dupallocN(var->description);
}
BLI_listbase_clear(&var_new->revisions);
for (act_rev = 0, rev = var->revisions.first; rev; act_rev++, rev = rev->next) {
FileDirEntryRevision *rev_new = MEM_dupallocN(rev);
const bool is_act_rev = (act_rev == var->act_revision);
if (rev->comment) {
rev_new->comment = MEM_dupallocN(rev->comment);
}
BLI_addtail(&var_new->revisions, rev_new);
if (is_act_var && is_act_rev) {
entry_new->entry = rev_new;
}
}
BLI_addtail(&entry_new->variants, var_new);
}
}
else if (entry->entry){
entry_new->entry = MEM_dupallocN(entry->entry);
}
BLI_assert(entry_new->entry != NULL);
/* TODO: tags! */
return entry_new;
}
void BKE_filedir_entryarr_clear(FileDirEntryArr *array)
{
FileDirEntry *entry, *entry_next;
for (entry = array->entries.first; entry; entry = entry_next) {
entry_next = entry->next;
BKE_filedir_entry_free(entry);
}
BLI_listbase_clear(&array->entries);
array->nbr_entries = 0;
array->nbr_entries_filtered = 0;
}
/* Various helpers */
unsigned int BKE_asset_uuid_hash(const void *key)
{
return BLI_hash_mm2((const unsigned char *)key, sizeof(AssetUUID), 0);
}
bool BKE_asset_uuid_cmp(const void *a, const void *b)
{
const AssetUUID *uuid1 = a;
const AssetUUID *uuid2 = b;
return !ASSETUUID_COMPARE(uuid1, uuid2); /* Expects false when compared equal... */
}
void BKE_asset_uuid_print(const AssetUUID *uuid)
{
/* TODO print nicer (as 128bit hexadecimal...). */
printf("[%d,%d,%d,%d][%d,%d,%d,%d][%d,%d,%d,%d]\n",
uuid->uuid_asset[0], uuid->uuid_asset[1], uuid->uuid_asset[2], uuid->uuid_asset[3],
uuid->uuid_variant[0], uuid->uuid_variant[1], uuid->uuid_variant[2], uuid->uuid_variant[3],
uuid->uuid_revision[0], uuid->uuid_revision[1], uuid->uuid_revision[2], uuid->uuid_revision[3]);
}

View File

@@ -42,9 +42,12 @@
#include "BLI_utildefines.h"
#include "BLI_callbacks.h"
#include "RNA_access.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
#include "BKE_asset_engine.h"
#include "BKE_blender.h" /* own include */
#include "BKE_blender_version.h" /* own include */
#include "BKE_blendfile.h"
@@ -66,7 +69,6 @@
#include "BLF_api.h"
Global G;
UserDef U;

View File

@@ -424,7 +424,7 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
{
const char *absbase = (flag & BKE_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL;
if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && ID_IS_LINKED_DATABLOCK(id)) {
if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && ID_IS_LINKED(id)) {
return;
}

View File

@@ -225,7 +225,7 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
* - mixed: make copy
*/
if (!ID_IS_LINKED_DATABLOCK(brush)) {
if (!ID_IS_LINKED(brush)) {
return;
}

View File

@@ -4649,7 +4649,7 @@ void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *use
/* helper for BKE_constraints_copy(), to be used for making sure that ID's are valid */
static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, bool UNUSED(is_reference), void *UNUSED(userData))
{
if (*idpoin && ID_IS_LINKED_DATABLOCK(*idpoin))
if (*idpoin && ID_IS_LINKED(*idpoin))
id_lib_extern(*idpoin);
}

View File

@@ -75,6 +75,8 @@
#include "BLI_threads.h"
#include "BLT_translation.h"
#include "RNA_access.h"
#include "BKE_action.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
@@ -116,8 +118,6 @@
#include "DEG_depsgraph.h"
#include "RNA_access.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -134,6 +134,10 @@
* also note that the id _must_ have a library - campbell */
void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
{
if (lib->flag & LIBRARY_FLAG_VIRTUAL) {
return;
}
const char *bpath_user_data[2] = {bmain->name, lib->filepath};
BKE_bpath_traverse_id(bmain, id,
@@ -144,7 +148,7 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id)
void id_lib_extern(ID *id)
{
if (id && ID_IS_LINKED_DATABLOCK(id)) {
if (id && ID_IS_LINKED(id)) {
BLI_assert(BKE_idcode_is_linkable(GS(id->name)));
if (id->tag & LIB_TAG_INDIRECT) {
id->tag -= LIB_TAG_INDIRECT;
@@ -276,7 +280,7 @@ void BKE_id_expand_local(ID *id)
*/
void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id)
{
if (ID_IS_LINKED_DATABLOCK(old_id)) {
if (ID_IS_LINKED(old_id)) {
BKE_id_expand_local(new_id);
BKE_id_lib_local_paths(bmain, old_id->lib, new_id);
}
@@ -295,7 +299,7 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
* In case we make a whole lib's content local, we always want to localize, and we skip remapping (done later).
*/
if (!ID_IS_LINKED_DATABLOCK(id)) {
if (!ID_IS_LINKED(id)) {
return;
}
@@ -711,7 +715,7 @@ void BKE_main_lib_objects_recalc_all(Main *bmain)
/* flag for full recalc */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ID_IS_LINKED_DATABLOCK(ob)) {
if (ID_IS_LINKED(ob)) {
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
@@ -1137,7 +1141,7 @@ static int id_relink_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **i
void BKE_libblock_relink(ID *id)
{
if (ID_IS_LINKED_DATABLOCK(id))
if (ID_IS_LINKED(id))
return;
BKE_library_foreach_ID_link(id, id_relink_looper, NULL, 0);
@@ -1147,6 +1151,8 @@ void BKE_library_free(Library *lib)
{
if (lib->packedfile)
freePackedFile(lib->packedfile);
BKE_library_asset_repository_free(lib);
}
Main *BKE_main_new(void)
@@ -1351,7 +1357,7 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
for (idtest = lb->first; idtest; idtest = idtest->next) {
/* if idtest is not a lib */
if (id != idtest && !ID_IS_LINKED_DATABLOCK(idtest)) {
if (id != idtest && !ID_IS_LINKED_DATABLOCK(idtest)) { /* Virtual lib IDs are considered as local ones here. */
/* do not test alphabetic! */
/* optimized */
if (idtest->name[2] == name[0]) {
@@ -1492,7 +1498,7 @@ bool new_id(ListBase *lb, ID *id, const char *tname)
bool result;
char name[MAX_ID_NAME - 2];
/* if library, don't rename */
/* if real library, don't rename */
if (ID_IS_LINKED_DATABLOCK(id))
return false;
@@ -1688,6 +1694,7 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged
}
}
/**
* Use after setting the ID's name
* When name exists: call 'new_id'
@@ -1733,6 +1740,11 @@ void BKE_id_ui_prefix(char name[MAX_ID_NAME + 1], const ID *id)
void BKE_library_filepath_set(Library *lib, const char *filepath)
{
if (lib->flag & LIBRARY_FLAG_VIRTUAL) {
/* Setting path for virtual libraries makes no sense. */
return;
}
/* in some cases this is used to update the absolute path from the
* relative */
if (lib->name != filepath) {

View File

@@ -0,0 +1,269 @@
/*
* ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2015,2016 by Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Bastien Montagne.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/library_asset.c
* \ingroup bke
*
* Contains asset-related management of ID's and libraries.
*/
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "RNA_types.h"
#include "BKE_asset_engine.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_main.h"
/* Asset managing - TODO: we most likely want to turn this into a hashing at some point, could become a bit slow
* when having huge assets (or many of them)... */
void BKE_library_asset_repository_init(Library *lib, const AssetEngineType *aet, const char *repo_root)
{
BKE_library_asset_repository_free(lib);
lib->asset_repository = MEM_mallocN(sizeof(*lib->asset_repository), __func__);
BLI_strncpy(lib->asset_repository->asset_engine, aet->idname, sizeof(lib->asset_repository->asset_engine));
lib->asset_repository->asset_engine_version = aet->version;
BLI_strncpy(lib->asset_repository->root, repo_root, sizeof(lib->asset_repository->root));
BLI_listbase_clear(&lib->asset_repository->assets);
}
void BKE_library_asset_repository_clear(Library *lib)
{
if (lib->asset_repository) {
for (AssetRef *aref; (aref = BLI_pophead(&lib->asset_repository->assets)); ) {
BLI_freelistN(&aref->id_list);
MEM_freeN(aref);
}
}
}
void BKE_library_asset_repository_free(Library *lib)
{
if (lib->asset_repository) {
BKE_library_asset_repository_clear(lib);
MEM_freeN(lib->asset_repository);
lib->asset_repository = NULL;
}
}
AssetRef *BKE_library_asset_repository_asset_add(Library *lib, const void *idv)
{
const ID *id = idv;
BLI_assert(id->uuid != NULL);
AssetRef *aref = BKE_library_asset_repository_asset_find(lib, idv);
if (!aref) {
aref = MEM_callocN(sizeof(*aref), __func__);
aref->uuid = *id->uuid;
BKE_library_asset_repository_subdata_add(aref, idv);
BLI_addtail(&lib->asset_repository->assets, aref);
}
return aref;
}
AssetRef *BKE_library_asset_repository_asset_find(Library *lib, const void *idv)
{
const ID *id = idv;
BLI_assert(id->uuid != NULL);
for (AssetRef *aref = lib->asset_repository->assets.first; aref; aref = aref->next) {
if (ASSETUUID_COMPARE(&aref->uuid, id->uuid)) {
#ifndef NDEBUG
LinkData *link = aref->id_list.first;
BLI_assert(link && (link->data == idv));
#endif
return aref;
}
}
return NULL;
}
void BKE_library_asset_repository_asset_remove(Library *lib, const void *idv)
{
AssetRef *aref = BKE_library_asset_repository_asset_find(lib, idv);
BLI_remlink(&lib->asset_repository->assets, aref);
BLI_freelistN(&aref->id_list);
MEM_freeN(aref);
}
void BKE_library_asset_repository_subdata_add(AssetRef *aref, const void *idv)
{
if (BLI_findptr(&aref->id_list, idv, offsetof(LinkData, data)) == NULL) {
BLI_addtail(&aref->id_list, BLI_genericNodeN((void *)idv));
}
}
void BKE_library_asset_repository_subdata_remove(AssetRef *aref, const void *idv)
{
LinkData *link = BLI_findptr(&aref->id_list, idv, offsetof(LinkData, data));
if (link) {
BLI_freelinkN(&aref->id_list, link);
}
}
void BKE_libraries_asset_subdata_remove(Main *bmain, const void *idv)
{
const ID *id = idv;
if (id->lib == NULL) {
return;
}
ListBase *lb = &bmain->library;
for (Library *lib = lb->first; lib; lib = lib->id.next) {
if (lib->asset_repository) {
for (AssetRef *aref = lib->asset_repository->assets.first; aref; aref = aref->next) {
LinkData *subdata = aref->id_list.first;
/* Skip first one, it's main asset, not subdata! */
for (subdata = subdata->next; subdata; subdata = subdata->next) {
if (subdata->data == idv) {
BLI_freelinkN(&aref->id_list, subdata);
break;
}
}
}
}
}
}
void BKE_libraries_asset_repositories_clear(Main *bmain)
{
ListBase *lb = which_libbase(bmain, ID_LI);
for (Library *lib = lb->first; lib; lib = lib->id.next) {
BKE_library_asset_repository_clear(lib);
}
BKE_main_id_tag_all(bmain, LIB_TAG_ASSET, false);
}
static int library_asset_dependencies_rebuild_cb(void *userdata, ID *id_self, ID **idp, int UNUSED(cd_flag))
{
if (!idp || !*idp) {
return IDWALK_RET_NOP;
}
AssetRef *aref = userdata;
ID *id = *idp;
if (id->uuid) {
return IDWALK_RET_STOP_RECURSION;
}
printf("%s (from %s)\n", id->name, id_self->name);
BKE_library_asset_repository_subdata_add(aref, (const void *)id);
id->tag |= LIB_TAG_ASSET;
return IDWALK_RET_NOP;
}
static void library_asset_dependencies_rebuild(ID *asset)
{
Library *lib = asset->lib;
BLI_assert(lib && lib->asset_repository);
if (!(lib && lib->asset_repository)) {
printf("asset: %s\n", asset->name);
printf("lib: %p\n", lib);
printf("lib: %s\n", lib->id.name);
printf("lib: %s\n", lib->name);
printf("lib: %p\n\n\n", lib->asset_repository);
}
asset->tag |= LIB_TAG_ASSET;
AssetRef *aref = BKE_library_asset_repository_asset_add(lib, asset);
BKE_library_foreach_ID_link(asset, library_asset_dependencies_rebuild_cb, aref, IDWALK_RECURSE);
}
void BKE_libraries_asset_repositories_rebuild(Main *bmain)
{
ListBase *lbarray[MAX_LIBARRAY];
ID *id;
int a;
BKE_libraries_asset_repositories_clear(bmain);
a = set_listbasepointers(bmain, lbarray);
while (a--) {
for (id = lbarray[a]->first; id; id = id->next) {
if (id->uuid) {
library_asset_dependencies_rebuild(id);
}
}
}
}
AssetRef *BKE_libraries_asset_repository_uuid_find(Main *bmain, const AssetUUID *uuid)
{
ListBase *lb = which_libbase(bmain, ID_LI);
for (Library *lib = lb->first; lib; lib = lib->id.next) {
for (AssetRef *aref = lib->asset_repository->assets.first; aref; aref = aref->next) {
if (ASSETUUID_COMPARE(&aref->uuid, uuid)) {
#ifndef NDEBUG
LinkData *link = aref->id_list.first;
BLI_assert(link && ((ID *)link->data)->uuid && ASSETUUID_COMPARE(((ID *)link->data)->uuid, uuid));
#endif
return aref;
}
}
}
return NULL;
}
/** Find or add the 'virtual' library datablock matching this asset engine, used for non-blend-data assets. */
Library *BKE_library_asset_virtual_ensure(Main *bmain, const AssetEngineType *aet)
{
Library *lib;
ListBase *lb = which_libbase(bmain, ID_LI);
for (lib = lb->first; lib; lib = lib->id.next) {
if (!(lib->flag & LIBRARY_FLAG_VIRTUAL) || !lib->asset_repository) {
continue;
}
if (STREQ(lib->asset_repository->asset_engine, aet->idname) &&
lib->asset_repository->asset_engine_version == aet->version)
{
return lib;
}
}
lib = BKE_libblock_alloc(bmain, ID_LI, "VirtualLib");
BKE_library_asset_repository_init(lib, aet, "");
lib->flag |= LIBRARY_FLAG_VIRTUAL;
return lib;
}

View File

@@ -298,7 +298,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
do {
data.self_id = id;
data.cd_flag = ID_IS_LINKED_DATABLOCK(id) ? IDWALK_INDIRECT_USAGE : 0;
data.cd_flag = ID_IS_LINKED(id) ? IDWALK_INDIRECT_USAGE : 0;
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
@@ -447,7 +447,7 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
* Since this field is set/owned by 'user' of this ID (and not ID itself), it is only indirect usage
* if proxy object is linked... Twisted. */
if (object->proxy_from) {
data.cd_flag = ID_IS_LINKED_DATABLOCK(object->proxy_from) ? IDWALK_INDIRECT_USAGE : 0;
data.cd_flag = ID_IS_LINKED(object->proxy_from) ? IDWALK_INDIRECT_USAGE : 0;
}
CALLBACK_INVOKE(object->proxy_from, IDWALK_NOP);
data.cd_flag = data_cd_flag;

View File

@@ -686,6 +686,10 @@ void BKE_libblock_free_data(Main *bmain, ID *id)
MEM_freeN(id->properties);
}
if (id->uuid) {
MEM_freeN(id->uuid);
}
/* this ID may be a driver target! */
BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
}

View File

@@ -707,7 +707,7 @@ void test_object_modifiers(Object *ob)
*/
const char *modifier_path_relbase(Object *ob)
{
if (G.relbase_valid || ID_IS_LINKED_DATABLOCK(ob)) {
if (G.relbase_valid || ID_IS_LINKED(ob)) {
return ID_BLEND_PATH(G.main, &ob->id);
}
else {

View File

@@ -2652,7 +2652,7 @@ void BKE_node_clipboard_add_node(bNode *node)
node_info->id = node->id;
if (node->id) {
BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name));
if (ID_IS_LINKED_DATABLOCK(node->id)) {
if (ID_IS_LINKED_DATABLOCK(node->id)) { /* Don't want virtual libraries here... */
BLI_strncpy(node_info->library_name, node->id->lib->filepath, sizeof(node_info->library_name));
}
else {

View File

@@ -1193,7 +1193,7 @@ void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local)
* In case we make a whole lib's content local, we always want to localize, and we skip remapping (done later).
*/
if (!ID_IS_LINKED_DATABLOCK(ob)) {
if (!ID_IS_LINKED(ob)) {
return;
}
@@ -1220,15 +1220,15 @@ void BKE_object_make_local(Main *bmain, Object *ob, const bool lib_local)
/* Returns true if the Object is from an external blend file (libdata) */
bool BKE_object_is_libdata(Object *ob)
{
return (ob && ID_IS_LINKED_DATABLOCK(ob));
return (ob && ID_IS_LINKED(ob));
}
/* Returns true if the Object data is from an external blend file (libdata) */
bool BKE_object_obdata_is_libdata(Object *ob)
{
/* Linked objects with local obdata are forbidden! */
BLI_assert(!ob || !ob->data || (ID_IS_LINKED_DATABLOCK(ob) ? ID_IS_LINKED_DATABLOCK(ob->data) : true));
return (ob && ob->data && ID_IS_LINKED_DATABLOCK(ob->data));
BLI_assert(!ob || !ob->data || (ID_IS_LINKED(ob) ? ID_IS_LINKED(ob->data) : true));
return (ob && ob->data && ID_IS_LINKED(ob->data));
}
/* *************** PROXY **************** */
@@ -1275,7 +1275,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
/* only on local objects because this causes indirect links
* 'a -> b -> c', blend to point directly to a.blend
* when a.blend has a proxy thats linked into c.blend */
if (!ID_IS_LINKED_DATABLOCK(ob))
if (!ID_IS_LINKED(ob))
id_lib_extern((ID *)dtar->id);
}
}
@@ -1293,7 +1293,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
{
/* paranoia checks */
if (ID_IS_LINKED_DATABLOCK(ob) || !ID_IS_LINKED_DATABLOCK(target)) {
if (ID_IS_LINKED(ob) || !ID_IS_LINKED(target)) {
printf("cannot make proxy\n");
return;
}
@@ -2670,7 +2670,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
printf("recalcob %s\n", ob->id.name + 2);
/* handle proxy copy for target */
if (ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from) {
if (ID_IS_LINKED(ob) && ob->proxy_from) {
// printf("ob proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
if (ob->proxy_from->proxy_group) { /* transform proxy into group space */
Object *obg = ob->proxy_from->proxy_group;

View File

@@ -203,7 +203,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
break;
}
case OB_ARMATURE:
if (ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from) {
if (ID_IS_LINKED(ob) && ob->proxy_from) {
if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
ob->id.name + 2, ob->proxy_from->id.name + 2);
@@ -315,7 +315,7 @@ void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx),
// XXX: it's almost redundant now...
/* Handle proxy copy for target, */
if (ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from) {
if (ID_IS_LINKED(ob) && ob->proxy_from) {
if (ob->proxy_from->proxy_group) {
/* Transform proxy into group space. */
Object *obg = ob->proxy_from->proxy_group;

View File

@@ -232,7 +232,7 @@ void packAll(Main *bmain, ReportList *reports, bool verbose)
int tot = 0;
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (BKE_image_has_packedfile(ima) == false && !ID_IS_LINKED_DATABLOCK(ima)) {
if (BKE_image_has_packedfile(ima) == false && !ID_IS_LINKED(ima)) {
if (ima->source == IMA_SRC_FILE) {
BKE_image_packfiles(reports, ima, ID_BLEND_PATH(bmain, &ima->id));
tot ++;
@@ -245,14 +245,14 @@ void packAll(Main *bmain, ReportList *reports, bool verbose)
}
for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
if (vfont->packedfile == NULL && !ID_IS_LINKED_DATABLOCK(vfont) && BKE_vfont_is_builtin(vfont) == false) {
if (vfont->packedfile == NULL && !ID_IS_LINKED(vfont) && BKE_vfont_is_builtin(vfont) == false) {
vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name);
tot ++;
}
}
for (sound = bmain->sound.first; sound; sound = sound->id.next) {
if (sound->packedfile == NULL && !ID_IS_LINKED_DATABLOCK(sound)) {
if (sound->packedfile == NULL && !ID_IS_LINKED(sound)) {
sound->packedfile = newPackedFile(reports, sound->name, bmain->name);
tot++;
}

View File

@@ -36,6 +36,8 @@
extern "C" {
#endif
struct AssetEngineType;
struct AssetUUID;
struct BlendThumbnail;
struct bScreen;
struct LinkNode;
@@ -102,6 +104,11 @@ struct ID *BLO_library_link_named_part_ex(
const short idcode, const char *name, const short flag,
struct Scene *scene, struct View3D *v3d,
const bool use_placeholders, const bool force_indirect);
struct ID *BLO_library_link_named_part_asset(
struct Main *mainl, BlendHandle **bh, const struct AssetEngineType *aet, const char *root,
const short idcode, const char *name, const struct AssetUUID *uuid, const short flag,
struct Scene *scene, struct View3D *v3d,
const bool use_placeholders, const bool force_indirect);
void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d);
void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh);

View File

@@ -109,10 +109,13 @@
#include "BLI_threads.h"
#include "BLI_mempool.h"
#include "RNA_types.h"
#include "BLT_translation.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_asset_engine.h"
#include "BKE_brush.h"
#include "BKE_cloth.h"
#include "BKE_constraint.h"
@@ -2160,6 +2163,9 @@ static void direct_link_id(FileData *fd, ID *id)
/* this case means the data was written incorrectly, it should not happen */
IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
}
if (id->uuid) {
id->uuid = newdataadr(fd, id->uuid);
}
}
/* ************ READ CurveMapping *************** */
@@ -7174,6 +7180,8 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
{
Main *newmain;
printf("adding lib %s (%s)\n", lib->id.name, lib->name);
/* check if the library was already read */
for (newmain = fd->mainlist->first; newmain; newmain = newmain->next) {
if (newmain->curlib) {
@@ -7201,7 +7209,12 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
// printf("direct_link_library: filepath %s\n", lib->filepath);
lib->packedfile = direct_link_packedfile(fd, lib->packedfile);
lib->asset_repository = newdataadr(fd, lib->asset_repository);
if (lib->asset_repository) {
/* Do not clear lib->asset_repository itself! */
BLI_listbase_clear(&lib->asset_repository->assets);
}
/* new main */
newmain = BKE_main_new();
BLI_addtail(fd->mainlist, newmain);
@@ -8017,15 +8030,33 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
return blo_nextbhead(fd, bhead);
id->tag = tag | LIB_TAG_NEED_LINK;
printf("id: %s (%p, %p), lib: %p\n", id->name, id, id->uuid, main->curlib);
id->lib = main->curlib;
id->us = ID_FAKE_USERS(id);
id->icon_id = 0;
/* this case cannot be direct_linked: it's just the ID part */
if (bhead->code == ID_ID) {
if (id->uuid) {
/* read all data into fd->datamap */
bhead = read_data_into_oldnewmap(fd, bhead, __func__);
id->uuid = newdataadr(fd, id->uuid);
oldnewmap_free_unused(fd->datamap);
oldnewmap_clear(fd->datamap);
return bhead;
}
return blo_nextbhead(fd, bhead);
}
/* If we have a real ID from a virtual library, tag ID as extern. */
if (id->lib && (id->lib->flag & LIBRARY_FLAG_VIRTUAL)) {
BLI_assert(ID_VIRTUAL_LIBRARY_VALID(id));
id->tag |= LIB_TAG_EXTERN;
}
/* need a name for the mallocN, just for debugging and sane prints on leaks */
allocname = dataname(GS(id->name));
@@ -8472,7 +8503,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
bhead->code = ID_SCR;
/* deliberate pass on to default */
default:
bhead = read_libblock(fd, bfd->main, bhead, LIB_TAG_LOCAL, NULL);
bhead = read_libblock(fd, mainlist.last, bhead, LIB_TAG_LOCAL, NULL);
}
}
@@ -8491,6 +8522,8 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
lib_verify_nodetree(bfd->main, true);
fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */
BKE_libraries_asset_repositories_rebuild(bfd->main);
link_global(fd, bfd); /* as last */
fd->mainlist = NULL; /* Safety, this is local variable, shall not be used afterward. */
@@ -9827,8 +9860,10 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
}
static ID *link_named_part_ex(
Main *mainl, FileData *fd, const short idcode, const char *name, const short flag,
Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
Main *mainl, FileData *fd, const AssetEngineType *aet, const char *root,
const short idcode, const char *name, const AssetUUID *uuid, const int flag,
Scene *scene, View3D *v3d,
const bool use_placeholders, const bool force_indirect)
{
ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect);
@@ -9841,6 +9876,18 @@ static ID *link_named_part_ex(
id->tag |= LIB_TAG_DOIT;
}
if (id && uuid) {
BLI_assert(root);
id->uuid = MEM_mallocN(sizeof(*id->uuid), __func__);
*id->uuid = *uuid;
id->flag |= LIB_ASSET;
if (!mainl->curlib->asset_repository) {
BKE_library_asset_repository_init(mainl->curlib, aet, root);
}
}
return id;
}
@@ -9881,7 +9928,33 @@ ID *BLO_library_link_named_part_ex(
const bool use_placeholders, const bool force_indirect)
{
FileData *fd = (FileData*)(*bh);
return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d, use_placeholders, force_indirect);
return link_named_part_ex(mainl, fd, NULL, NULL, idcode, name, NULL, flag, scene, v3d, use_placeholders, force_indirect);
}
/**
* Link a named datablock from an external blend file, using given asset engine & asset UUID.
* Optionally instantiate the object/group in the scene when the flags are set.
*
* \param mainl The main database to link from (not the active one).
* \param bh The blender file handle.
* \param aet The asset engine type (NULL when no asset engine is used).
* \param root the 'path' of the asset repository.
* \param idcode The kind of datablock to link.
* \param name The name of the datablock (without the 2 char ID prefix).
* \param uuid The asset engine's UUID of this datablock (NULL when no asset engine is used).
* \param flag Options for linking, used for instantiating.
* \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done).
* \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL).
* \return the linked ID when found.
*/
struct ID *BLO_library_link_named_part_asset(
Main *mainl, BlendHandle **bh, const AssetEngineType *aet, const char *root,
const short idcode, const char *name, const AssetUUID *uuid, const short flag,
Scene *scene, View3D *v3d,
const bool use_placeholders, const bool force_indirect)
{
FileData *fd = (FileData*)(*bh);
return link_named_part_ex(mainl, fd, aet, root, idcode, name, uuid, flag, scene, v3d, use_placeholders, force_indirect);
}
static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id)
@@ -10019,6 +10092,8 @@ static void library_link_end(Main *mainl, FileData **fd, const short flag, Scene
/* clear group instantiating tag */
BKE_main_id_tag_listbase(&(mainvar->group), LIB_TAG_DOIT, false);
BKE_libraries_asset_repositories_rebuild(mainvar);
/* patch to prevent switch_endian happens twice */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
blo_freefiledata(*fd);
@@ -10195,6 +10270,11 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
* (known case: some directly linked shapekey from a missing lib...). */
/* BLI_assert(realid != NULL); */
if (realid && id->uuid) {
/* we can give ownership of that pointer to new ID. */
realid->uuid = id->uuid;
}
change_idid_adr(mainlist, basefd, id, realid);
MEM_freeN(id);

View File

@@ -672,7 +672,14 @@ static void write_iddata(void *wd, const ID *id)
{
/* ID_WM's id->properties are considered runtime only, and never written in .blend file. */
if (id->properties && !ELEM(GS(id->name), ID_WM)) {
IDP_WriteProperty(id->properties, wd);
/* We want to write IDProps from 'virtual' libraries too, but not from 'real' linked datablocks... */
if (!id->uuid || (id->lib && (id->lib->flag & LIBRARY_FLAG_VIRTUAL))) {
IDP_WriteProperty(id->properties, wd);
}
}
if (id->uuid) {
BLI_assert(id->lib && id->lib->asset_repository);
writestruct(wd, DATA, AssetUUID, 1, id->uuid);
}
}
@@ -3871,6 +3878,7 @@ static void write_libraries(WriteData *wd, Main *main)
bool found_one;
for (; main; main = main->next) {
BLI_assert(BLI_listbase_is_empty(&main->library));
a = tot = set_listbasepointers(main, lbarray);
@@ -3900,6 +3908,9 @@ static void write_libraries(WriteData *wd, Main *main)
writestruct(wd, ID_LI, Library, 1, main->curlib);
write_iddata(wd, &main->curlib->id);
BLI_assert(!(main->curlib->flag & LIBRARY_FLAG_VIRTUAL) ||
(!main->curlib->packedfile && main->curlib->asset_repository));
if (main->curlib->packedfile) {
PackedFile *pf = main->curlib->packedfile;
writestruct(wd, DATA, PackedFile, 1, pf);
@@ -3909,15 +3920,57 @@ static void write_libraries(WriteData *wd, Main *main)
}
}
while (a--) {
for (id = lbarray[a]->first; id; id = id->next) {
if (id->us > 0 && (id->tag & LIB_TAG_EXTERN)) {
if (!BKE_idcode_is_linkable(GS(id->name))) {
printf("ERROR: write file: datablock '%s' from lib '%s' is not linkable "
"but is flagged as directly linked", id->name, main->curlib->filepath);
BLI_assert(0);
if (main->curlib->asset_repository) {
writestruct(wd, DATA, AssetRepositoryRef, 1, main->curlib->asset_repository);
}
if (main->curlib->flag & LIBRARY_FLAG_VIRTUAL) {
/* Those should be the only datatypes found in a virtual library! */
write_images (wd, &main->image);
write_vfonts (wd, &main->vfont);
write_texts (wd, &main->text);
write_sounds (wd, &main->sound);
BLI_assert(BLI_listbase_is_empty(&main->wm));
BLI_assert(BLI_listbase_is_empty(&main->screen));
BLI_assert(BLI_listbase_is_empty(&main->movieclip));
BLI_assert(BLI_listbase_is_empty(&main->mask));
BLI_assert(BLI_listbase_is_empty(&main->scene));
BLI_assert(BLI_listbase_is_empty(&main->curve));
BLI_assert(BLI_listbase_is_empty(&main->mball));
BLI_assert(BLI_listbase_is_empty(&main->camera));
BLI_assert(BLI_listbase_is_empty(&main->lamp));
BLI_assert(BLI_listbase_is_empty(&main->latt));
BLI_assert(BLI_listbase_is_empty(&main->key));
BLI_assert(BLI_listbase_is_empty(&main->world));
BLI_assert(BLI_listbase_is_empty(&main->speaker));
BLI_assert(BLI_listbase_is_empty(&main->group));
BLI_assert(BLI_listbase_is_empty(&main->armature));
BLI_assert(BLI_listbase_is_empty(&main->action));
BLI_assert(BLI_listbase_is_empty(&main->object));
BLI_assert(BLI_listbase_is_empty(&main->mat));
BLI_assert(BLI_listbase_is_empty(&main->tex));
BLI_assert(BLI_listbase_is_empty(&main->mesh));
BLI_assert(BLI_listbase_is_empty(&main->particle));
BLI_assert(BLI_listbase_is_empty(&main->nodetree));
BLI_assert(BLI_listbase_is_empty(&main->brush));
BLI_assert(BLI_listbase_is_empty(&main->palettes));
BLI_assert(BLI_listbase_is_empty(&main->paintcurves));
BLI_assert(BLI_listbase_is_empty(&main->gpencil));
BLI_assert(BLI_listbase_is_empty(&main->linestyle));
}
else {
while (a--) {
for (id = lbarray[a]->first; id; id = id->next) {
if (id->us > 0 && (id->tag & LIB_TAG_EXTERN)) {
if (!BKE_idcode_is_linkable(GS(id->name))) {
printf("ERROR: write file: datablock '%s' from lib '%s' is not linkable "
"but is flagged as directly linked", id->name, main->curlib->filepath);
BLI_assert(0);
}
writestruct(wd, ID_ID, ID, 1, id);
write_iddata(wd, id);
}
writestruct(wd, ID_ID, ID, 1, id);
}
}
}

View File

@@ -32,6 +32,7 @@
#define __ED_FILESELECT_H__
struct ARegion;
struct AssetEngine;
struct FileSelectParams;
struct ScrArea;
struct SpaceFile;
@@ -111,6 +112,8 @@ void ED_file_read_bookmarks(void);
void ED_file_change_dir(struct bContext *C);
struct AssetEngine *ED_filelist_assetengine_get(struct SpaceFile *sfile);
/* File menu stuff */
typedef enum FSMenuCategory {

View File

@@ -459,6 +459,11 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
data->totline++;
}
else if (ID_IS_LINKED_DATAPATH(id)) {
BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Using file path as asset"));
data->format[data->totline].color_id = UI_TIP_LC_NORMAL;
data->totline++;
}
}
}
else if (but->optype) {

View File

@@ -521,7 +521,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
const bool update_stat_strings = small_size != SMALL_SIZE_CHECK(layout->curr_size);
const float thumb_icon_aspect = sqrtf(64.0f / (float)(params->thumbnail_size));
numfiles = filelist_files_ensure(files);
numfiles = filelist_files_ensure(files, params);
if (params->display != FILE_IMGDISPLAY) {

View File

@@ -109,11 +109,10 @@ void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
int file_highlight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath);
void file_sfile_to_operator_ex(struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
void file_sfile_to_operator_ex(struct wmOperator *op, struct SpaceFile *sfile, char *filepath, const bool is_fake);
void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile);
void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op);
/* filesel.c */
void fileselect_file_set(SpaceFile *sfile, const int index);
float file_string_width(const char *str);

View File

@@ -33,9 +33,14 @@
#include "BLI_fileops_types.h"
#include "BLI_linklist.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
#include "BLO_readfile.h"
#include "BKE_appdir.h"
#include "BKE_asset_engine.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
@@ -53,9 +58,6 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "UI_view2d.h"
#include "WM_api.h"
@@ -100,7 +102,7 @@ static void file_deselect_all(SpaceFile *sfile, unsigned int flag)
{
FileSelection sel;
sel.first = 0;
sel.last = filelist_files_ensure(sfile->files) - 1;
sel.last = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile)) - 1;
filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
}
@@ -140,7 +142,7 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
FileSelection sel;
sel = find_file_mouse_rect(sfile, ar, rect);
@@ -169,7 +171,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
FileSelect retval = FILE_SELECT_NOTHING;
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
const FileDirEntry *file;
/* make the selected file active */
@@ -223,9 +225,8 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
/**
* \warning: loops over all files so better use cautiously
*/
static bool file_is_any_selected(struct FileList *files)
static bool file_is_any_selected(struct FileList *files, const int numfiles)
{
const int numfiles = filelist_files_ensure(files);
int i;
/* Is any file selected ? */
@@ -288,7 +289,8 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
FileSelect retval = FILE_SELECT_NOTHING;
FileSelection sel = file_selection_get(C, rect, fill); /* get the selection */
const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
const int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
/* flag the files as selected in the filelist */
filelist_entries_select_index_range_set(sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
@@ -303,7 +305,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
}
}
if (select != FILE_SEL_ADD && !file_is_any_selected(sfile->files)) {
if (select != FILE_SEL_ADD && !file_is_any_selected(sfile->files, numfiles)) {
sfile->params->active_file = -1;
}
else {
@@ -483,7 +485,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if (sfile && sfile->params) {
int idx = sfile->params->highlight_file;
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
if ((idx >= 0) && (idx < numfiles)) {
/* single select, deselect all selected first */
@@ -648,8 +650,8 @@ static bool file_walk_select_do(
const bool extend, const bool fill)
{
struct FileList *files = sfile->files;
const int numfiles = filelist_files_ensure(files);
const bool has_selection = file_is_any_selected(files);
const int numfiles = filelist_files_ensure(files, ED_fileselect_get_params(sfile));
const bool has_selection = file_is_any_selected(files, numfiles);
const int active_old = params->active_file;
int active_new = -1;
int other_site = -1; /* file on the other site of active_old */
@@ -764,8 +766,8 @@ static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op))
ScrArea *sa = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelection sel;
const int numfiles = filelist_files_ensure(sfile->files);
const bool has_selection = file_is_any_selected(sfile->files);
const int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
const bool has_selection = file_is_any_selected(sfile->files, numfiles);
sel.first = 0;
sel.last = numfiles - 1;
@@ -1101,8 +1103,8 @@ int file_highlight_set(SpaceFile *sfile, ARegion *ar, int mx, int my)
if (sfile == NULL || sfile->files == NULL) return 0;
numfiles = filelist_files_ensure(sfile->files);
params = ED_fileselect_get_params(sfile);
numfiles = filelist_files_ensure(sfile->files, params);
origfile = params->highlight_file;
@@ -1189,81 +1191,146 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
}
void file_sfile_to_operator_ex(wmOperator *op, SpaceFile *sfile, char *filepath)
void file_sfile_to_operator_ex(
wmOperator *op, SpaceFile *sfile, char filepath[FILE_MAX_LIBEXTRA], const bool is_fake)
{
PropertyRNA *prop;
PropertyRNA *prop, *prop_files, *prop_dirs;
/* Note filebrowser does not create ae for default NONE 'engine', we'll get NULL in this case here. */
AssetEngine *ae = filelist_assetengine_get(sfile->files);
AssetUUIDList *uuids;
FileDirEntryArr *selection;
FileCheckType check = CHECK_NONE;
BLI_join_dirfile(filepath, FILE_MAX, sfile->params->dir, sfile->params->file); /* XXX, not real length */
if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
BLI_path_rel(filepath, G.main->name);
}
if ((prop_files = RNA_struct_find_property(op->ptr, "files"))) {
check |= CHECK_FILES;
}
if ((prop_dirs = RNA_struct_find_property(op->ptr, "dirs"))) {
check |= CHECK_DIRS;
}
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
RNA_property_string_set(op->ptr, prop, sfile->params->file);
BLI_assert(STREQ(sfile->params->dir, filelist_dir(sfile->files)));
selection = filelist_selection_get(sfile->files, check, sfile->params->file, &uuids, !is_fake);
if (ae && selection->nbr_entries && !is_fake) { /* We only expect uuids when not is_fake... */
BLI_assert(uuids);
}
if ((prop = RNA_struct_find_property(op->ptr, "directory"))) {
RNA_property_string_set(op->ptr, prop, sfile->params->dir);
RNA_property_string_set(op->ptr, prop, selection->root);
}
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
RNA_property_string_set(op->ptr, prop, filepath);
}
/* some ops have multiple files to select */
/* this is called on operators check() so clear collections first since
* they may be already set. */
{
int i, numfiles = filelist_files_ensure(sfile->files);
if ((prop = RNA_struct_find_property(op->ptr, "files"))) {
PointerRNA itemptr;
int num_files = 0;
RNA_property_collection_clear(op->ptr, prop);
for (i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
FileDirEntry *file = filelist_file(sfile->files, i);
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", file->relpath);
num_files++;
}
}
/* make sure the file specified in the filename button is added even if no files selected */
if (0 == num_files) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", sfile->params->file);
if (selection->nbr_entries != 0) {
const char *filename;
filename = ((FileDirEntry *)selection->entries.first)->relpath;
BLI_join_dirfile(filepath, FILE_MAX_LIBEXTRA /* XXX sizeof(filepath) */, selection->root, filename);
if ((prop = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (RNA_property_boolean_get(op->ptr, prop)) {
BLI_path_rel(filepath, G.main->name);
}
}
if ((prop = RNA_struct_find_property(op->ptr, "dirs"))) {
PointerRNA itemptr;
int num_dirs = 0;
RNA_property_collection_clear(op->ptr, prop);
for (i = 0; i < numfiles; i++) {
if (filelist_entry_select_index_get(sfile->files, i, CHECK_DIRS)) {
FileDirEntry *file = filelist_file(sfile->files, i);
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", file->relpath);
num_dirs++;
}
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
RNA_property_string_set(op->ptr, prop, filename);
}
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
RNA_property_string_set(op->ptr, prop, filepath);
}
if (ae && uuids) {
if ((prop = RNA_struct_find_property(op->ptr, "asset_uuid"))) {
RNA_property_int_set_array(op->ptr, prop, uuids->uuids[0].uuid_asset);
}
/* make sure the directory specified in the button is added even if no directory selected */
if (0 == num_dirs) {
RNA_property_collection_add(op->ptr, prop, &itemptr);
RNA_string_set(&itemptr, "name", sfile->params->dir);
if ((prop = RNA_struct_find_property(op->ptr, "variant_uuid"))) {
RNA_property_int_set_array(op->ptr, prop, uuids->uuids[0].uuid_variant);
}
if ((prop = RNA_struct_find_property(op->ptr, "revision_uuid"))) {
RNA_property_int_set_array(op->ptr, prop, uuids->uuids[0].uuid_revision);
}
}
/* some ops have multiple files to select */
/* this is called on operators check() so clear collections first since
* they may be already set. */
{
if (prop_files) {
FileDirEntry *entry;
PointerRNA itemptr;
int i;
RNA_property_collection_clear(op->ptr, prop_files);
for (i = 0, entry = selection->entries.first; entry; entry = entry->next, i++) {
if (!(entry->typeflag & FILE_TYPE_DIR)) {
RNA_property_collection_add(op->ptr, prop_files, &itemptr);
RNA_string_set(&itemptr, "name", entry->relpath);
if (ae) {
BLI_assert(i < uuids->nbr_uuids);
RNA_int_set_array(&itemptr, "asset_uuid", uuids->uuids[i].uuid_asset);
RNA_int_set_array(&itemptr, "variant_uuid", uuids->uuids[i].uuid_variant);
RNA_int_set_array(&itemptr, "revision_uuid", uuids->uuids[i].uuid_revision);
}
}
}
}
if (prop_dirs) {
FileDirEntry *entry;
PointerRNA itemptr;
int num_dirs = 0;
RNA_property_collection_clear(op->ptr, prop);
for (entry = selection->entries.first; entry; entry = entry->next) {
if (entry->typeflag & FILE_TYPE_DIR) {
RNA_property_collection_add(op->ptr, prop_dirs, &itemptr);
RNA_string_set(&itemptr, "name", entry->relpath);
num_dirs++;
}
}
/* make sure the directory specified in the button is added even if no directory selected */
if (!num_dirs) {
RNA_property_collection_add(op->ptr, prop_dirs, &itemptr);
RNA_string_set(&itemptr, "name", sfile->params->dir);
}
}
}
}
else {
/* We have to ensure those are properly reset!!! */
if ((prop = RNA_struct_find_property(op->ptr, "filename"))) {
RNA_property_string_set(op->ptr, prop, sfile->params->file);
}
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
BLI_join_dirfile(filepath, FILE_MAX_LIBEXTRA, sfile->params->dir, sfile->params->file);
RNA_property_string_set(op->ptr, prop, filepath);
}
if (prop_files) {
RNA_property_reset(op->ptr, prop, 0);
}
if (prop_dirs) {
RNA_property_reset(op->ptr, prop, 0);
}
}
if (!is_fake && ae && (prop = RNA_struct_find_property(op->ptr, "asset_engine"))) {
RNA_property_string_set(op->ptr, prop, ae->type->idname);
}
if (uuids) {
MEM_freeN(uuids->uuids);
MEM_freeN(uuids);
}
BKE_filedir_entryarr_clear(selection);
MEM_freeN(selection);
}
void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile)
{
char filepath[FILE_MAX];
file_sfile_to_operator_ex(op, sfile, filepath);
file_sfile_to_operator_ex(op, sfile, filepath, false);
}
void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
@@ -1320,7 +1387,8 @@ void file_draw_check(bContext *C)
wmOperator *op = sfile->op;
if (op) { /* fail on reload */
if (op->type->check) {
file_sfile_to_operator(op, sfile);
char filepath[FILE_MAX_LIBEXTRA];
file_sfile_to_operator_ex(op, sfile, filepath, true);
/* redraw */
if (op->type->check(C, op)) {
@@ -1362,8 +1430,8 @@ int file_exec(bContext *C, wmOperator *exec_op)
wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
const struct FileDirEntry *file = filelist_file(sfile->files, sfile->params->active_file);
char filepath[FILE_MAX];
char filepath[FILE_MAX_LIBEXTRA];
/* directory change */
if (file && (file->typeflag & FILE_TYPE_DIR)) {
if (!file->relpath) {
@@ -1388,7 +1456,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
/* when used as a macro, for doubleclick,
* to prevent closing when doubleclicking on .. item */
if (RNA_boolean_get(exec_op->ptr, "need_active")) {
const int numfiles = filelist_files_ensure(sfile->files);
const int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
int i, active = 0;
for (i = 0; i < numfiles; i++) {
@@ -1403,7 +1471,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
sfile->op = NULL;
file_sfile_to_operator_ex(op, sfile, filepath);
file_sfile_to_operator_ex(op, sfile, filepath, false);
if (BLI_exists(sfile->params->dir)) {
fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL,
@@ -1572,7 +1640,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata)
return OPERATOR_PASS_THROUGH;
numfiles = filelist_files_ensure(sfile->files);
numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
/* check if we are editing a name */
for (i = 0; i < numfiles; ++i) {
@@ -2169,7 +2237,7 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
if (sfile->params) {
int idx = sfile->params->highlight_file;
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, sfile->params);
if ((0 <= idx) && (idx < numfiles)) {
FileDirEntry *file = filelist_file(sfile->files, idx);
filelist_entry_select_index_set(sfile->files, idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
@@ -2190,7 +2258,7 @@ static int file_rename_poll(bContext *C)
if (sfile && sfile->params) {
int idx = sfile->params->highlight_file;
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, sfile->params);
if ((0 <= idx) && (idx < numfiles)) {
FileDirEntry *file = filelist_file(sfile->files, idx);
@@ -2236,7 +2304,7 @@ static int file_delete_poll(bContext *C)
if (sfile && sfile->params) {
char dir[FILE_MAX];
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, sfile->params);
int i;
int num_selected = 0;
@@ -2263,7 +2331,7 @@ int file_delete_exec(bContext *C, wmOperator *op)
SpaceFile *sfile = CTX_wm_space_file(C);
ScrArea *sa = CTX_wm_area(C);
FileDirEntry *file;
int numfiles = filelist_files_ensure(sfile->files);
int numfiles = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
int i;
bool report_error = false;

View File

@@ -63,6 +63,9 @@
# include "BLI_winstuff.h"
#endif
#include "RNA_types.h"
#include "BKE_asset_engine.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -285,6 +288,8 @@ enum {
typedef struct FileList {
FileDirEntryArr filelist;
AssetEngine *ae;
short prv_w;
short prv_h;
@@ -509,30 +514,17 @@ static int compare_extension(void *UNUSED(user_data), const void *a1, const void
return BLI_natstrcmp(name1, name2);
}
void filelist_sort(struct FileList *filelist)
static bool filelist_need_sorting(struct FileList *filelist)
{
if ((filelist->flags & FL_NEED_SORTING) && (filelist->sort != FILE_SORT_NONE)) {
switch (filelist->sort) {
case FILE_SORT_ALPHA:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_name, NULL);
break;
case FILE_SORT_TIME:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_date, NULL);
break;
case FILE_SORT_SIZE:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_size, NULL);
break;
case FILE_SORT_EXTENSION:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_extension, NULL);
break;
case FILE_SORT_NONE: /* Should never reach this point! */
default:
BLI_assert(0);
break;
}
return (((filelist->flags & FL_NEED_SORTING) || (filelist->ae && (filelist->ae->flag & AE_DIRTY_SORTING))) &&
(filelist->sort != FILE_SORT_NONE));
}
filelist_filter_clear(filelist);
filelist->flags &= ~FL_NEED_SORTING;
static void filelist_need_sorting_clear(struct FileList *filelist)
{
filelist->flags &= ~FL_NEED_SORTING;
if (filelist->ae) {
filelist->ae->flag &= ~AE_DIRTY_SORTING;
}
}
@@ -678,54 +670,17 @@ static void filelist_filter_clear(FileList *filelist)
filelist->flags |= FL_NEED_FILTERING;
}
void filelist_filter(FileList *filelist)
static bool filelist_need_filtering(struct FileList *filelist)
{
int num_filtered = 0;
const int num_files = filelist->filelist.nbr_entries;
FileListInternEntry **filtered_tmp, *file;
return ((filelist->flags & FL_NEED_FILTERING) || (filelist->ae && (filelist->ae->flag & AE_DIRTY_FILTER)));
}
if (filelist->filelist.nbr_entries == 0) {
return;
}
if (!(filelist->flags & FL_NEED_FILTERING)) {
/* Assume it has already been filtered, nothing else to do! */
return;
}
filelist->filter_data.flags &= ~FLF_HIDE_LIB_DIR;
if (filelist->max_recursion) {
/* Never show lib ID 'categories' directories when we are in 'flat' mode, unless
* root path is a blend file. */
char dir[FILE_MAX_LIBEXTRA];
if (!filelist_islibrary(filelist, dir, NULL)) {
filelist->filter_data.flags |= FLF_HIDE_LIB_DIR;
}
}
filtered_tmp = MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__);
/* Filter remap & count how many files are left after filter in a single loop. */
for (file = filelist->filelist_intern.entries.first; file; file = file->next) {
if (filelist->filterf(file, filelist->filelist.root, &filelist->filter_data)) {
filtered_tmp[num_filtered++] = file;
}
}
if (filelist->filelist_intern.filtered) {
MEM_freeN(filelist->filelist_intern.filtered);
}
filelist->filelist_intern.filtered = MEM_mallocN(sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered,
__func__);
memcpy(filelist->filelist_intern.filtered, filtered_tmp,
sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered);
filelist->filelist.nbr_entries_filtered = num_filtered;
// printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.nbr_entries);
filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
static void filelist_need_filtering_clear(struct FileList *filelist)
{
filelist->flags &= ~FL_NEED_FILTERING;
MEM_freeN(filtered_tmp);
if (filelist->ae) {
filelist->ae->flag &= ~AE_DIRTY_FILTER;
}
}
void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent,
@@ -763,6 +718,93 @@ void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const b
}
}
void filelist_sort_filter(struct FileList *filelist, FileSelectParams *params)
{
if (filelist->ae) {
if (filelist->ae->type->sort_filter) {
const bool need_sorting = filelist_need_sorting(filelist);
const bool need_filtering = filelist_need_filtering(filelist);
const bool changed = filelist->ae->type->sort_filter(
filelist->ae, need_sorting, need_filtering, params, &filelist->filelist);
// printf("%s: changed: %d (%d - %d)\n", __func__, changed, need_sorting, need_filtering);
if (changed) {
filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
}
}
}
else {
if (filelist_need_sorting(filelist)) {
switch (filelist->sort) {
case FILE_SORT_ALPHA:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_name, NULL);
break;
case FILE_SORT_TIME:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_date, NULL);
break;
case FILE_SORT_SIZE:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_size, NULL);
break;
case FILE_SORT_EXTENSION:
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_extension, NULL);
break;
case FILE_SORT_NONE: /* Should never reach this point! */
default:
BLI_assert(0);
}
filelist_filter_clear(filelist);
}
if (filelist_need_filtering(filelist)) {
int num_filtered = 0;
const int num_files = filelist->filelist.nbr_entries;
FileListInternEntry **filtered_tmp, *file;
if (filelist->filelist.nbr_entries == 0) {
return;
}
filelist->filter_data.flags &= ~FLF_HIDE_LIB_DIR;
if (filelist->max_recursion) {
/* Never show lib ID 'categories' directories when we are in 'flat' mode, unless
* root path is a blend file. */
char dir[FILE_MAXDIR];
if (!filelist_islibrary(filelist, dir, NULL)) {
filelist->filter_data.flags |= FLF_HIDE_LIB_DIR;
}
}
filtered_tmp = MEM_mallocN(sizeof(*filtered_tmp) * (size_t)num_files, __func__);
/* Filter remap & count how many files are left after filter in a single loop. */
for (file = filelist->filelist_intern.entries.first; file; file = file->next) {
if (filelist->filterf(file, filelist->filelist.root, &filelist->filter_data)) {
filtered_tmp[num_filtered++] = file;
}
}
if (filelist->filelist_intern.filtered) {
MEM_freeN(filelist->filelist_intern.filtered);
}
filelist->filelist_intern.filtered = MEM_mallocN(sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered,
__func__);
memcpy(filelist->filelist_intern.filtered, filtered_tmp,
sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered);
filelist->filelist.nbr_entries_filtered = num_filtered;
// printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.nbr_entries);
filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
MEM_freeN(filtered_tmp);
}
}
filelist_need_sorting_clear(filelist);
filelist_need_filtering_clear(filelist);
}
/* ********** Icon/image helpers ********** */
void filelist_init_icons(void)
@@ -940,17 +982,27 @@ int filelist_geticon(struct FileList *filelist, const int index, const bool is_m
/* ********** Main ********** */
static void filelist_checkdir_dir(struct FileList *UNUSED(filelist), char *r_dir)
static void filelist_checkdir_dir(struct FileList *filelist, char *r_dir)
{
BLI_make_exist(r_dir);
if (filelist->ae && filelist->ae->type->check_dir) {
filelist->ae->type->check_dir(filelist->ae, r_dir);
}
else {
BLI_make_exist(r_dir);
}
}
static void filelist_checkdir_lib(struct FileList *UNUSED(filelist), char *r_dir)
static void filelist_checkdir_lib(struct FileList *filelist, char *r_dir)
{
char dir[FILE_MAX_LIBEXTRA];
if (!BLO_library_path_explode(r_dir, dir, NULL, NULL)) {
/* if not a valid library, we need it to be a valid directory! */
BLI_make_exist(r_dir);
if (filelist->ae && filelist->ae->type->check_dir) {
filelist->ae->type->check_dir(filelist->ae, r_dir);
}
else {
char dir[FILE_MAX_LIBEXTRA];
if (!BLO_library_path_explode(r_dir, dir, NULL, NULL)) {
/* if not a valid library, we need it to be a valid directory! */
BLI_make_exist(r_dir);
}
}
}
@@ -960,6 +1012,7 @@ static void filelist_checkdir_main(struct FileList *filelist, char *r_dir)
filelist_checkdir_lib(filelist, r_dir);
}
#if 0
static void filelist_entry_clear(FileDirEntry *entry)
{
if (entry->name) {
@@ -1033,6 +1086,7 @@ static void filelist_direntryarr_free(FileDirEntryArr *array)
array->entry_idx_start = -1;
array->entry_idx_end = -1;
}
#endif
static void filelist_intern_entry_free(FileListInternEntry *entry)
{
@@ -1216,9 +1270,11 @@ static void filelist_cache_free(FileListEntryCache *cache)
BLI_ghash_free(cache->uuids, NULL, NULL);
// printf("\n\n%s:\n", __func__);
for (entry = cache->cached_entries.first; entry; entry = entry_next) {
// printf("\t%s (%p, %p)\n", entry->relpath, entry, entry->next);
entry_next = entry->next;
filelist_entry_free(entry);
BKE_filedir_entry_free(entry);
}
BLI_listbase_clear(&cache->cached_entries);
}
@@ -1249,9 +1305,11 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size)
cache->size = new_size;
// printf("\n\n%s:\n", __func__);
for (entry = cache->cached_entries.first; entry; entry = entry_next) {
// printf("\t%s (%p, %p)\n", entry->relpath, entry, entry->next);
entry_next = entry->next;
filelist_entry_free(entry);
BKE_filedir_entry_free(entry);
}
BLI_listbase_clear(&cache->cached_entries);
}
@@ -1298,7 +1356,8 @@ void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const boo
filelist_intern_free(&filelist->filelist_intern);
filelist_direntryarr_free(&filelist->filelist);
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries));
BKE_filedir_entryarr_clear(&filelist->filelist);
if (do_selection && filelist->selection_state) {
BLI_ghash_clear(filelist->selection_state, MEM_freeN, NULL);
@@ -1320,6 +1379,11 @@ void filelist_free(struct FileList *filelist)
filelist_clear_ex(filelist, false, false); /* No need to clear cache & selection_state, we free them anyway. */
filelist_cache_free(&filelist->filelist_cache);
if (filelist->ae) {
BKE_asset_engine_free(filelist->ae);
filelist->ae = NULL;
}
if (filelist->selection_state) {
BLI_ghash_free(filelist->selection_state, MEM_freeN, NULL);
filelist->selection_state = NULL;
@@ -1338,6 +1402,11 @@ void filelist_freelib(struct FileList *filelist)
filelist->libfiledata = NULL;
}
AssetEngine *filelist_assetengine_get(struct FileList *filelist)
{
return filelist->ae;
}
BlendHandle *filelist_lib(struct FileList *filelist)
{
return filelist->libfiledata;
@@ -1371,6 +1440,30 @@ static const char *fileentry_uiname(const char *root, const char *relpath, const
return name;
}
void filelist_assetengine_set(struct FileList *filelist, struct AssetEngineType *aet)
{
if (filelist->ae) {
if (filelist->ae->type == aet) {
return;
}
BKE_asset_engine_free(filelist->ae);
filelist->ae = NULL;
}
else if (!aet) {
return;
}
if (aet) {
filelist->ae = BKE_asset_engine_create(aet, NULL);
}
filelist->flags |= FL_FORCE_RESET;
}
AssetEngine *ED_filelist_assetengine_get(SpaceFile *sfile)
{
return sfile->files->ae;
}
const char *filelist_dir(struct FileList *filelist)
{
return filelist->filelist.root;
@@ -1388,6 +1481,7 @@ void filelist_setdir(struct FileList *filelist, char *r_dir)
if (!STREQ(filelist->filelist.root, r_dir)) {
BLI_strncpy(filelist->filelist.root, r_dir, sizeof(filelist->filelist.root));
printf("%s: Forcing Reset!!!\n", __func__);
filelist->flags |= FL_FORCE_RESET;
}
}
@@ -1419,46 +1513,112 @@ bool filelist_pending(struct FileList *filelist)
* Limited version of full update done by space_file's file_refresh(), to be used by operators and such.
* Ensures given filelist is ready to be used (i.e. it is filtered and sorted), unless it is tagged for a full refresh.
*/
int filelist_files_ensure(FileList *filelist)
int filelist_files_ensure(FileList *filelist, FileSelectParams *params)
{
if (!filelist_force_reset(filelist) || !filelist_empty(filelist)) {
filelist_sort(filelist);
filelist_filter(filelist);
filelist_sort_filter(filelist, params);
}
return filelist->filelist.nbr_entries_filtered;
}
static FileDirEntry *filelist_file_create_entries_block(FileList *filelist, const int index, const int size);
static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int index)
{
FileListInternEntry *entry = filelist->filelist_intern.filtered[index];
FileListEntryCache *cache = &filelist->filelist_cache;
FileDirEntry *ret;
FileDirEntryRevision *rev;
ret = MEM_callocN(sizeof(*ret), __func__);
rev = MEM_callocN(sizeof(*rev), __func__);
if (filelist->ae) {
ret = filelist_file_create_entries_block(filelist, index, 1);
rev->size = (uint64_t)entry->st.st_size;
BLI_assert(!ret || !ret->next);
}
else {
FileListInternEntry *entry = filelist->filelist_intern.filtered[index];
FileDirEntryRevision *rev;
rev->time = (int64_t)entry->st.st_mtime;
ret = MEM_callocN(sizeof(*ret), __func__);
rev = MEM_callocN(sizeof(*rev), __func__);
ret->entry = rev;
ret->relpath = BLI_strdup(entry->relpath);
ret->name = BLI_strdup(entry->name);
ret->description = BLI_strdupcat(filelist->filelist.root, entry->relpath);
memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
rev->size = (uint64_t)entry->st.st_size;
rev->time = (int64_t)entry->st.st_mtime;
ret->entry = rev;
ret->relpath = BLI_strdup(entry->relpath);
ret->name = BLI_strdup(entry->name);
ret->description = BLI_strdupcat(filelist->filelist.root, entry->relpath);
memcpy(ret->uuid, entry->uuid, sizeof(ret->uuid));
ret->blentype = entry->blentype;
ret->typeflag = entry->typeflag;
BLI_addtail(&cache->cached_entries, ret);
}
BLI_addtail(&cache->cached_entries, ret);
return ret;
}
static FileDirEntry *filelist_file_create_entries_block(FileList *filelist, const int index, const int size)
{
FileDirEntry *entry = NULL;
FileDirEntryArr tmp_arr;
int i;
tmp_arr = filelist->filelist;
BLI_listbase_clear(&tmp_arr.entries);
if (filelist->ae) {
if (!filelist->ae->type->entries_block_get) {
printf("%s: Asset Engine %s does not implement 'entries_block_get'...\n", __func__, filelist->ae->type->name);
return entry;
}
if (!filelist->ae->type->entries_block_get(filelist->ae, index, index + size, &tmp_arr)) {
printf("%s: Failed to get [%d:%d] from AE %s\n", __func__, index, index + size, filelist->ae->type->name);
BKE_filedir_entryarr_clear(&tmp_arr);
return entry;
}
for (i = 0, entry = tmp_arr.entries.first; i < size && entry; i++, entry = entry->next) {
BLI_assert(!BLI_listbase_is_empty(&entry->variants) && entry->nbr_variants);
BLI_assert(entry->act_variant < entry->nbr_variants);
if (!entry->name) {
char buff[FILE_MAX_LIBEXTRA];
entry->name = BLI_strdup(fileentry_uiname(filelist->filelist.root,
entry->relpath, entry->typeflag, buff));
}
if (!entry->entry) {
FileDirEntryVariant *variant = BLI_findlink(&entry->variants, entry->act_variant);
BLI_assert(!BLI_listbase_is_empty(&variant->revisions) && variant->nbr_revisions);
BLI_assert(variant->act_revision < variant->nbr_revisions);
entry->entry = BLI_findlink(&variant->revisions, variant->act_revision);
BLI_assert(entry->entry);
}
}
BLI_assert(i == size && !entry);
entry = tmp_arr.entries.first;
/* Using filelist->filelist_cache.cached_entries as owner of that mem! */
BLI_movelisttolist(&filelist->filelist_cache.cached_entries, &tmp_arr.entries);
}
#if 0 /* UNUSED */
else {
entry = filelist_file_create_entry(filelist, index);
for (i = 1, idx = index + 1; i < size; i++, idx++) {
filelist_file_create_entry(filelist, idx);
}
}
#endif
return entry;
}
static void filelist_file_release_entry(FileList *filelist, FileDirEntry *entry)
{
BLI_remlink(&filelist->filelist_cache.cached_entries, entry);
filelist_entry_free(entry);
BKE_filedir_entry_free(entry);
}
static FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const bool use_request)
@@ -1489,22 +1649,24 @@ static FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index
/* Else, we have to add new entry to 'misc' cache - and possibly make room for it first! */
ret = filelist_file_create_entry(filelist, index);
old_index = cache->misc_entries_indices[cache->misc_cursor];
if ((old = BLI_ghash_popkey(cache->misc_entries, SET_INT_IN_POINTER(old_index), NULL))) {
BLI_ghash_remove(cache->uuids, old->uuid, NULL, NULL);
filelist_file_release_entry(filelist, old);
}
BLI_ghash_insert(cache->misc_entries, SET_INT_IN_POINTER(index), ret);
BLI_ghash_insert(cache->uuids, ret->uuid, ret);
if (ret) {
old_index = cache->misc_entries_indices[cache->misc_cursor];
if ((old = BLI_ghash_popkey(cache->misc_entries, SET_INT_IN_POINTER(old_index), NULL))) {
BLI_ghash_remove(cache->uuids, old->uuid, NULL, NULL);
filelist_file_release_entry(filelist, old);
}
BLI_ghash_insert(cache->misc_entries, SET_INT_IN_POINTER(index), ret);
BLI_ghash_insert(cache->uuids, ret->uuid, ret);
cache->misc_entries_indices[cache->misc_cursor] = index;
cache->misc_cursor = (cache->misc_cursor + 1) % cache_size;
cache->misc_entries_indices[cache->misc_cursor] = index;
cache->misc_cursor = (cache->misc_cursor + 1) % cache_size;
#if 0 /* Actually no, only block cached entries should have preview imho. */
if (cache->previews_pool) {
filelist_cache_previews_push(filelist, ret, index);
}
if (cache->previews_pool) {
filelist_cache_previews_push(filelist, ret, index);
}
#endif
}
return ret;
}
@@ -1548,7 +1710,30 @@ FileDirEntry *filelist_entry_find_uuid(struct FileList *filelist, const int uuid
}
}
{
if (filelist->ae) {
AssetEngine *engine = filelist->ae;
if (engine->type->entries_uuid_get) {
FileDirEntryArr r_entries;
AssetUUIDList uuids = {0};
AssetUUID asset_uuid = {0};
FileDirEntry *en = NULL;
uuids.uuids = &asset_uuid;
uuids.nbr_uuids = 1;
uuids.asset_engine_version = engine->type->version;
memcpy(asset_uuid.uuid_asset, uuid, sizeof(asset_uuid.uuid_asset));
/* Variants and revision uuids remain NULL here. */
if (engine->type->entries_uuid_get(engine, &uuids, &r_entries)) {
en = r_entries.entries.first;
}
return en;
}
}
else {
int fidx;
for (fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
@@ -1582,7 +1767,20 @@ static bool filelist_file_cache_block_create(FileList *filelist, const int start
{
FileListEntryCache *cache = &filelist->filelist_cache;
{
if (filelist->ae) {
FileDirEntry *entry;
int i;
entry = filelist_file_create_entries_block(filelist, start_index, size);
for (i = 0; i < size; i++, cursor++, entry = entry->next) {
// printf("%d, %p\n", i, entry);
cache->block_entries[cursor] = entry;
BLI_ghash_insert(cache->uuids, entry->uuid, entry);
}
return true;
}
else {
int i, idx;
for (i = 0, idx = start_index; i < size; i++, idx++, cursor++) {
@@ -1604,19 +1802,17 @@ static bool filelist_file_cache_block_create(FileList *filelist, const int start
static void filelist_file_cache_block_release(struct FileList *filelist, const int size, int cursor)
{
FileListEntryCache *cache = &filelist->filelist_cache;
int i;
{
int i;
for (i = 0; i < size; i++, cursor++) {
FileDirEntry *entry = cache->block_entries[cursor];
// printf("%s: release cacheidx %d (%%p %%s)\n", __func__, cursor/*, cache->block_entries[cursor], cache->block_entries[cursor]->relpath*/);
BLI_ghash_remove(cache->uuids, entry->uuid, NULL, NULL);
filelist_file_release_entry(filelist, cache->block_entries[cursor]);
for (i = 0; i < size; i++, cursor++) {
FileDirEntry *entry = cache->block_entries[cursor];
// printf("%s: release cacheidx %d (%%p %%s)\n", __func__, cursor/*, cache->block_entries[cursor], cache->block_entries[cursor]->relpath*/);
BLI_ghash_remove(cache->uuids, entry->uuid, NULL, NULL);
filelist_file_release_entry(filelist, entry);
#ifndef NDEBUG
cache->block_entries[cursor] = NULL;
cache->block_entries[cursor] = NULL;
#endif
}
}
}
@@ -2113,6 +2309,60 @@ unsigned int filelist_entry_select_index_get(FileList *filelist, const int index
return 0;
}
/**
* Returns a list of selected entries, if use_ae is set also calls asset engine's load_pre callback.
* Note first item of returned list shall be used as 'active' file.
*/
FileDirEntryArr *filelist_selection_get(
FileList *filelist, FileCheckType check, const char *name, AssetUUIDList **r_uuids, const bool use_ae)
{
FileDirEntryArr *selection;
GHashIterator *iter = BLI_ghashIterator_new(filelist->selection_state);
bool done_name = false;
selection = MEM_callocN(sizeof(*selection), __func__);
strcpy(selection->root, filelist->filelist.root);
for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
const int *uuid = BLI_ghashIterator_getKey(iter);
FileDirEntry *entry_org = filelist_entry_find_uuid(filelist, uuid);
BLI_assert(BLI_ghashIterator_getValue(iter));
if (entry_org &&
(((ELEM(check, CHECK_ALL, CHECK_NONE))) ||
((check == CHECK_DIRS) && (entry_org->typeflag & FILE_TYPE_DIR)) ||
((check == CHECK_FILES) && !(entry_org->typeflag & FILE_TYPE_DIR)))) {
/* Always include 'name' (i.e. given relpath) */
if (!done_name && STREQ(entry_org->relpath, name)) {
FileDirEntry *entry_new = BKE_filedir_entry_copy(entry_org);
/* We add it in head - first entry in this list is always considered 'active' one. */
BLI_addhead(&selection->entries, entry_new);
selection->nbr_entries++;
done_name = true;
}
else {
FileDirEntry *entry_new = BKE_filedir_entry_copy(entry_org);
BLI_addtail(&selection->entries, entry_new);
selection->nbr_entries++;
}
}
}
BLI_ghashIterator_free(iter);
if (use_ae && filelist->ae) {
/* This will 'rewrite' selection list, returned paths are expected to be valid! */
*r_uuids = BKE_asset_engine_entries_load_pre(filelist->ae, selection);
}
else {
*r_uuids = NULL;
}
return selection;
}
/* WARNING! dir must be FILE_MAX_LIBEXTRA long! */
bool filelist_islibrary(struct FileList *filelist, char *dir, char **group)
{
@@ -2226,7 +2476,7 @@ static int filelist_readjob_list_lib(const char *root, ListBase *entries, const
return nbr_entries;
}
/* memory for strings is passed into filelist[i].entry->relpath and freed in filelist_entry_free. */
/* memory for strings is passed into filelist[i].entry->relpath and freed in BKE_filedir_entry_free. */
if (group) {
idcode = groupname_to_code(group);
names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, &nnames);
@@ -2560,79 +2810,134 @@ typedef struct FileListReadJob {
char main_name[FILE_MAX];
struct FileList *filelist;
struct FileList *tmp_filelist; /* XXX We may use a simpler struct here... just a linked list and root path? */
int ae_job_id;
float *progress;
short *stop;
} FileListReadJob;
static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update, float *progress)
{
FileListReadJob *flrj = flrjv;
// printf("START filelist reading (%d files, main thread: %d)\n",
// flrj->filelist->filelist.nbr_entries, BLI_thread_is_main());
if (flrj->filelist->ae) {
flrj->progress = progress;
flrj->stop = stop;
flrj->ae_job_id = AE_JOB_ID_UNSET;
/* When using AE engine, worker thread here is just sleeping! */
while ((flrj->filelist->flags & FL_IS_PENDING) && !*stop) {
PIL_sleep_ms(10);
*do_update = true;
}
}
else {
BLI_mutex_lock(&flrj->lock);
BLI_mutex_lock(&flrj->lock);
BLI_assert((flrj->tmp_filelist == NULL) && flrj->filelist);
BLI_assert((flrj->tmp_filelist == NULL) && flrj->filelist);
flrj->tmp_filelist = MEM_dupallocN(flrj->filelist);
flrj->tmp_filelist = MEM_dupallocN(flrj->filelist);
BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries);
flrj->tmp_filelist->filelist.nbr_entries = 0;
BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries);
flrj->tmp_filelist->filelist.nbr_entries = 0;
flrj->tmp_filelist->filelist_intern.filtered = NULL;
BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries);
memset(flrj->tmp_filelist->filelist_intern.curr_uuid, 0, sizeof(flrj->tmp_filelist->filelist_intern.curr_uuid));
flrj->tmp_filelist->filelist_intern.filtered = NULL;
BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries);
memset(flrj->tmp_filelist->filelist_intern.curr_uuid, 0, sizeof(flrj->tmp_filelist->filelist_intern.curr_uuid));
flrj->tmp_filelist->libfiledata = NULL;
memset(&flrj->tmp_filelist->filelist_cache, 0, sizeof(flrj->tmp_filelist->filelist_cache));
flrj->tmp_filelist->selection_state = NULL;
flrj->tmp_filelist->libfiledata = NULL;
memset(&flrj->tmp_filelist->filelist_cache, 0, sizeof(flrj->tmp_filelist->filelist_cache));
flrj->tmp_filelist->selection_state = NULL;
BLI_mutex_unlock(&flrj->lock);
BLI_mutex_unlock(&flrj->lock);
flrj->tmp_filelist->read_jobf(flrj->tmp_filelist, flrj->main_name, stop, do_update, progress, &flrj->lock);
flrj->tmp_filelist->read_jobf(flrj->tmp_filelist, flrj->main_name, stop, do_update, progress, &flrj->lock);
}
}
static void filelist_readjob_update(void *flrjv)
{
FileListReadJob *flrj = flrjv;
FileListIntern *fl_intern = &flrj->filelist->filelist_intern;
ListBase new_entries = {NULL};
int nbr_entries, new_nbr_entries = 0;
BLI_movelisttolist(&new_entries, &fl_intern->entries);
nbr_entries = flrj->filelist->filelist.nbr_entries;
BLI_mutex_lock(&flrj->lock);
if (flrj->tmp_filelist->filelist.nbr_entries) {
/* We just move everything out of 'thread context' into final list. */
new_nbr_entries = flrj->tmp_filelist->filelist.nbr_entries;
BLI_movelisttolist(&new_entries, &flrj->tmp_filelist->filelist.entries);
flrj->tmp_filelist->filelist.nbr_entries = 0;
if (flrj->filelist->flags & FL_FORCE_RESET) {
*flrj->stop = true;
}
else if (flrj->filelist->ae) {
/* We only communicate with asset engine from main thread! */
AssetEngine *ae = flrj->filelist->ae;
BLI_mutex_unlock(&flrj->lock);
if (flrj->ae_job_id == AE_JOB_ID_INVALID) {
BLI_assert(0); /* Should never reach this point... */
*flrj->progress = 1.0f;
*flrj->stop = true;
return;
}
if (new_nbr_entries) {
/* Do not clear selection cache, we can assume already 'selected' uuids are still valid! */
filelist_clear_ex(flrj->filelist, true, false);
flrj->ae_job_id = ae->type->list_dir(ae, flrj->ae_job_id, &flrj->filelist->filelist);
flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING);
}
/* if no new_nbr_entries, this is NOP */
BLI_movelisttolist(&fl_intern->entries, &new_entries);
flrj->filelist->filelist.nbr_entries = nbr_entries + new_nbr_entries;
if (flrj->ae_job_id == AE_JOB_ID_INVALID) { /* Immediate execution. */
*flrj->progress = 1.0f;
*flrj->stop = true;
}
else {
*flrj->progress = ae->type->progress(ae, flrj->ae_job_id);
if ((ae->type->status(ae, flrj->ae_job_id) & (AE_STATUS_RUNNING | AE_STATUS_VALID)) !=
(AE_STATUS_RUNNING | AE_STATUS_VALID))
{
*flrj->stop = true;
}
}
}
else {
FileListIntern *fl_intern = &flrj->filelist->filelist_intern;
ListBase new_entries = {NULL};
int nbr_entries, new_nbr_entries = 0;
BLI_movelisttolist(&new_entries, &fl_intern->entries);
nbr_entries = flrj->filelist->filelist.nbr_entries;
BLI_mutex_lock(&flrj->lock);
if (flrj->tmp_filelist->filelist.nbr_entries) {
/* We just move everything out of 'thread context' into final list. */
new_nbr_entries = flrj->tmp_filelist->filelist.nbr_entries;
BLI_movelisttolist(&new_entries, &flrj->tmp_filelist->filelist.entries);
flrj->tmp_filelist->filelist.nbr_entries = 0;
}
BLI_mutex_unlock(&flrj->lock);
if (new_nbr_entries) {
/* Do not clear selection cache, we can assume already 'selected' uuids are still valid! */
filelist_clear_ex(flrj->filelist, true, false);
flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING);
}
/* if no new_nbr_entries, this is NOP */
BLI_movelisttolist(&fl_intern->entries, &new_entries);
flrj->filelist->filelist.nbr_entries = nbr_entries + new_nbr_entries;
}
}
static void filelist_readjob_endjob(void *flrjv)
{
FileListReadJob *flrj = flrjv;
/* In case there would be some dangling update... */
filelist_readjob_update(flrjv);
/* In case there would be some dangling update.
* Do not do this in case of ae job returning AE_JOB_ID_INVALID as job_id (immediate execution). */
if (flrj->filelist->ae == NULL || flrj->ae_job_id != AE_JOB_ID_INVALID) {
filelist_readjob_update(flrjv);
}
flrj->filelist->flags &= ~FL_IS_PENDING;
flrj->filelist->flags |= FL_IS_READY;
if (flrj->filelist->ae && !ELEM(flrj->ae_job_id, AE_JOB_ID_INVALID, AE_JOB_ID_UNSET)) {
AssetEngine *ae = flrj->filelist->ae;
ae->type->kill(ae, flrj->ae_job_id);
}
}
static void filelist_readjob_free(void *flrjv)

View File

@@ -37,12 +37,17 @@
extern "C" {
#endif
#include "BKE_asset_engine.h"
struct AssetEngineType;
struct AssetEngine;
struct BlendHandle;
struct FileList;
struct FileSelection;
struct wmWindowManager;
struct FileDirEntry;
struct FileDirEntryArr;
typedef enum FileSelType {
FILE_SEL_REMOVE = 0,
@@ -50,12 +55,6 @@ typedef enum FileSelType {
FILE_SEL_TOGGLE = 2
} FileSelType;
typedef enum FileCheckType {
CHECK_DIRS = 1,
CHECK_FILES = 2,
CHECK_ALL = 3
} FileCheckType;
struct ListBase * folderlist_new(void);
void folderlist_free(struct ListBase *folderlist);
struct ListBase * folderlist_duplicate(ListBase *folderlist);
@@ -66,12 +65,10 @@ int folderlist_clear_next(struct SpaceFile *sfile);
void filelist_setsorting(struct FileList *filelist, const short sort);
void filelist_sort(struct FileList *filelist);
void filelist_setfilter_options(struct FileList *filelist, const bool hide_dot, const bool hide_parent,
const unsigned int filter, const unsigned int filter_id,
const char *filter_glob, const char *filter_search);
void filelist_filter(struct FileList *filelist);
void filelist_sort_filter(struct FileList *filelist, struct FileSelectParams *params);
void filelist_init_icons(void);
void filelist_free_icons(void);
@@ -85,12 +82,14 @@ void filelist_clear(struct FileList *filelist);
void filelist_clear_ex(struct FileList *filelist, const bool do_cache, const bool do_selection);
void filelist_free(struct FileList *filelist);
void filelist_assetengine_set(struct FileList *filelist, struct AssetEngineType *aet);
const char * filelist_dir(struct FileList *filelist);
void filelist_setdir(struct FileList *filelist, char *r_dir);
int filelist_files_ensure(struct FileList *filelist);
int filelist_files_ensure(struct FileList *filelist, struct FileSelectParams *params);
int filelist_empty(struct FileList *filelist);
FileDirEntry * filelist_file(struct FileList *filelist, int index);
struct FileDirEntry *filelist_file(struct FileList *filelist, int index);
int filelist_file_findpath(struct FileList *filelist, const char *file);
FileDirEntry * filelist_entry_find_uuid(struct FileList *filelist, const int uuid[4]);
void filelist_file_cache_slidingwindow_set(struct FileList *filelist, size_t window_size);
@@ -105,6 +104,8 @@ void filelist_entry_select_index_set(struct FileList *filelist, c
void filelist_entries_select_index_range_set(struct FileList *filelist, FileSelection *sel, FileSelType select, unsigned int flag, FileCheckType check);
unsigned int filelist_entry_select_get(struct FileList *filelist, struct FileDirEntry *entry, FileCheckType check);
unsigned int filelist_entry_select_index_get(struct FileList *filelist, const int index, FileCheckType check);
struct FileDirEntryArr *filelist_selection_get(
struct FileList *filelist, FileCheckType check, const char *name, AssetUUIDList **r_uuids, const bool use_ae);
void filelist_setrecursion(struct FileList *filelist, const int recursion_level);
@@ -112,6 +113,8 @@ struct BlendHandle *filelist_lib(struct FileList *filelist);
bool filelist_islibrary(struct FileList *filelist, char *dir, char **group);
void filelist_freelib(struct FileList *filelist);
struct AssetEngine *filelist_assetengine_get(struct FileList *filelist);
void filelist_readjob_start(struct FileList *filelist, const struct bContext *C);
void filelist_readjob_stop(struct wmWindowManager *wm, struct ScrArea *sa);
int filelist_readjob_running(struct wmWindowManager *wm, struct ScrArea *sa);

View File

@@ -501,7 +501,7 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
return;
}
numfiles = filelist_files_ensure(sfile->files);
numfiles = filelist_files_ensure(sfile->files, params);
textheight = (int)file_font_pointsize();
layout = sfile->layout;
layout->textheight = textheight;
@@ -611,7 +611,7 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche
int i;
FileDirEntry *file;
int n = filelist_files_ensure(sfile->files);
int n = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
/* select any file that matches the pattern, this includes exact match
* if the user selects a single file by entering the filename
@@ -687,7 +687,7 @@ int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
/* search if str matches the beginning of name */
if (str[0] && sfile->files) {
AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX);
int nentries = filelist_files_ensure(sfile->files);
int nentries = filelist_files_ensure(sfile->files, ED_fileselect_get_params(sfile));
int i;
for (i = 0; i < nentries; ++i) {

View File

@@ -39,14 +39,15 @@
#include "BLI_utildefines.h"
#include "BLI_fileops_types.h"
#include "RNA_access.h"
#include "RNA_types.h"
#include "BKE_appdir.h"
#include "BKE_asset_engine.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -75,6 +76,8 @@ static SpaceLink *file_new(const bContext *UNUSED(C))
sfile = MEM_callocN(sizeof(SpaceFile), "initfile");
sfile->spacetype = SPACE_FILE;
BKE_asset_engines_get_default(sfile->asset_engine, sizeof(sfile->asset_engine));
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for file");
BLI_addtail(&sfile->regionbase, ar);
@@ -165,6 +168,12 @@ static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
*/
fsmenu_refresh_bookmarks_status(ED_fsmenu_get());
if (!BKE_asset_engines_find(sfile->asset_engine)) {
BKE_asset_engines_get_default(sfile->asset_engine, sizeof(sfile->asset_engine));
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
if (sfile->layout) sfile->layout->dirty = true;
}
@@ -184,7 +193,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
{
SpaceFile *sfileo = (SpaceFile *)sl;
SpaceFile *sfilen = MEM_dupallocN(sl);
/* clear or remove stuff from old */
sfilen->op = NULL; /* file window doesn't own operators */
@@ -212,6 +221,12 @@ static void file_refresh(const bContext *C, ScrArea *sa)
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
struct FSMenu *fsmenu = ED_fsmenu_get();
AssetEngineType *aet = NULL;
if (!STREQ(sfile->asset_engine, AE_FAKE_ENGINE_ID) && (params->type == FILE_LOADLIB)) {
/* Only allow asset engine usage in 'loadlib' (i.e. link/append) case. */
aet = BKE_asset_engines_find(sfile->asset_engine);
}
if (!sfile->folders_prev) {
sfile->folders_prev = folderlist_new();
@@ -220,6 +235,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
sfile->files = filelist_new(params->type);
params->highlight_file = -1; /* added this so it opens nicer (ton) */
}
filelist_assetengine_set(sfile->files, aet);
filelist_setdir(sfile->files, params->dir);
filelist_setrecursion(sfile->files, params->recursion_level);
filelist_setsorting(sfile->files, params->sort);
@@ -247,8 +263,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
}
}
filelist_sort(sfile->files);
filelist_filter(sfile->files);
filelist_sort_filter(sfile->files, params);
if (params->display == FILE_IMGDISPLAY) {
filelist_cache_previews_set(sfile->files, true);

View File

@@ -1568,7 +1568,7 @@ static void outliner_draw_tree_element(
else
offsx += 2 * ufac;
if (tselem->type == 0 && ID_IS_LINKED_DATABLOCK(tselem->id)) {
if (tselem->type == 0 && ID_IS_LINKED(tselem->id)) {
glPixelTransferf(GL_ALPHA_SCALE, 0.5f);
if (tselem->id->tag & LIB_TAG_MISSING) {
UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_BROKEN);
@@ -1579,6 +1579,22 @@ static void outliner_draw_tree_element(
else {
UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_LIBRARY_DATA_DIRECT);
}
if (tselem->id->uuid) {
offsx += UI_UNIT_X;
UI_icon_draw((float)startx + offsx - 0.5f * ufac, (float)*starty + 1.5f * ufac, ICON_SOLO_ON);
if (tselem->id->uuid->tag & UUID_TAG_ENGINE_MISSING) {
UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_GHOST_ENABLED);
}
else if (tselem->id->uuid->tag & UUID_TAG_ASSET_MISSING) {
/* Nothing special (underlying icon is already 'broken' one)... */
}
else if (tselem->id->uuid->tag & UUID_TAG_ASSET_RELOAD) {
UI_icon_draw((float)startx + offsx, (float)*starty + 2 * ufac, ICON_FILE_REFRESH);
}
else {
/* Nothing special (underlying icon is already 'OK' one)... */
}
}
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
offsx += UI_UNIT_X;
}

View File

@@ -435,10 +435,11 @@ static void id_local_cb(
bContext *C, ReportList *UNUSED(reports), Scene *UNUSED(scene), TreeElement *UNUSED(te),
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
{
if (ID_IS_LINKED_DATABLOCK(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
Main *bmain = CTX_data_main(C);
/* if the ID type has no special local function,
* just clear the lib */
* just clear the lib. */
/* XXX This is very, very, **very** suspicious - should not be handled that way at all!!! */
if (id_make_local(bmain, tselem->id, false, false) == false) {
id_clear_lib_data(bmain, tselem->id);
}

View File

@@ -165,3 +165,23 @@ void SCRIPT_OT_autoexec_warn_clear(wmOperatorType *ot)
/* api callbacks */
ot->exec = script_autoexec_warn_clear_exec;
}
static int script_assets_warn_clear_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
{
G.f |= G_ASSETS_QUIET;
return OPERATOR_FINISHED;
}
void SCRIPT_OT_assets_warn_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Silence Assets Warnings";
ot->description = "Ignore assets warning and errors";
ot->idname = "SCRIPT_OT_assets_warn_clear";
/* flags */
ot->flag = OPTYPE_INTERNAL;
/* api callbacks */
ot->exec = script_assets_warn_clear_exec;
}

View File

@@ -41,6 +41,7 @@ void script_keymap(struct wmKeyConfig *keyconf);
void SCRIPT_OT_reload(struct wmOperatorType *ot);
void SCRIPT_OT_python_file_run(struct wmOperatorType *ot);
void SCRIPT_OT_autoexec_warn_clear(struct wmOperatorType *ot);
void SCRIPT_OT_assets_warn_clear(struct wmOperatorType *ot);
#endif /* __SCRIPT_INTERN_H__ */

View File

@@ -45,6 +45,7 @@ void script_operatortypes(void)
WM_operatortype_append(SCRIPT_OT_python_file_run);
WM_operatortype_append(SCRIPT_OT_reload);
WM_operatortype_append(SCRIPT_OT_autoexec_warn_clear);
WM_operatortype_append(SCRIPT_OT_assets_warn_clear);
}
void script_keymap(wmKeyConfig *UNUSED(keyconf))

View File

@@ -106,6 +106,46 @@ enum {
/* add any future new id property types here.*/
/* About Unique identifier.
* Each engine is free to use it as it likes - it will be the only thing passed to it by blender to identify
* asset/variant/version (concatenating the three into a single 48 bytes one).
* Assumed to be 128bits, handled as four integers due to lack of real bytes proptype in RNA :|.
*/
#define ASSET_UUID_LENGTH 16
/* Used to communicate with asset engines outside of 'import' context. */
typedef struct AssetUUID {
int uuid_asset[4];
int uuid_variant[4];
int uuid_revision[4];
short flag; /* Saved. */
short tag; /* Runtime. */
int pad_i1;
} AssetUUID;
/**
* uuid->flag (persitent, saved in .blend files).
*/
enum {
UUID_FLAG_LAST_REVISION = 1 << 0, /* This asset should always use latest available revision. */
};
/**
* uuid->tag (runtime only).
*/
enum {
UUID_TAG_ENGINE_MISSING = 1 << 0, /* The asset engine used for this asset is not known by Blender. */
UUID_TAG_ASSET_MISSING = 1 << 1, /* The asset engine was found but does not know about this asset (anymore). */
UUID_TAG_ASSET_RELOAD = 1 << 8, /* Set by the asset engine to indicates that that asset has to be reloaded. */
};
typedef struct AssetUUIDList {
AssetUUID *uuids;
int nbr_uuids;
int asset_engine_version;
} AssetUUIDList;
/* watch it: Sequence has identical beginning. */
/**
* ID is the first thing included in all serializable types. It
@@ -134,8 +174,42 @@ typedef struct ID {
int us;
int icon_id;
IDProperty *properties;
AssetUUID *uuid;
} ID;
/* Note: Those two structs are for now being runtime-stored in Library datablocks.
* Later it may be interesting to also cache those globally in some ghash...
*/
/**
* An asset reference, storing the uuid and a list of pointers to all used IDs.
* Runtime only currently.
*/
#
#
typedef struct AssetRef {
struct AssetRef *next, *prev;
AssetUUID uuid;
/* Runtime */
ListBase id_list; /* List of pointers to all IDs used by this asset (first one being 'root' one). */
} AssetRef;
/**
* An asset repository reference, storing all that's needed to find the repo, and a list of loaded assets.
* WARNING: this is per library, **not** per asset repo.
*/
typedef struct AssetRepositoryRef {
char asset_engine[64]; /* MAX_ST_NAME */
int asset_engine_version;
int pad_i1;
/* 'Path' to asset engine's root of the reprository, can be an url, whatever... */
char root[768]; /* FILE_MAXDIR */
/* Runtime */
ListBase assets; /* A list of AssetRef assets from this lib. */
} AssetRepositoryRef;
/**
* For each library file used, a Library struct is added to Main
* WARNING: readfile.c, expand_doit() reads this struct without DNA check!
@@ -143,7 +217,8 @@ typedef struct ID {
typedef struct Library {
ID id;
struct FileData *filedata;
char name[1024]; /* path name used for reading, can be relative and edited in the outliner */
/* path name used for reading, can be relative and edited in the outliner. */
char name[1024];
/* absolute filepath, this is only for convenience, 'name' is the real path used on file read but in
* some cases its useful to access the absolute one.
@@ -155,10 +230,20 @@ typedef struct Library {
struct PackedFile *packedfile;
AssetRepositoryRef *asset_repository;
int temp_index;
int _pad;
short flag;
short pad_s1;
} Library;
/* Library.flag */
enum {
/* The library does not actually exist, used to allow handling of files from asset engines. */
LIBRARY_FLAG_VIRTUAL = 1 << 0,
};
enum eIconSizes {
ICON_SIZE_ICON = 0,
ICON_SIZE_PREVIEW = 1,
@@ -269,7 +354,10 @@ typedef struct PreviewImage {
#define ID_MISSING(_id) (((_id)->tag & LIB_TAG_MISSING) != 0)
#define ID_IS_LINKED_DATABLOCK(_id) (((ID *)(_id))->lib != NULL)
#define ID_IS_LINKED(_id) (((ID *)(_id))->lib != NULL)
#define LIB_IS_VIRTUAL(_lib) (((_lib)->flag & LIBRARY_FLAG_VIRTUAL) != 0)
#define ID_IS_LINKED_DATABLOCK(_id) (ID_IS_LINKED(_id) && !LIB_IS_VIRTUAL(((ID *)(_id))->lib))
#define ID_IS_LINKED_DATAPATH(_id) (ID_IS_LINKED(_id) && LIB_IS_VIRTUAL(((ID *)(_id))->lib))
#ifdef GS
# undef GS
@@ -280,8 +368,12 @@ typedef struct PreviewImage {
#define ID_NEW_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
#define ID_NEW_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
#define ID_VIRTUAL_LIBRARY_VALID(_id) (ELEM(GS((_id)->name), ID_IM, ID_VF, ID_TXT, ID_SO))
/* id->flag (persitent). */
enum {
/* Flag asset IDs (the ones who should have a valid uuid). */
LIB_ASSET = 1 << 0,
LIB_FAKEUSER = 1 << 9,
};
@@ -304,6 +396,8 @@ enum {
LIB_TAG_EXTERN = 1 << 0,
/* RESET_NEVER Datablock is from a library, and is only used (linked) inderectly through other libraries. */
LIB_TAG_INDIRECT = 1 << 1,
/* RESET_NEVER Datablock is (or is used by) an asset. */
LIB_TAG_ASSET = 1 << 9,
/* RESET_AFTER_USE Three flags used internally in readfile.c, to mark IDs needing to be read (only done once). */
LIB_TAG_NEED_EXPAND = 1 << 3,

View File

@@ -280,6 +280,7 @@ typedef struct Object {
struct CurveCache *curve_cache;
struct DerivedMesh *derivedDeform, *derivedFinal;
void *pad_v1;
uint64_t lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */
uint64_t customdata_mask; /* (extra) custom data layer mask to use for creating derivedmesh, set by depsgraph */
unsigned int state; /* bit masks of game controllers that are active */

View File

@@ -1591,6 +1591,8 @@ typedef struct Scene {
/* Movie Tracking */
struct MovieClip *clip; /* active movie clip */
void *pad_v1;
uint64_t customdata_mask; /* XXX. runtime flag for drawing, actually belongs in the window, only used by BKE_object_handle_update() */
uint64_t customdata_mask_modal; /* XXX. same as above but for temp operator use (gl renders) */

View File

@@ -629,6 +629,8 @@ typedef struct SpaceFile {
int scroll_offset;
char asset_engine[64]; /* BKE_ST_MAXNAME */
struct FileSelectParams *params; /* config and input for file select */
struct FileList *files; /* holds the list of files to show */
@@ -755,26 +757,6 @@ typedef enum eDirEntry_SelectFlag {
/* ***** Related to file browser, but never saved in DNA, only here to help with RNA. ***** */
/* About Unique identifier.
* Stored in a CustomProps once imported.
* Each engine is free to use it as it likes - it will be the only thing passed to it by blender to identify
* asset/variant/version (concatenating the three into a single 48 bytes one).
* Assumed to be 128bits, handled as four integers due to lack of real bytes proptype in RNA :|.
*/
#define ASSET_UUID_LENGTH 16
/* Used to communicate with asset engines outside of 'import' context. */
typedef struct AssetUUID {
int uuid_asset[4];
int uuid_variant[4];
int uuid_revision[4];
} AssetUUID;
typedef struct AssetUUIDList {
AssetUUID *uuids;
int nbr_uuids, pad;
} AssetUUIDList;
/* Container for a revision, only relevant in asset context. */
typedef struct FileDirEntryRevision {
struct FileDirEntryRevision *next, *prev;
@@ -848,7 +830,6 @@ typedef struct FileDirEntryArr {
ListBase entries;
int nbr_entries;
int nbr_entries_filtered;
int entry_idx_start, entry_idx_end;
char root[1024]; /* FILE_MAX */
} FileDirEntryArr;

View File

@@ -62,6 +62,7 @@ typedef struct Text {
int undo_pos, undo_len;
void *compiled;
void *pad_v1;
double mtime;
} Text;

View File

@@ -71,6 +71,12 @@ extern StructRNA RNA_Armature;
extern StructRNA RNA_ArmatureModifier;
extern StructRNA RNA_ArmatureSensor;
extern StructRNA RNA_ArrayModifier;
extern StructRNA RNA_AssetEngine;
extern StructRNA RNA_AssetEntry;
extern StructRNA RNA_AssetList;
extern StructRNA RNA_AssetRevision;
extern StructRNA RNA_AssetUUID;
extern StructRNA RNA_AssetVariant;
extern StructRNA RNA_BackgroundImage;
extern StructRNA RNA_BevelModifier;
extern StructRNA RNA_SplinePoint;

View File

@@ -36,6 +36,7 @@ set(DEFSRC
rna_animation.c
rna_animviz.c
rna_armature.c
rna_asset.c
rna_boid.c
rna_brush.c
rna_camera.c

View File

@@ -3299,6 +3299,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_animviz.c", NULL, RNA_def_animviz},
{"rna_actuator.c", "rna_actuator_api.c", RNA_def_actuator},
{"rna_armature.c", "rna_armature_api.c", RNA_def_armature},
{"rna_asset.c", NULL, RNA_def_asset},
{"rna_boid.c", NULL, RNA_def_boid},
{"rna_brush.c", NULL, RNA_def_brush},
{"rna_camera.c", "rna_camera_api.c", RNA_def_camera},

View File

@@ -716,6 +716,29 @@ static PointerRNA rna_IDPreview_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_ImagePreview, prv_img);
}
static void rna_ID_asset_dependencies_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
ID *id = ptr->data;
if (id->uuid && id->lib) {
AssetRef *aref = BKE_library_asset_repository_asset_find(id->lib, id);
if (aref) {
rna_iterator_listbase_begin(iter, &aref->id_list, NULL);
return;
}
}
rna_iterator_listbase_begin(iter, NULL, NULL);
}
static PointerRNA rna_ID_asset_dependencies_get(CollectionPropertyIterator *iter)
{
ListBaseIterator *internal = &iter->internal.listbase;
PointerRNA ptr;
RNA_id_pointer_create((ID *)((LinkData *)internal->link)->data, &ptr);
return ptr;
}
#else
static void rna_def_ID_properties(BlenderRNA *brna)
@@ -978,6 +1001,20 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_funcs(prop, "rna_IDPreview_get", NULL, NULL, NULL);
/* XXX Not sure we actually want those two in our RNA in the end.
* But at least for now, they are important debug tools! */
prop = RNA_def_pointer(srna, "asset_uuid", "AssetUUID", "Asset UUID",
"Unique identifier of the asset represented by that ID (NULL if not an asset)");
RNA_def_property_pointer_sdna(prop, NULL, "uuid");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_collection(srna, "asset_dependencies", "ID", "Asset Dependencies",
"A list of all IDs used by this asset");
RNA_def_property_collection_funcs(prop, "rna_ID_asset_dependencies_begin", "rna_iterator_listbase_next",
"rna_iterator_listbase_end", "rna_ID_asset_dependencies_get",
NULL, NULL, NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
/* functions */
func = RNA_def_function(srna, "copy", "rna_ID_copy");
RNA_def_function_ui_description(func, "Create a copy of this data-block (not supported for all data-blocks)");

File diff suppressed because it is too large Load Diff

View File

@@ -130,6 +130,7 @@ void RNA_def_action(struct BlenderRNA *brna);
void RNA_def_animation(struct BlenderRNA *brna);
void RNA_def_animviz(struct BlenderRNA *brna);
void RNA_def_armature(struct BlenderRNA *brna);
void RNA_def_asset(struct BlenderRNA *brna);
void RNA_def_actuator(struct BlenderRNA *brna);
void RNA_def_boid(struct BlenderRNA *brna);
void RNA_def_brush(struct BlenderRNA *brna);

View File

@@ -31,6 +31,11 @@
#include "BLT_translation.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "BKE_asset_engine.h"
#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_movieclip.h"
@@ -46,9 +51,6 @@
#include "DNA_mask_types.h"
#include "DNA_view3d_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "rna_internal.h"
#include "WM_api.h"
@@ -247,9 +249,11 @@ EnumPropertyItem rna_enum_file_sort_items[] = {
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BKE_animsys.h"
#include "BKE_asset_engine.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -1603,6 +1607,47 @@ static EnumPropertyItem *rna_FileSelectParams_recursion_level_itemf(
return fileselectparams_recursion_level_items;
}
static int rna_FileBrowser_AE_type_enum_get(PointerRNA *ptr)
{
SpaceFile *sf = ptr->data;
return BLI_findstringindex(&asset_engines, sf->asset_engine, offsetof(AssetEngineType, idname));
}
static void rna_FileBrowser_AE_type_enum_set(PointerRNA *ptr, const int value)
{
SpaceFile *sf = ptr->data;
AssetEngineType *aet = BLI_findlink(&asset_engines, value);
if (aet) {
BLI_strncpy(sf->asset_engine, aet->idname, sizeof(sf->asset_engine));
}
}
static EnumPropertyItem *rna_FileBrowser_AE_type_enum_itemf(
bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
{
EnumPropertyItem *items = NULL;
AssetEngineType *aet = NULL;
int totitem = 0;
for (aet = asset_engines.first; aet; aet = aet->next) {
EnumPropertyItem item = {totitem, aet->idname, 0, aet->name, ""};
RNA_enum_item_add(&items, &totitem, &item);
}
RNA_enum_item_end(&items, &totitem);
*r_free = true;
return items;
}
static PointerRNA rna_FileBrowser_AE_ptr_get(PointerRNA *ptr)
{
SpaceFile *sfile = ptr->data;
AssetEngine *ae = ED_filelist_assetengine_get(sfile);
return rna_pointer_inherit_refine(ptr, &RNA_AssetEngine, ae);
}
static void rna_FileBrowser_FSMenuEntry_path_get(PointerRNA *ptr, char *value)
{
char *path = ED_fsmenu_entry_get_path(ptr->data);
@@ -4034,10 +4079,29 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem asset_engine_items[] = {
{0, AE_FAKE_ENGINE_ID, 0, "None", ""},
{0, NULL, 0, NULL, NULL}
};
srna = RNA_def_struct(brna, "SpaceFileBrowser", "Space");
RNA_def_struct_sdna(srna, "SpaceFile");
RNA_def_struct_ui_text(srna, "Space File Browser", "File browser space data");
prop = RNA_def_property(srna, "asset_engine_type", PROP_ENUM, PROP_NONE);
RNA_def_property_ui_text(prop, "Asset Engine Type", "Active asset engine type");
RNA_def_property_enum_items(prop, asset_engine_items);
RNA_def_property_enum_funcs(prop, "rna_FileBrowser_AE_type_enum_get", "rna_FileBrowser_AE_type_enum_set",
"rna_FileBrowser_AE_type_enum_itemf");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
prop = RNA_def_property(srna, "asset_engine", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Asset Engine", "Active asset engine");
RNA_def_property_struct_type(prop, "AssetEngine");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_funcs(prop, "rna_FileBrowser_AE_ptr_get", NULL, NULL, NULL);
prop = RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "params");
RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser");

View File

@@ -1648,6 +1648,16 @@ static void rna_def_operator_filelist_element(BlenderRNA *brna)
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_FILENAME);
RNA_def_property_flag(prop, PROP_IDPROPERTY);
RNA_def_property_ui_text(prop, "Name", "Name of a file or directory within a file list");
prop = RNA_def_int_vector(srna, "asset_uuid", 4, NULL, INT_MIN, INT_MAX,
"Asset UUID", "Identifier of this item in current asset engine", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_IDPROPERTY);
prop = RNA_def_int_vector(srna, "variant_uuid", 4, NULL, INT_MIN, INT_MAX,
"Variant UUID", "Identifier of this item's variant in current asset engine", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_IDPROPERTY);
prop = RNA_def_int_vector(srna, "revision_uuid", 4, NULL, INT_MIN, INT_MAX,
"Revision UUID", "Identifier of this item's revision in current asset engine", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_IDPROPERTY);
}
static void rna_def_event(BlenderRNA *brna)

View File

@@ -350,7 +350,14 @@ static PyGetSetDef bpy_app_getsets[] = {
{(char *)"autoexec_fail", bpy_app_global_flag_get, NULL, NULL, (void *)G_SCRIPT_AUTOEXEC_FAIL},
{(char *)"autoexec_fail_quiet", bpy_app_global_flag_get, NULL, NULL, (void *)G_SCRIPT_AUTOEXEC_FAIL_QUIET},
{(char *)"autoexec_fail_message", bpy_app_autoexec_fail_message_get, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}
/* Assets */
{(char *)"assets_need_reload", bpy_app_global_flag_get, NULL, NULL, (void *)G_ASSETS_NEED_RELOAD},
{(char *)"assets_fail", bpy_app_global_flag_get, NULL, NULL, (void *)G_ASSETS_FAIL},
{(char *)"assets_quiet", bpy_app_global_flag_get, NULL, NULL, (void *)G_ASSETS_QUIET},
// {(char *)"assets_fail_message", bpy_app_autoexec_fail_message_get, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
static void py_struct_seq_getset_init(void)

View File

@@ -7832,7 +7832,7 @@ PyDoc_STRVAR(pyrna_register_class_doc,
" Register a subclass of a blender type in (:class:`bpy.types.Panel`,\n"
" :class:`bpy.types.UIList`, :class:`bpy.types.Menu`, :class:`bpy.types.Header`,\n"
" :class:`bpy.types.Operator`, :class:`bpy.types.KeyingSetInfo`,\n"
" :class:`bpy.types.RenderEngine`).\n"
" :class:`bpy.types.RenderEngine`, :class:`bpy.types.AssetEngine`).\n"
"\n"
" If the class has a *register* class method it will be called\n"
" before registration.\n"

View File

@@ -443,6 +443,7 @@ enum {
WM_JOB_TYPE_SEQ_BUILD_PREVIEW,
WM_JOB_TYPE_POINTCACHE,
WM_JOB_TYPE_DPAINT_BAKE,
WM_JOB_TYPE_ASSET_UPDATECHECK,
/* add as needed, screencast, seq proxy build
* if having hard coded values is a problem */
};

View File

@@ -50,6 +50,9 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "RNA_access.h"
#include "BKE_asset_engine.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_global.h"
@@ -66,8 +69,6 @@
#include "ED_view3d.h"
#include "ED_util.h"
#include "RNA_access.h"
#include "GPU_debug.h"
#include "UI_interface.h"

View File

@@ -554,7 +554,11 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
/* confusing this global... */
G.relbase_valid = 1;
retval = BKE_blendfile_read(C, filepath, reports);
retval = BKE_blendfile_read(C, filepath, reports);
printf("Updating assets for: %s\n", filepath);
WM_operator_name_call(C, "WM_OT_assets_update_check", WM_OP_EXEC_DEFAULT, NULL);
/* when loading startup.blend's, we can be left with a blank path */
if (G.main->name[0]) {
G.save_over = 1;
@@ -694,6 +698,9 @@ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const c
if (!from_memory) {
if (BLI_access(startstr, R_OK) == 0) {
success = (BKE_blendfile_read(C, startstr, NULL) != BKE_BLENDFILE_READ_FAIL);
printf("Updating assets for: %s\n", startstr);
WM_operator_name_call(C, "WM_OT_assets_update_check", WM_OP_EXEC_DEFAULT, NULL);
}
if (BLI_listbase_is_empty(&U.themes)) {
if (G.debug & G_DEBUG)

View File

@@ -44,9 +44,11 @@
#include "DNA_ID.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "BLI_blenlib.h"
#include "BLI_bitmap.h"
@@ -56,16 +58,21 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "PIL_time.h"
#include "BLO_readfile.h"
#include "BKE_asset_engine.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h" /* BKE_ST_MAXNAME */
#include "BKE_idcode.h"
@@ -73,13 +80,10 @@
#include "IMB_colormanagement.h"
#include "ED_screen.h"
#include "ED_fileselect.h"
#include "GPU_material.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -144,6 +148,7 @@ static short wm_link_append_flag(wmOperator *op)
}
typedef struct WMLinkAppendDataItem {
AssetUUID *uuid;
char *name;
BLI_bitmap *libraries; /* All libs (from WMLinkAppendData.libraries) to try to load this ID from. */
short idcode;
@@ -153,6 +158,7 @@ typedef struct WMLinkAppendDataItem {
} WMLinkAppendDataItem;
typedef struct WMLinkAppendData {
const char *root;
LinkNodePair libraries;
LinkNodePair items;
int num_libraries;
@@ -192,11 +198,18 @@ static void wm_link_append_data_library_add(WMLinkAppendData *lapp_data, const c
}
static WMLinkAppendDataItem *wm_link_append_data_item_add(
WMLinkAppendData *lapp_data, const char *idname, const short idcode, void *customdata)
WMLinkAppendData *lapp_data, const char *idname, const short idcode, const AssetUUID *uuid, void *customdata)
{
WMLinkAppendDataItem *item = BLI_memarena_alloc(lapp_data->memarena, sizeof(*item));
size_t len = strlen(idname) + 1;
const size_t len = strlen(idname) + 1;
if (uuid) {
item->uuid = BLI_memarena_alloc(lapp_data->memarena, sizeof(*item->uuid));
*item->uuid = *uuid;
}
else {
item->uuid = NULL;
}
item->name = BLI_memarena_alloc(lapp_data->memarena, len);
BLI_strncpy(item->name, idname, len);
item->idcode = idcode;
@@ -211,8 +224,80 @@ static WMLinkAppendDataItem *wm_link_append_data_item_add(
return item;
}
static int path_to_idcode(const char *path)
{
const int filetype = ED_path_extension_type(path);
switch (filetype) {
case FILE_TYPE_IMAGE:
case FILE_TYPE_MOVIE:
return ID_IM;
case FILE_TYPE_FTFONT:
return ID_VF;
case FILE_TYPE_SOUND:
return ID_SO;
case FILE_TYPE_PYSCRIPT:
case FILE_TYPE_TEXT:
return ID_TXT;
default:
return 0;
}
}
static void wm_link_virtual_lib(WMLinkAppendData *lapp_data, Main *bmain, AssetEngineType *aet, const int lib_idx)
{
LinkNode *itemlink;
int item_idx;
BLI_assert(aet);
/* Find or add virtual library matching current asset engine. */
Library *virtlib = BKE_library_asset_virtual_ensure(bmain, aet);
for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
WMLinkAppendDataItem *item = itemlink->link;
ID *new_id = NULL;
bool id_exists = false;
if (!BLI_BITMAP_TEST(item->libraries, lib_idx)) {
continue;
}
switch (item->idcode) {
case ID_IM:
new_id = (ID *)BKE_image_load_exists_ex(item->name, &id_exists);
if (id_exists) {
if (!new_id->uuid || !ASSETUUID_COMPARE(new_id->uuid, item->uuid)) {
/* Fake 'same ID' (same path, but different uuid or whatever), force loading into new ID. */
BLI_assert(new_id->lib != virtlib);
new_id = (ID *)BKE_image_load(bmain, item->name);
id_exists = false;
}
}
break;
default:
break;
}
if (new_id) {
new_id->lib = virtlib;
new_id->tag |= LIB_TAG_EXTERN | LIB_ASSET;
if (!id_exists) {
new_id->uuid = MEM_mallocN(sizeof(*new_id->uuid), __func__);
*new_id->uuid = *item->uuid;
}
/* If the link is sucessful, clear item's libs 'todo' flags.
* This avoids trying to link same item with other libraries to come. */
BLI_BITMAP_SET_ALL(item->libraries, false, lapp_data->num_libraries);
item->new_id = new_id;
}
}
BKE_libraries_asset_repositories_rebuild(bmain);
}
static void wm_link_do(
WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d,
WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, AssetEngineType *aet, Scene *scene, View3D *v3d,
const bool use_placeholders, const bool force_indirect)
{
Main *mainl;
@@ -229,6 +314,12 @@ static void wm_link_do(
for (lib_idx = 0, liblink = lapp_data->libraries.list; liblink; lib_idx++, liblink = liblink->next) {
char *libname = liblink->link;
if (libname[0] == '\0') {
/* Special 'virtual lib' cases. */
wm_link_virtual_lib(lapp_data, bmain, aet, lib_idx);
continue;
}
bh = BLO_blendhandle_from_file(libname, reports);
if (bh == NULL) {
@@ -260,8 +351,9 @@ static void wm_link_do(
continue;
}
new_id = BLO_library_link_named_part_ex(
mainl, &bh, item->idcode, item->name, flag, scene, v3d, use_placeholders, force_indirect);
new_id = BLO_library_link_named_part_asset(
mainl, &bh, aet, lapp_data->root, item->idcode, item->name, item->uuid, flag, scene, v3d,
use_placeholders, force_indirect);
if (new_id) {
/* If the link is successful, clear item's libs 'todo' flags.
@@ -287,21 +379,30 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
int totfiles = 0;
short flag;
char asset_engine[BKE_ST_MAXNAME];
AssetEngineType *aet = NULL;
AssetUUID uuid = {0};
RNA_string_get(op->ptr, "filename", relname);
RNA_string_get(op->ptr, "directory", root);
BLI_join_dirfile(path, sizeof(path), root, relname);
RNA_string_get(op->ptr, "asset_engine", asset_engine);
if (asset_engine[0] != '\0') {
aet = BKE_asset_engines_find(asset_engine);
}
/* test if we have a valid data */
if (!BLO_library_path_explode(path, libname, &group, &name)) {
if (!BLO_library_path_explode(path, libname, &group, &name) && (!aet || !path_to_idcode(path))) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path);
return OPERATOR_CANCELLED;
}
else if (!group) {
else if (!group && !aet) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path);
return OPERATOR_CANCELLED;
}
else if (BLI_path_cmp(bmain->name, libname) == 0) {
else if (libname[0] && BLI_path_cmp(bmain->name, libname) == 0) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path);
return OPERATOR_CANCELLED;
}
@@ -347,6 +448,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* We define our working data...
* Note that here, each item 'uses' one library, and only one. */
lapp_data = wm_link_append_data_new(flag);
lapp_data->root = root;
if (totfiles != 0) {
GHash *libraries = BLI_ghash_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
int lib_idx = 0;
@@ -368,6 +470,14 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
wm_link_append_data_library_add(lapp_data, libname);
}
}
/* Non-blend paths are only valid in asset engine context (virtual libraries). */
else if (aet && path_to_idcode(path)) {
if (!BLI_ghash_haskey(libraries, "")) {
BLI_ghash_insert(libraries, BLI_strdup(""), SET_INT_IN_POINTER(lib_idx));
lib_idx++;
wm_link_append_data_library_add(lapp_data, "");
}
}
}
RNA_END;
@@ -386,26 +496,47 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
lib_idx = GET_INT_FROM_POINTER(BLI_ghash_lookup(libraries, libname));
item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL);
if (aet) {
RNA_int_get_array(&itemptr, "asset_uuid", uuid.uuid_asset);
RNA_int_get_array(&itemptr, "variant_uuid", uuid.uuid_variant);
RNA_int_get_array(&itemptr, "revision_uuid", uuid.uuid_revision);
}
item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), &uuid, NULL);
BLI_BITMAP_ENABLE(item->libraries, lib_idx);
}
else if (aet) { /* Non-blend paths are only valid in asset engine context (virtual libraries). */
const int idcode = path_to_idcode(path);
if (idcode != 0) {
WMLinkAppendDataItem *item;
lib_idx = GET_INT_FROM_POINTER(BLI_ghash_lookup(libraries, ""));
RNA_int_get_array(&itemptr, "asset_uuid", uuid.uuid_asset);
RNA_int_get_array(&itemptr, "variant_uuid", uuid.uuid_variant);
RNA_int_get_array(&itemptr, "revision_uuid", uuid.uuid_revision);
item = wm_link_append_data_item_add(lapp_data, path, idcode, &uuid, NULL);
BLI_BITMAP_ENABLE(item->libraries, lib_idx);
}
}
}
RNA_END;
BLI_ghash_free(libraries, MEM_freeN, NULL);
}
else {
else if (group && name) {
WMLinkAppendDataItem *item;
wm_link_append_data_library_add(lapp_data, libname);
item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL);
item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), &uuid, NULL);
BLI_BITMAP_ENABLE(item->libraries, 0);
}
/* XXX We'd need re-entrant locking on Main for this to work... */
/* BKE_main_lock(bmain); */
wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C), false, false);
wm_link_do(lapp_data, op->reports, bmain, aet, scene, CTX_wm_view3d(C), false, false);
/* BKE_main_unlock(bmain); */
@@ -465,6 +596,10 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
/* better not save _any_ settings for this operator */
/* properties */
prop = RNA_def_string(ot->srna, "asset_engine", NULL, sizeof(((AssetEngineType *)NULL)->idname),
"Asset Engine", "Asset engine identifier used to append/link the data");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
prop = RNA_def_boolean(ot->srna, "link", is_link,
"Link", "Link the objects or datablocks rather than appending");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
@@ -541,6 +676,11 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN
"Cannot relocate indirectly linked library '%s'", lib->filepath);
return OPERATOR_CANCELLED;
}
if (lib->flag & LIBRARY_FLAG_VIRTUAL) {
BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT,
"Cannot relocate virtual library '%s'", lib->id.name + 2);
return OPERATOR_CANCELLED;
}
RNA_string_set(op->ptr, "filepath", lib->filepath);
WM_event_add_fileselect(C, op);
@@ -551,9 +691,13 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN
return OPERATOR_CANCELLED;
}
/**
* \param library if given, all IDs from that library will be removed and reloaded. Otherwise, IDs must have already
* been removed from \a bmain, and added to \a lapp_data.
*/
static void lib_relocate_do(
Main *bmain, Scene *scene,
Library *library, WMLinkAppendData *lapp_data, ReportList *reports, const bool do_reload)
Library *library, WMLinkAppendData *lapp_data, ReportList *reports, AssetEngineType *aet, const bool do_reload)
{
ListBase *lbarray[MAX_LIBARRAY];
int lba_idx;
@@ -562,29 +706,31 @@ static void lib_relocate_do(
int item_idx;
/* Remove all IDs to be reloaded from Main. */
lba_idx = set_listbasepointers(bmain, lbarray);
while (lba_idx--) {
ID *id = lbarray[lba_idx]->first;
const short idcode = id ? GS(id->name) : 0;
if (library) {
lba_idx = set_listbasepointers(bmain, lbarray);
while (lba_idx--) {
ID *id = lbarray[lba_idx]->first;
const short idcode = id ? GS(id->name) : 0;
if (!id || !BKE_idcode_is_linkable(idcode)) {
/* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */
continue;
}
if (!id || !BKE_idcode_is_linkable(idcode)) {
/* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */
continue;
}
for (; id; id = id->next) {
if (id->lib == library) {
WMLinkAppendDataItem *item;
for (; id; id = id->next) {
if (id->lib == library) {
WMLinkAppendDataItem *item;
/* We remove it from current Main, and add it to items to link... */
/* Note that non-linkable IDs (like e.g. shapekeys) are also explicitely linked here... */
BLI_remlink(lbarray[lba_idx], id);
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id);
BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries);
/* We remove it from current Main, and add it to items to link... */
/* Note that non-linkable IDs (like e.g. shapekeys) are also explicitely linked here... */
BLI_remlink(lbarray[lba_idx], id);
item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, NULL, id);
BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries);
#ifdef PRINT_DEBUG
printf("\tdatablock to seek for: %s\n", id->name);
printf("\tdatablock to seek for: %s\n", id->name);
#endif
}
}
}
}
@@ -592,7 +738,7 @@ static void lib_relocate_do(
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
/* We do not want any instanciation here! */
wm_link_do(lapp_data, reports, bmain, NULL, NULL, do_reload, do_reload);
wm_link_do(lapp_data, reports, bmain, aet, NULL, NULL, do_reload, do_reload);
BKE_main_lock(bmain);
@@ -759,7 +905,7 @@ void WM_lib_reload(Library *lib, bContext *C, ReportList *reports)
wm_link_append_data_library_add(lapp_data, lib->filepath);
lib_relocate_do(CTX_data_main(C), CTX_data_scene(C), lib, lapp_data, reports, true);
lib_relocate_do(CTX_data_main(C), CTX_data_scene(C), lib, lapp_data, reports, NULL, true);
wm_link_append_data_free(lapp_data);
@@ -792,6 +938,11 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
"Cannot relocate indirectly linked library '%s'", lib->filepath);
return OPERATOR_CANCELLED;
}
if (lib->flag & LIBRARY_FLAG_VIRTUAL) {
BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT,
"Cannot relocate or reload virtual library '%s'", lib->id.name + 2);
return OPERATOR_CANCELLED;
}
RNA_string_get(op->ptr, "directory", root);
RNA_string_get(op->ptr, "filename", libname);
@@ -866,7 +1017,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload)
}
}
lib_relocate_do(bmain, scene, lib, lapp_data, op->reports, do_reload);
lib_relocate_do(bmain, scene, lib, lapp_data, op->reports, NULL, do_reload);
wm_link_append_data_free(lapp_data);
@@ -934,4 +1085,451 @@ void WM_OT_lib_reload(wmOperatorType *ot)
FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
}
/** \name Asset-related operators.
*
* \{ */
typedef struct AssetUpdateCheckEngine {
struct AssetUpdateCheckEngine *next, *prev;
AssetEngine *ae;
/* Note: We cannot store IDs themselves in non-locking async task... so we'll have to check again for
* UUID/IDs mapping on each update call... Not ideal, but don't think it will be that big of a bottleneck
* in practice. */
AssetUUIDList uuids;
int allocated_uuids;
int ae_job_id;
short status;
} AssetUpdateCheckEngine;
typedef struct AssetUpdateCheckJob {
ListBase engines;
short flag;
float *progress;
short *stop;
} AssetUpdateCheckJob;
/* AssetUpdateCheckEngine.status */
enum {
AUCE_UPDATE_CHECK_DONE = 1 << 0, /* Update check is finished for this engine. */
AUCE_ENSURE_ASSETS_DONE = 1 << 1, /* Asset ensure is finished for this engine (if applicable). */
};
/* AssetUpdateCheckJob.flag */
enum {
AUCJ_ENSURE_ASSETS = 1 << 0, /* Try to perform the 'ensure' task too. */
};
/* Helper to fetch a set of assets to handle, regrouped by asset engine. */
static void asset_update_engines_uuids_fetch(
ListBase *engines,
Main *bmain, AssetUUIDList *uuids, const short uuid_tags,
const bool do_reset_tags)
{
for (Library *lib = bmain->library.first; lib; lib = lib->id.next) {
if (lib->asset_repository) {
printf("Checking lib file '%s' (engine %s, ver. %d)\n", lib->filepath,
lib->asset_repository->asset_engine, lib->asset_repository->asset_engine_version);
AssetUpdateCheckEngine *auce = NULL;
AssetEngineType *ae_type = BKE_asset_engines_find(lib->asset_repository->asset_engine);
bool copy_engine = false;
if (ae_type == NULL) {
printf("ERROR! Unknown asset engine!\n");
}
for (AssetRef *aref = lib->asset_repository->assets.first; aref; aref = aref->next) {
ID *id = ((LinkData *)aref->id_list.first)->data;
BLI_assert(id->uuid);
if (uuid_tags && !(id->uuid->tag & uuid_tags)) {
continue;
}
if (uuids) {
int i = uuids->nbr_uuids;
bool skip = true;
for (AssetUUID *uuid = uuids->uuids; i--; uuid++) {
if (ASSETUUID_COMPARE(id->uuid, uuid)) {
skip = false;
break;
}
}
if (skip) {
continue;
}
}
if (ae_type == NULL) {
if (do_reset_tags) {
id->uuid->tag = UUID_TAG_ENGINE_MISSING;
}
else {
id->uuid->tag |= UUID_TAG_ENGINE_MISSING;
}
G.f |= G_ASSETS_FAIL;
continue;
}
if (auce == NULL) {
for (auce = engines->first; auce; auce = auce->next) {
if (auce->ae->type == ae_type) {
/* In case we have several engine versions for the same engine, we create several
* AssetUpdateCheckEngine structs (since an uuid list can only handle one ae version), using
* the same (shallow) copy of the actual asset engine. */
copy_engine = (auce->uuids.asset_engine_version != lib->asset_repository->asset_engine_version);
break;
}
}
if (copy_engine || auce == NULL) {
AssetUpdateCheckEngine *auce_prev = auce;
auce = MEM_callocN(sizeof(*auce), __func__);
auce->ae = copy_engine ? BKE_asset_engine_copy(auce_prev->ae) :
BKE_asset_engine_create(ae_type, NULL);
auce->ae_job_id = AE_JOB_ID_UNSET;
auce->uuids.asset_engine_version = lib->asset_repository->asset_engine_version;
BLI_addtail(engines, auce);
}
}
printf("\tWe need to check for updated asset %s...\n", id->name);
if (do_reset_tags) {
id->uuid->tag = (id->tag & LIB_TAG_MISSING) ? UUID_TAG_ASSET_MISSING : 0;
}
auce->uuids.nbr_uuids++;
BKE_asset_uuid_print(id->uuid);
if (auce->uuids.nbr_uuids > auce->allocated_uuids) {
auce->allocated_uuids += 16;
BLI_assert(auce->uuids.nbr_uuids < auce->allocated_uuids);
const size_t allocsize = sizeof(*auce->uuids.uuids) * (size_t)auce->allocated_uuids;
auce->uuids.uuids = auce->uuids.uuids ?
MEM_reallocN_id(auce->uuids.uuids, allocsize, __func__) :
MEM_mallocN(allocsize, __func__);
}
auce->uuids.uuids[auce->uuids.nbr_uuids - 1] = *id->uuid;
}
}
}
}
static void asset_updatecheck_startjob(void *aucjv, short *stop, short *do_update, float *progress)
{
AssetUpdateCheckJob *aucj = aucjv;
aucj->progress = progress;
aucj->stop = stop;
/* Using AE engine, worker thread here is just sleeping! */
while (!*stop) {
*do_update = true;
PIL_sleep_ms(100);
}
}
static void asset_updatecheck_update(void *aucjv)
{
AssetUpdateCheckJob *aucj = aucjv;
Main *bmain = G.main;
const bool do_ensure = ((aucj->flag & AUCJ_ENSURE_ASSETS) != 0);
bool is_finished = true;
int nbr_engines = 0;
*aucj->progress = 0.0f;
/* TODO need to take care of 'broken' engines that error - in this case we probably want to cancel the whole
* update process over effected libraries' data... */
for (AssetUpdateCheckEngine *auce = aucj->engines.first; auce; auce = auce->next, nbr_engines++) {
AssetEngine *ae = auce->ae;
AssetEngineType *ae_type = ae->type;
/* Step 1: we ask asset engine about status of all asset IDs from it. */
if (!(auce->status & AUCE_UPDATE_CHECK_DONE)) {
auce->ae_job_id = ae_type->update_check(ae, auce->ae_job_id, &auce->uuids);
if (auce->ae_job_id == AE_JOB_ID_INVALID) { /* Immediate execution. */
*aucj->progress += 1.0f;
auce->status |= AUCE_UPDATE_CHECK_DONE;
}
else {
*aucj->progress += ae_type->progress(ae, auce->ae_job_id);
if ((ae_type->status(ae, auce->ae_job_id) & (AE_STATUS_RUNNING | AE_STATUS_VALID)) !=
(AE_STATUS_RUNNING | AE_STATUS_VALID))
{
auce->status |= AUCE_UPDATE_CHECK_DONE;
}
}
if (auce->status & AUCE_UPDATE_CHECK_DONE) {
auce->ae_job_id = AE_JOB_ID_UNSET;
for (Library *lib = bmain->library.first; lib; lib = lib->id.next) {
if (!lib->asset_repository ||
(BKE_asset_engines_find(lib->asset_repository->asset_engine) != ae_type))
{
continue;
}
/* UUIDs returned by update_check are assumed to be valid (one way or the other) in current
* asset engine version. */
lib->asset_repository->asset_engine_version = ae_type->version;
int i = auce->uuids.nbr_uuids;
for (AssetUUID *uuid = auce->uuids.uuids; i--; uuid++) {
for (AssetRef *aref = lib->asset_repository->assets.first; aref; aref = aref->next) {
ID *id = ((LinkData *)aref->id_list.first)->data;
BLI_assert(id->uuid);
if (ASSETUUID_COMPARE(id->uuid, uuid)) {
*id->uuid = *uuid;
if (id->uuid->tag & UUID_TAG_ENGINE_MISSING) {
G.f |= G_ASSETS_FAIL;
printf("\t%s uses a currently unknown asset engine!\n", id->name);
}
else if (id->uuid->tag & UUID_TAG_ASSET_MISSING) {
G.f |= G_ASSETS_FAIL;
printf("\t%s is currently unknown by asset engine!\n", id->name);
}
else if (id->uuid->tag & UUID_TAG_ASSET_RELOAD) {
G.f |= G_ASSETS_NEED_RELOAD;
printf("\t%s needs to be reloaded/updated!\n", id->name);
}
break;
}
}
}
}
}
}
/* Step 2: If required and supported, we 'ensure' assets tagged as to be reloaded. */
if (do_ensure && !(auce->status & AUCE_ENSURE_ASSETS_DONE) && ae_type->ensure_uuids != NULL) {
/* TODO ensure entries! */
*aucj->progress += 1.0f;
auce->status |= AUCE_ENSURE_ASSETS_DONE;
if (auce->status & AUCE_ENSURE_ASSETS_DONE) {
auce->ae_job_id = AE_JOB_ID_UNSET;
}
}
if ((auce->status & (AUCE_UPDATE_CHECK_DONE | AUCE_ENSURE_ASSETS_DONE)) !=
(AUCE_UPDATE_CHECK_DONE | AUCE_ENSURE_ASSETS_DONE))
{
is_finished = false;
}
}
*aucj->progress /= (float)(do_ensure ? nbr_engines * 2 : nbr_engines);
*aucj->stop = is_finished;
}
static void asset_updatecheck_endjob(void *aucjv)
{
AssetUpdateCheckJob *aucj = aucjv;
/* In case there would be some dangling update. */
asset_updatecheck_update(aucjv);
for (AssetUpdateCheckEngine *auce = aucj->engines.first; auce; auce = auce->next) {
AssetEngine *ae = auce->ae;
if (!ELEM(auce->ae_job_id, AE_JOB_ID_INVALID, AE_JOB_ID_UNSET)) {
ae->type->kill(ae, auce->ae_job_id);
}
}
}
static void asset_updatecheck_free(void *aucjv)
{
AssetUpdateCheckJob *aucj = aucjv;
for (AssetUpdateCheckEngine *auce = aucj->engines.first; auce; auce = auce->next) {
BKE_asset_engine_free(auce->ae);
MEM_freeN(auce->uuids.uuids);
}
BLI_freelistN(&aucj->engines);
MEM_freeN(aucj);
}
static void asset_updatecheck_start(const bContext *C)
{
wmJob *wm_job;
AssetUpdateCheckJob *aucj;
Main *bmain = CTX_data_main(C);
/* prepare job data */
aucj = MEM_callocN(sizeof(*aucj), __func__);
G.f &= ~(G_ASSETS_FAIL | G_ASSETS_NEED_RELOAD | G_ASSETS_QUIET);
/* Get all assets' uuids, grouped by asset engine/versions - and with cleared status tags. */
asset_update_engines_uuids_fetch(&aucj->engines, bmain, NULL, 0, true);
/* Early out if there is nothing to do! */
if (BLI_listbase_is_empty(&aucj->engines)) {
asset_updatecheck_free(aucj);
return;
}
/* setup job */
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_area(C), "Checking for asset updates...",
WM_JOB_PROGRESS, WM_JOB_TYPE_ASSET_UPDATECHECK);
WM_jobs_customdata_set(wm_job, aucj, asset_updatecheck_free);
WM_jobs_timer(wm_job, 0.1, 0, 0/*NC_SPACE | ND_SPACE_FILE_LIST, NC_SPACE | ND_SPACE_FILE_LIST*/); /* TODO probably outliner stuff once UI is defined for this! */
WM_jobs_callbacks(wm_job, asset_updatecheck_startjob, NULL, asset_updatecheck_update, asset_updatecheck_endjob);
/* start the job */
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
static int wm_assets_update_check_exec(bContext *C, wmOperator *UNUSED(op))
{
asset_updatecheck_start(C);
return OPERATOR_FINISHED;
}
void WM_OT_assets_update_check(wmOperatorType *ot)
{
ot->name = "Check Assets Update";
ot->idname = "WM_OT_assets_update_check";
ot->description = "Check/refresh status of assets (in a background job)";
ot->exec = wm_assets_update_check_exec;
}
static int wm_assets_reload_exec(bContext *C, wmOperator *op)
{
/* We need to:
* - get list of all asset IDs to reload (either via given uuids, or their tag), and regroup them by asset engine.
* - tag somehow all their indirect 'dependencies' IDs.
* - call load_pre to get actual filepaths.
* - do reload/relocate and remap as in lib_reload.
* - cleanup indirect dependencies IDs with zero users.
*/
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ListBase engines = {NULL};
/* For now, ignore the uuids list of op. */
asset_update_engines_uuids_fetch(&engines, bmain, NULL, UUID_TAG_ASSET_RELOAD, false);
for (AssetUpdateCheckEngine *auce = engines.first; auce; auce = auce->next) {
FileDirEntryArr *paths = BKE_asset_engine_uuids_load_pre(auce->ae, &auce->uuids);
FileDirEntry *en;
AssetUUID *uuid;
char path[FILE_MAX_LIBEXTRA], libname[FILE_MAX];
char *group, *name;
short flag = 0;
bool do_reload = true;
WMLinkAppendData *lapp_data = wm_link_append_data_new(flag);
lapp_data->root = paths->root;
GHash *libraries = BLI_ghash_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
int lib_idx = 0;
printf("Engine %s (ver. %d) returned root path '%s'\n", auce->ae->type->name, auce->ae->type->version, paths->root);
for (en = paths->entries.first; en; en = en->next) {
printf("\t-> %s\n", en->relpath);
BLI_join_dirfile(path, sizeof(path), paths->root, en->relpath);
if (BLO_library_path_explode(path, libname, &group, &name)) {
BLI_assert(group && name);
if (!BLI_ghash_haskey(libraries, libname)) {
BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx));
lib_idx++;
wm_link_append_data_library_add(lapp_data, libname);
}
}
/* Non-blend paths are only valid in asset engine context (virtual libraries). */
else if (path_to_idcode(path)) {
if (!BLI_ghash_haskey(libraries, "")) {
BLI_ghash_insert(libraries, BLI_strdup(""), SET_INT_IN_POINTER(lib_idx));
lib_idx++;
wm_link_append_data_library_add(lapp_data, "");
}
}
else {
BLI_assert(0);
}
}
for (en = paths->entries.first, uuid = auce->uuids.uuids; en; en = en->next, uuid++) {
int idcode;
const char *libname_def, *name_def;
if (BLO_library_path_explode(path, libname, &group, &name)) {
idcode = BKE_idcode_from_name(group);
libname_def = libname;
name_def = name;
}
else {
idcode = path_to_idcode(path);
libname_def = "";
name_def = path;
}
if (idcode != 0) {
WMLinkAppendDataItem *item;
AssetRef *aref = BKE_libraries_asset_repository_uuid_find(bmain, uuid);
ID *old_id = aref ? ((LinkData *)aref->id_list.first)->data : NULL;
BLI_assert(!old_id || (old_id->uuid && ASSETUUID_COMPARE(old_id->uuid, uuid)));
lib_idx = GET_INT_FROM_POINTER(BLI_ghash_lookup(libraries, libname_def));
BLI_remlink(which_libbase(bmain, GS(old_id->name)), old_id);
item = wm_link_append_data_item_add(lapp_data, name_def, idcode, uuid, old_id);
BLI_BITMAP_ENABLE(item->libraries, lib_idx);
}
}
lib_relocate_do(bmain, scene, NULL, lapp_data, op->reports, auce->ae->type, do_reload);
wm_link_append_data_free(lapp_data);
BLI_ghash_free(libraries, MEM_freeN, NULL);
BKE_filedir_entryarr_clear(paths);
MEM_freeN(paths);
}
/* Cleanup. */
for (AssetUpdateCheckEngine *auce = engines.first; auce; auce = auce->next) {
BKE_asset_engine_free(auce->ae);
MEM_SAFE_FREE(auce->uuids.uuids);
}
BLI_freelistN(&engines);
WM_event_add_notifier(C, NC_WINDOW, NULL);
G.f &= ~G_ASSETS_NEED_RELOAD;
return OPERATOR_FINISHED;
}
void WM_OT_assets_reload(wmOperatorType *ot)
{
PropertyRNA *prop;
ot->name = "Reload Assets";
ot->idname = "WM_OT_assets_reload";
ot->description = "Reload the given assets (either explicitely by their UUIDs, or all curently tagged for reloading)";
// ot->invoke = wm_assets_reload_invoke;
ot->exec = wm_assets_reload_exec;
ot->flag |= OPTYPE_UNDO; /* XXX Do we want to keep this? Is it even working? */
prop = RNA_def_collection_runtime(ot->srna, "uuids", &RNA_AssetUUID, "UUIDs", "UUIDs of assets to reload");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
/** \} */

View File

@@ -40,6 +40,9 @@
#include "MEM_guardedalloc.h"
#include "RNA_define.h"
#include "RNA_types.h"
#include "DNA_genfile.h"
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
@@ -54,6 +57,7 @@
#include "BLO_writefile.h"
#include "BKE_asset_engine.h"
#include "BKE_blender.h"
#include "BKE_blender_undo.h"
#include "BKE_context.h"
@@ -89,8 +93,6 @@
#include "GHOST_Path-api.h"
#include "GHOST_C-api.h"
#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -501,7 +503,9 @@ void WM_exit_ext(bContext *C, const bool do_python)
/* render code might still access databases */
RE_FreeAllRender();
RE_engines_exit();
BKE_asset_engines_exit();
ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */
if (C && wm)

View File

@@ -30,6 +30,8 @@
#include "DNA_space_types.h"
#include "BKE_screen.h"
#include "BLI_rect.h"
#include "BLI_math_base.h"
@@ -60,7 +62,8 @@ void WM_operator_properties_filesel(
if (flag & WM_FILESEL_FILEPATH)
RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path", "Path to file");
if (flag & WM_FILESEL_DIRECTORY)
/* Enforce directory in file cases, needed with asset engines. */
if (flag & (WM_FILESEL_DIRECTORY | WM_FILESEL_FILEPATH | WM_FILESEL_FILENAME | WM_FILESEL_FILES))
RNA_def_string_dir_path(ot->srna, "directory", NULL, FILE_MAX, "Directory", "Directory of the file");
if (flag & WM_FILESEL_FILENAME)
@@ -69,6 +72,23 @@ void WM_operator_properties_filesel(
if (flag & WM_FILESEL_FILES)
RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
if (flag & (WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_FILES)) {
prop = RNA_def_string(ot->srna, "asset_engine", NULL, BKE_ST_MAXNAME, "Asset Engine",
"Identifier of relevant asset engine (if any)");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
if (flag & (WM_FILESEL_FILEPATH | WM_FILESEL_FILENAME)) {
prop = RNA_def_int_vector(ot->srna, "asset_uuid", 4, NULL, INT_MIN, INT_MAX,
"Asset UUID", "Identifier of this item in current asset engine", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_int_vector(ot->srna, "variant_uuid", 4, NULL, INT_MIN, INT_MAX,
"Variant UUID", "Identifier of this item's variant in current asset engine", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_int_vector(ot->srna, "revision_uuid", 4, NULL, INT_MIN, INT_MAX,
"Revision UUID", "Identifier of this item's revision in current asset engine", INT_MIN, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
}
if (action == FILE_SAVE) {
/* note, this is only used to check if we should highlight the filename area red when the
* filepath is an existing file. */

View File

@@ -4124,6 +4124,8 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_quit_blender);
WM_operatortype_append(WM_OT_open_mainfile);
WM_operatortype_append(WM_OT_revert_mainfile);
WM_operatortype_append(WM_OT_assets_update_check);
WM_operatortype_append(WM_OT_assets_reload);
WM_operatortype_append(WM_OT_link);
WM_operatortype_append(WM_OT_append);
WM_operatortype_append(WM_OT_lib_relocate);

View File

@@ -62,5 +62,8 @@ void WM_OT_append(struct wmOperatorType *ot);
void WM_OT_lib_relocate(struct wmOperatorType *ot);
void WM_OT_lib_reload(struct wmOperatorType *ot);
void WM_OT_assets_update_check(struct wmOperatorType *ot);
void WM_OT_assets_reload(struct wmOperatorType *ot);
#endif /* __WM_FILES_H__ */

View File

@@ -43,6 +43,7 @@
struct ARegion;
struct ARegionType;
struct AssetEngine;
struct BMEditMesh;
struct Base;
struct BoundBox;
@@ -379,6 +380,8 @@ void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct
void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) RET_NONE
void ED_render_engine_changed(struct Main *bmain) RET_NONE
struct AssetEngine *ED_filelist_assetengine_get(struct SpaceFile *sfile) RET_NULL
void ED_file_read_bookmarks(void) RET_NONE
void ED_file_change_dir(struct bContext *C) RET_NONE
void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain) RET_NONE
@@ -621,6 +624,9 @@ void uiTemplateNodeSocket(struct uiLayout *layout, struct bContext *C, float *co
void uiTemplatePalette(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, int color) RET_NONE
void uiTemplateImageStereo3d(struct uiLayout *layout, struct PointerRNA *stereo3d_format_ptr) RET_NONE
/* rna asset */
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr) RET_NONE
/* rna render */
struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname) RET_NULL
struct RenderResult *RE_AcquireResultRead(struct Render *re) RET_NULL

View File

@@ -50,8 +50,11 @@
#include "BLI_callbacks.h"
#include "BLI_string.h"
#include "RNA_define.h"
/* mostly init functions */
#include "BKE_appdir.h"
#include "BKE_asset_engine.h"
#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -75,8 +78,6 @@
#include "WM_api.h"
#include "RNA_define.h"
#ifdef WITH_FREESTYLE
# include "FRS_freestyle.h"
#endif
@@ -403,6 +404,7 @@ int main(
psys_init_rng();
/* end second init */
BKE_asset_engines_init();
#if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
G.background = true; /* python module mode ALWAYS runs in background mode (for now) */