2

I have recently encountered a scope technique in Cinder -- a graphics library:

{    
    gl::ScopedModelMatrix scpModelMatrix;  
    //.... Anything in this area will be executed in ModelMatrix-mode.
    //      (if applicable)
}
//.... In this area, there is no ModelMatrix-mode effect.

Let's assume that this technique is implemented by:

  • The constructor (at the beginning of the scope);
  • The destructor (at the end of the scope).

(Thank, Klitos Kyriacou!)

Question

  1. What is the name of this technique?
    ... I tried to google it, but found no article mentioning this.

  2. What are the disadvantages of this technique?

I planned to do something like:

{    
    Go* gameObject = sysCreator->createGameObject();
    ScopeMarker scope=sysCreator->markScope(gameObject);
    Graphic_Object* gra = sysGraphic->create( ... );
    Physic_Object* phy = sysPhysic->create( .... );
    // "gra" & "phy" will be considered as owned by "gameObject".
    //  That is : both variables will be deleted automatically ...
    //          ... when "gameObject" is destroyed.
}

In other words, is there anything of which I should be careful specifically?


Edit2: Thank a lot for many useful comments.

As requested, this is how I will implement it. Roughly speaking,

ScopeMarker SysCreator::markScope(GameObject* gameObject){
    sysGraphic->notify( gameObject );
    sysPhysic->notify( gameObject );
    ScopeMarker scope= ScopeMarker(this);
}
int counter=0; // counter for scope constructor (+1), destructor (-1)
// .... other code to manage Constructor / Destructor of ScopeMarker ...

Every time new graphic/physic object created, it will be marked as owned by the game object.

void SysGraphic::notify(GameObject* gameObject){
    this->cacheGO=gameObject;
}
Graphic_Object* SysGraphic::create( some parameter ){
    Graphic_Object* gra = create_( some parameter);
    sysOwnerBinder->markOwner( this->cacheGO, gra ); //another system
}
//Every timestep,
// sysOwnerBinder will check find every "gameObject" that will be deleted.
// It will delete its "gra" & "phy" first.

Note that I don't use any static variables / function.

Reference: https://libcinder.org/docs/structcinder_1_1gl_1_1_scoped_depth_test.html

Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67
  • 1
    Do you mean namespaces? – Lehu Jul 29 '16 at 08:19
  • 2
    @Lehu he's referring to the _local scope_ I believe – Jonathon Ogden Jul 29 '16 at 08:20
  • I don't think it is namespace. IMHO, namespace is a programmer-logical term, but the scope I meant here is more like an execution controller. :) – javaLover Jul 29 '16 at 08:21
  • 1
    Ah! I see it now :) . – Lehu Jul 29 '16 at 08:21
  • 3
    I haven't seen the source code for this implementation, but it seems these scoping classes would work by having constructors and destructors that alter the global environment. Which means that it can affect other threads, even if they're not running in that particular scope. – Klitos Kyriacou Jul 29 '16 at 08:22
  • I agree, Klitos Kyriacou. I also think it is controlled by destructors. (I will edit question now) "affect other threads." nice concern! – javaLover Jul 29 '16 at 08:24
  • 2
    I use this technique all the time, but I don't know whether it has a name. The closest thing I can think of is the ScopeGuard, whose task is a subset of the general technique (namely cleaning up non-RAII resources such as C library handles and applying commit/rollback mechanics). – Quentin Jul 29 '16 at 08:26
  • 2
    See also [`std::lock_guard`](http://en.cppreference.com/w/cpp/thread/lock_guard) for an example of such an object from the standard library. This one is simply described as "RAII-style". – Quentin Jul 29 '16 at 08:30
  • @Quentin Thank a lot, that is very close! Did you face any difficulty about multi-threading (mentioned by Klitos Kyriacou)? If so, how did you solve it? ... and where did you learn about this scope technique from? (book?, web?) – javaLover Jul 29 '16 at 08:37
  • 1
    @javaLover regarding your question about _disadvantages_ of your code, what is it you're trying to do exactly? We'd need context before we can give advice. – Jonathon Ogden Jul 29 '16 at 08:37
  • 1
    Indeed std::lock_guard and gl::ScopedModelMatrix scpModelMatrix are RAII-style. This style is typically good. What I'm referring to in my previous comment is that normally RAII-style scope guards affect an object passed as a parameter to their constructor. Such scope guards are generally well written and well behaved. By contrast, ScopedModelMatrix doesn't take any parameters; so, what exactly does it affect? The global state? – Klitos Kyriacou Jul 29 '16 at 08:38
  • 1
    @javaLover I've used it for automatic binding of OpenGL objects (such as VAOs, programs and the like). I've not dealt with multithreading at all, but that shouldn't be any more difficult -- in fact, you probably can simply embed a `std::lock_guard` into your own object. – Quentin Jul 29 '16 at 08:40
  • 2
    As for the way I came around to this technique, I'm actually not sure... I think it stemmed from the "everything must be RAII" scheme, extended to abstract things like "this object represents the locking of that one". So that would simply be "RAII" by default, but I definitely think it needs ots own name :) – Quentin Jul 29 '16 at 08:41
  • 1
    @KlitosKyriacou I'd guess that it wraps a pair of [`glMatrixMode`](https://www.opengl.org/sdk/docs/man2/xhtml/glMatrixMode.xml) calls. These change the global OpenGL state, namely which matrix is being modified by subsequent `gl*Matrix` calls. – Quentin Jul 29 '16 at 08:44

0 Answers0