How to subclass Clock in Pyglet?
Question: I want to subclass Clock class of pyglet.clock module, but I have some
troubles when I use schedule_interval:

The following code doesn't print anything and the object c looks like if not
ticked at all:

    
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import pyglet
    
    class Clock(pyglet.clock.Clock):
        def __init__(self):
            super(Clock, self).__init__()
    
    class Test(object):
        def update(self, dt):
            print dt
    
    w = pyglet.window.Window()
    @w.event
    def on_draw():
        w.clear()
    
    t = Test()
    
    c = pyglet.clock.Clock()
    c.schedule_interval(t.update, 1/60.0)
    
    pyglet.app.run()
    

But the next works fine.

    
    
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import pyglet
    
    class Clock(pyglet.clock.Clock):
        def __init__(self):
            super(Clock, self).__init__()
    
            pyglet.clock.set_default(self)
    
    class Test(object):
        def update(self, dt):
            print dt
    
    w = pyglet.window.Window()
    @w.event
    def on_draw():
        w.clear()
    
    t = Test()
    
    c = Clock()
    c.schedule_interval(t.update, 1/60.0)
    
    pyglet.app.run()
    

The only difference is the pyglet.clock.set_default(self) sentence in the
constructor method of Clock.

I think this is not clear or, at least, is not the best way of subclassing
pyglet.clock.Clock to have your own derived Clock class.

**The questions:**

There is some way to set the default clock automatically with Pyglet?

There is a solution more elegant or pythonic?

Is possible do this without the pyglet.clock.set_default(self) line?


Answer: I haven't used pyglet, but here's my guess:

You're almost there. The reason your first implementation probably didn't work
is because of these lines:

    
    
    c = pyglet.clock.Clock()
    c.schedule_interval(t.update, 1/60.0)
    

Here, you are creating a new Clock instance and are scheduling a callback on
it. However, at no point are you actually associating that instance of a clock
with pyglet. So, when you run...

    
    
    pyglet.app.run()
    

...you never actually told pyglet about the new clock instance `c`. Instead,
pyglet will use an instance that it made itself. Check out this [source code
for pyglet from the clock
module](https://code.google.com/p/pyglet/source/browse/pyglet/clock.py)...:

    
    
    # Default clock.
    _default = Clock()
    
    def set_default(default):
        '''Set the default clock to use for all module-level functions.
    
        By default an instance of `Clock` is used.
    
        :Parameters:
            `default` : `Clock`
                The default clock to use.
        '''
        global _default
        _default = default
    
    def get_default():
        '''Return the `Clock` instance that is used by all module-level
        clock functions.
    
        :rtype: `Clock`
        :return: The default clock.
    

When pyglet starts up, it creates its own instance of the clock (called
`_default`). If you want to use your own, you need to use `set_default()` to
replace it. Therefore, to fix your first piece of code, you probably would
need to do one of the following:

    
    
    c = pyglet.clock.get_default()
    c.schedule_interval(t.update, 1/60.0)
    

...or...

    
    
    c = pyglet.clock.Clock()
    pyglet.clock.set_default(c)
    c.schedule_interval(t.update, 1/60.0)
    

The second example above is pointless: pyglet already gives you an instance of
Clock, so you'd really just duplicating something that pyglet has already done
for you. Either way though, you end up scheduling the callback on the clock
**that pyglet is using**.

So, it should now make sense that, yes, you do need to call `set_default()`.
This is how you tell pyglet to use your object rather than the one it makes by
default. Now, you **could** conceivably put this `set_default()` call where
you currently have it (in the constructor). However, it probably makes more
sense to do this...

    
    
    class Clock(pyglet.clock.Clock):
        def __init__(self):
            super(Clock, self).__init__()
    
    ...
    
    c = Clock()
    pyglet.clock.set_default(c)
    

**Edit** :

In response to the question of why you would do this outside the constructor:

First, as a general rule of thumb, a constructor should only be used to
construct the object. By adding set_default, you are not only constructing the
object, you are also changing the state of some other entity (the pyglet.clock
module). This can cause confusion, as I will show below. Assume I wrote code
that looked like this...

    
    
    c = MyClock()
    c2 = UnpausedClock()
    

In this example, I have previously implemented two different clock types:
`NewClock` and `UnpausedClock`. `UnpausedClock` will only consider time to be
passing when the game is unpaused. If I put `set_default()` in the constructor
of these two new classes, then `UnpausedClock` would become the new default
clock (which I don't want). By NOT putting `set_default()` in the constructor,
and instead doing the following:

    
    
    c = MyClock()
    c2 = UnpausedClock()
    pyglet.clock.set_default(c)
    

My code is more explicit, and less confusing.

Of course, the code will work either way, but I feel that having the
set_default OUTSIDE the constructor gives you more flexibility to use the
class as you need to later on.

