View Single Post
Posts: 631 | Thanked: 837 times | Joined on May 2007 @ Milton, Ontario, Canada
#104
Originally Posted by daperl View Post
Syncing in user space should be simple. The following psuedo code would cost very little and makes the reasonable assumption that sleeping will take no less than 60 seconds and no more than a 120 seconds.

Code:
def clock_update():
  while not_done:
    now = get_system_time_in_seconds()
    update_clock (now)
    sleep_time = 60 - now MOD 60
    sleep_for_seconds (sleep_time)

clock_update_thread = threading.Thread (target=clock_update)
clock_update_thread.start()
Interesting, see I started picking at the code yesterday with the aim of helping out by getting the whole "don't do anything while the tablet is inactive" thing sorted out. I'm not a big python person (in fact some parts of it drive me crazy compared to other languages, but that's just me!), but I'm really interested in this project so I wanted to try and help. See I just took Ciro's updated code and adapted the logic so that it makes sense... If you look at his last post he started with:

Code:
ctime = 
time.ctime()
pygame.time.set_timer(DRAW_CLOCK_EVENT,(60-int(str(ctime[17])+str(ctime[18])))*1000)
Which is brilliant, causes the event to fire at exactly the correct time; the only thing I found odd was that he then went on to fire the event every 60 seconds after that, instead of using the same calculation to fire it at exactly the right time. So he suggested:
Code:
 if timesixty == False:
      pygame.time.set_timer(DRAW_CLOCK_EVENT, 60000)
      timesixty = True
But really that doesn't make sense... why not just do the proper time adjusted calculation each time the clock updates? That way it's always accurate... and it's one call to the ctime() method, so not exactly CPU intensive or anything. So my version ended up with the if statement looking like this:
Code:
 elif event.type == DRAW_CLOCK_EVENT:
    #Clear the current timer
    pygame.time.set_timer(DRAW_CLOCK_EVENT, 0)
    
    if ci.fcmode==0:                      #Redraw the clock only
      ci_gfx.drawclock()                  #  when is visible
    else:
      ci_gfx.drawalarm()                # no need to redrawm, anyway in not cheap
	
	#recalculate time until next second and reset delay as required
    ctime = time.ctime()
    pygame.time.set_timer(DRAW_CLOCK_EVENT, (60-int(str(ctime[17])+str(ctime[18])))*1000)
Everytime the update runs it clears the old timer value (just incase soemthing odd happens during the update? I'm not 100% sure about the functionality of the set_timer method as I'm thinking along the lines of JavaScript's setInterval), then once the update has completed the timer is recalculated (that way the wait is accurately calculated again AFTER all potentially time-consuming code has been run).

Basically the same sort of solution, just a different way of going about it. Second point though... I tried implementing the power notification stuff using the osso module, but seem to have run into the same problems as others found when developing maemoClock, etc: set it all up just before the while True loop like this:
Code:
def state_cb(shutdown, save_unsaved_data, memory_low, system_inactivity, 
    message, loop):

    print "System Inactivity: ", system_inactivity
    if system_inactivity:
        #Clear the current timer
        pygame.time.set_timer(DRAW_CLOCK_EVENT, 0)
    else:
        #make the update and stuff happen now
        pygame.time.set_timer(DRAW_CLOCK_EVENT, 10)

    return False


osso_c = osso.Context("flip_clock", "0.7", False)
device = osso.DeviceState(osso_c)
device.set_device_state_callback(state_cb, system_inactivity=True, user_data=None)
Which in theory should work... when system is inactive it causes the event looper to abort, preventing any kind of screen refresh/update; and when it becomes active again the screen refresh/update is restarted almost immediately. However the callback never gets executed. A lot of googling later has indicated that there's something more to the problem here... I think it's something to do with the pygame.event.wait() call, but I tried swapping that out for just some sleep and pygame.event.get() setups and it still never actually gets called. Perhaps some kind of thread or something is needed?

Great app though, awesome work to everyone involved!

Thanks,
-Rob
 

The Following User Says Thank You to jolouis For This Useful Post: