
Originally Posted by
gtannus
I want a function that tries for 1 minute to get a valid GPS data and than stop GPS. But this has to run in a thread (application might not stop for 1 minute). It seems that gps callback and thread do not work well together. Any ideas?
The general structure of a PyS60 program seems to be:
1. Set everything up
2. Wait on an e32.Ao_lock()
3. Process events from other active objects, until you want to quit
4. Signal the lock, and exit
Point is that most of the time, you're at step 3, so as long as none of your event handlers block the main thread, you can do virtually everything in a single thread.
According to the docs, if you use a callback, positioning.position() won't block the thread, so why d'ya need another thread?
I can't test this, cos I'm too lazy to resign PythonScriptShell with permission to use positioning, but...
Code:
import e32, positioning
lock = e32.Ao_lock()
data = None
timer = e32.Ao_timer()
def stopApp():
lock.signal()
def startSearch():
positioning.position(<insert other params here>, callback=searchCallback)
timer.after(60, stopSearch)
def stopSearch():
positioning.stop_position()
def searchCallback(d):
if dataIsValid(d):
timer.cancel()
global data
data = d
stopSearch()
# Do other stuff here
def dataIsValid(d):
# I guess it's up to you to decide when you have enough info
if <insert condition here>:
return True
else:
return False
# Setup app here
lock.wait()
As a general rule, most IO functions have a non-blocking option. The only time you really need another thread is when you're CPU-bound (e.g. doing some serious number-crunching) for longer than you're prepared to let the UI be unresponsive for (maybe 100ms or so).
Now, having said all that, if point #1 in the following is true, which I can't confirm...

Originally Posted by
miohtama
stop_position() must be called in the main thread and not in 1) callback 2) any other thread.
...then you'll have to do something more complicated, like either wrapping the start/stop positioning method in an e32.ao_callgate(), or if that doesn't work, you'll have to replace the Ao_lock() with something like...
Code:
import e32, positioning
running = True
data = None
timer = e32.Ao_timer()
callQueue = []
def stopApp():
global running
running = False
def callInMainAo(func, args = (), kwargs = {}):
callQueue.append((func, args, kwargs))
def startSearch():
callInMainAo(positioning.position, (<insert other params here>), {'callback': searchCallback})
timer.after(60, stopSearch)
def stopSearch():
callInMainAo(positioning.stop_position)
def searchCallback(d):
if dataIsValid(d):
timer.cancel()
global data
data = d
stopSearch()
# Do other stuff here
def dataIsValid(d):
# I guess it's up to you to decide when you have enough info
if <insert condition here>:
return True
else:
return False
# Setup app here
while running:
if not callQueue:
e32.ao_sleep(0.1)
continue
while callQueue:
func, args, kwargs = calls.pop(0)
apply(func, args, kwargs)
Just make sure you don't push a blocking call onto the call queue.