Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Packaging" class member functions as closures

46 views
Skip to first unread message

bitrex

unread,
Sep 4, 2017, 2:46:20 PM9/4/17
to
It was suggested to me that my OpenGL "game engine" could be improved by
having the thread with the OpenGL context execute "scripts" that are
passed to it from game objects in another thread via a locking queue.
This makes sense since OpenGL isn't intrinsically multithreaded, and
simply trying to make OpenGL calls (e.g. the GPU shader pipeline
specifically) across threads via say a vector of weak pointers held by
the thread with the active context has caused me grief.

Using lambdas/closures was suggested as a way to accomplish this by
putting say a member "render" function, object, and arguments into a
package that could be passed over through the queue. I'm not
super-familiar with lambdas and the stuff that's now possible with
std::function post C+11, wondering if anyone could give a reference or
example as to how something like this would be done?

Chris M. Thomasson

unread,
Sep 4, 2017, 2:59:45 PM9/4/17
to

bitrex

unread,
Sep 4, 2017, 10:36:47 PM9/4/17
to
Hey cool!

bitrex

unread,
Sep 4, 2017, 10:48:43 PM9/4/17
to
On 09/04/2017 02:59 PM, Chris M. Thomasson wrote:
But while it is cool, it's very abstract and seems more or less a
guideline as to how to re-implement a framework like Unity. Which
unfortunately I don't really have time to do. :-(

Chris Vine

unread,
Sep 5, 2017, 7:53:51 AM9/5/17
to
"Closures" in the abstract sense are just functions which have
previously declared variables accessible to them lexically which are
not passed to the functions as arguments. These so-called "free"
variables are said to be closed over by the function.

Unlike some languages, C++ does not have closures built in, and they
have to be synthesized. They are synthesized as objects with a
operator() method (function objects) which keep the "closed over"
variables as data members. You have probably written hundreds of them
without labelling them as closures in your mind - they are pretty
basic. Most function objects of class type are closures.

As suggested, because such "closures" (ie function objects) comprise a
"package" containing the data members plus a function to operate on
them, they can be useful for passing to other functions for those other
functions to do something with them: you could think of such function
objects as self-contained callbacks. This can be done opaquely,
because any function object can be stored polymorphically in a
std::function object. They are also commonly passed statically as
types of a template function - this occurs throughout the standard
library.

C++11 lambdas are just a syntactic convenience to construct anonymous
function objects "on the fly". The closed-over free variables to be
incorporated in the function object are specified in the lambda's
capture list. std::bind also constructs anonymous function objects.

So far as reading is concerned, although VS orientated this is quite a
good introduction:
https://docs.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp

Chris




bitrex

unread,
Sep 8, 2017, 9:00:24 PM9/8/17
to
Thanks for laying out the executive summary. I've experimented a bit
with using closures for render instruction passing in my engine this
week and I think I've got the hang of it, but the experimenting has also
made it apparent that without rewriting some of the engine applying them
properly won't make much of a difference (I really need to separate out
the code that manages the 'scene objects' from the code that renders
those objects, the render code should really just return fully rendered
frames and nothing else, One Responsibility and all that) so that's good
to know too. ;-)

0 new messages