This vector implementation does is optimized for the case of having only a small number of elements, which are stored directly on the vector object rather than being allocated from the heap. If the capacity exceeds this small number, then a heap allocation is done.
This should improve performance in a couple of cases where vectors typically store 1 element and rarely more than that.
The order of arguments is now the same as in Python (with the callable first), sort and priority arguments have been added, and new tasks can be added directly to a chain
init_memory_hook() is no longer required, eliminating static initialization order issues
This required moving the DeletedBufferChain map elsewhere, which now also has a const-initialized array for relatively small allocations.
Also, deletedChain.T has been renamed to deletedChain.I
Fixes#539
std::function has unnecessary overhead, better to just create an AsyncTask subclass in-place storing the closure
This obsoletes FunctionAsyncTask, it will be removed in a future commit
This typedefs to std::atomic<> when building with true threading, and uses a dummy implementation without.
This lets us use the full range of atomic operations offered by C++11, including explicit specification of memory fences. Using barriers lets the compiler generate more optimal code since currently we are using the quite strict sequential-consistent memory ordering for all operations. ReferenceCount has been changed to use the correct barriers (I hope). This may especially make a difference on weak ordering systems such as ARM.
Over time we should gradually replace the use of AtomicAdjust with the new patomic file.
It's unfortunate that we now have three maps on EventHandler for three different types of functions. I'd love to unify them all under std::function, but the fact that it doesn't support comparison means the behavior would be different.
Perhaps in the future we can create a new interface or deprecate the existing behaviors and unify everything under std::function.
* Passing a Python subclass of a C++ class now works, the extra Python stuff isn't just discarded
* EventParameter objects are no longer automagically unwrapped - there's no more reason to pass an EventParameter to this method anyway, and it might be unexpected if it is treated specially.
This matches the behaviour of asyncio. It schedules with the current task's manager and chain. If no current manager is found, it prints a warning. (The user can just add the coroutine to a task manager themselves and pass the resulting task into gather() if needed.)
See discussion here:
https://discourse.panda3d.org/t/task-gather-does-not-seem-to-work/27313
This is more useful and consistent; you can after all just use "return" to end the task, whereas you can now just use "yield" to continue the next frame rather than "yield Task.cont".
This is a follow-up to f6b39345f7, which already enabled this behavior when an __await__ (that is awaited from a task) yielded None.
This matches the behavior of asyncio's Task implementation, where this is the equivalent of `yield Task.cont`.
I've kept regular generator tasks unaffected for now, since this might break existing usage.