Global objects and external libraries??

Here’s the weird problem…

I’m using the following code to get/set a global variable (for a custom game controller):

        if GameLogic.__dict__.has_key('tp_tracker'):
                tp_tracker=GameLogic.tp_tracker
        else:
                print "---------------------- Starting ThinkPad Tracker"
                tp_tracker=ThinkpadTracker()
                scene=GameLogic.getCurrentScene()
                tp_tracker.boundObject=scene.getObjectList()["OBlaptop"]
                GameLogic.tp_tracker=tp_tracker
        tp_tracker.sample()

(This is called by an “Always” logic brick.)

The first time through, it hits the “else” as expected, then successfully executes sample().

Next time, however, it retrieves tp_tracker, doesn’t hit the else code (as expected) and calls sample()… but the code inside sample() fails miserably! It acts like it can’t find any of my imported libraries.

In fact, it gives me an error it can’t even find the global value “False”, which is kinda basic, ya know!

So like, what gives!?? :confused:

Thanks in advance,
-thsm

What specific errors is the console giving you? It might also be helpful to see the code for the sample() function.


if not hasattr(GameLogic, "tp_tracker"):
    print "-------------Starting Thinkpad Tracker"
    GameLogic.tp_tracker = ThinkpadTracker()
    laptop = GameLogic.getCurrentScene().getObjectList()["OBlaptop"]
    GameLogic.tp_tracker.boundObject = laptop

GameLogic.tp_tracker.sample()

There is no reason to reassign things, as you can see. Just use the object you initially created as shown.

Hope this helps.

Thanks for your help.

MagicMan: That’s what is so weird. It can be anything even


        def sample(self):
                return False

Which works the first time, then every time afterwards gives me
NameError: global name ‘False’ is not defined
Is that not weird?

I also tried adding the
GameLogic.tp_tracker.sample()
line and it made no difference.

In fact, just try this. Just set up an “always” block linked to the following code:


class Foo():
        def something(self):
                try:
                        x=False
                        print "smiley, nicey-nice
"
                except:
                        print "what's the deal!??
"
 
if GameLogic.__dict__.has_key('foo') == False:
        print "---------------------- Creating object"
        GameLogic.foo=Foo()
GameLogic.foo.something()

Thansk again!

False is not an across-the-board standard Python global. It works on some systems, but not on others, and I’m not sure why.

Instead of True and False, use 1 and 0. Alternately, you could declare values for True and False at the beginning of your script, then you could be sure that they will work on all systems.

edit: Also, did you try the script that Social posted? It looks like it would work, and it eliminates your need for the true and false checking anyway.

Using 2.45 on both Linux and windows, True and False are defined properly.

Which is weird, because as long as I can remember, these statements only worked on windows. Maybe this is a 2.44 exclusive issue that was resolved in 2.45.

Blendenzo, is your situation still the same with 2.45?

You’re welcome.

I think I’ve got it!

What I think is happening is there is an execution context with all the libraries loaded where I create the object. I save that object away, but once BGE leaves that context, python cleans everything up that it thinks is unused, including the imported libraries.

Then next time the lop comes around, it starts me an all new context, with all the libraries. I get the stored object and all its data is still good BUT… strangley, all the methods on that object still execute IN THE OLD EMPTIED CONTEXT! :eek:

Therefore, nothing can be referenced from any library great or small (even the implied one that contains False).

To get around this problem, perisit only DATA ONLY objects. Ponder the following modification:


class Foo():
        class PersistentCrap():
                something=False
        def __init__(self,pc=None):
                if pc==None:
                        self.pc=self.PersistentCrap()
                else:
                        self.pc=pc
        def something(self):
                try:
                        if self.pc.something == False:
                                print "smiley, "
                                self.pc.something = True
                        else:
                                print "nicey-nice
"
                                self.pc.something = False
                except:
                        print "what's the deal!??
"
 
if GameLogic.__dict__.has_key('foo_pc') == False:
        print "---------------------- Creating object"
        foo=Foo()
else:
        foo=Foo(GameLogic.foo_pc)
foo.something()
GameLogic.foo_pc=foo.pc

In other words, I added all the data I wanted to save inside an inner object. Then I re-create the outer object (that contains all my methods) every time.

You’ll notice in the very last line, ONLY my data elements are stored instance-to-instance.

That all works perfectly fine. To prove it, I even made a little flip/flop logic based on True/False.

Hurray! Stange, obsure, backwards, head-beating-against-the-wall problem solved!

(I hope this info will be helpful to others in the same plight. )

As I said, there is no need to re-create things like this.

Doing “GameLogic.myObject = myClass()” once is enough. That object should be saved in memory, along with all it’s methods and data.

PS: Use “hasattr()” for your initialization. It’s easier to read and type.