Importing big modules

Hi, I need to use pygame in my bge script to catch midi input. The problem is that it is a very big module, so importing it every half second isn’t good because the importing takes half a second itself.

So is there a way to import all the stuff i need and create the static data i will need troughout the whole BGE session at its start?

Someone more familiar with the Blender API and how scripts work can correct me… BUT:

In general, Python will only import a module once. It checks the module dictionary (sys.modules) to see all of the imported modules. If a module is already imported, it won’t import it again, it’ll just use the old reference.

If you’re only using a part of Pygame, you can always do something like


from Pygame import mixer

To only import the mixer module.

Source: http://effbot.org/zone/import-confusion.htm

-Sam

use:

from Pygame import *

Then when you call something like:

mixer.function()

It’ll import mixer (because you’re importing only used modules)

This is my understanding as well.

by chance, have you info about the controller script module option ?

Should be the same… it’s a general Python thing, not specific to Blender.

-Sam

it should be but it appears it’s not, else I won’t ask… :wink:

I’d also need to create a static variable, which must never get deleted or changed trough the whole BGE session, and I need to create it once and at start. Is there a way not to overwrite it on every cycle?

You can use python module. The global part (not within the methods) will run just once.

e.g.


print "init"

def x():
    print "x"

ok so i should create a new module and import it? and then the code inside it will all be executed once?

you could simply use an object property no ?
it will work fine for strings, int, boolean, float… even objects.

you call it in your scripts with something like :


sc     = g.getCurrentScene()
config = sc.objects['OBconfig'] # an object where the main vars are stored as properties
myvar=config['var']

you can also use the gamelogic module to store a dictionnary :
http://www.tutorialsforblender3d.com/GameModule/GameLogicModule_20.html

so vars can be retrieved from any script present in your game.

personnaly I do this (perhaps not academic but well…)


# init
import GameLogic as g
g.gamevars={} # gamevars is a name I chose, not an existing func or class.
g.gamevars['playerobject']     = own
g.gamevars['playermode']       = own['mode']
g.gamevars['playerpos']        = player.worldPosition

# retrieve it (another script)
import GameLogic as g
playerpos = g.gamevars['playerpos']
...

it can be risky if you use an existing function name or class :slight_smile:
you can use another module or loaded script to store it I suppose.

litlleneo, you should use GameLogic.GlobalDict for that. It’s a dictionary object specifically for the purpose of being persistent and global inside the GE, and you know it only contains what you put in it. It even has automated save / load functions, and works between scenes.

Also, for the set once variable problem, IIRC you can connect your python block to an always in pulse mode - then it’ll only run once ever.

@TerabyteST,

yes.

Try this example moduleExample.blend (136 KB). Press p to start with A and B you trigger Object A and ObjectB to calle the method x(). Watch the console. You will see the global part is called once even when the module is called by multiple objects. It will run with the first controller calling a method from that module.

I hope it helps

                      I'd also need to create a static variable, which must never get deleted or changed trough the whole BGE session

One way to create a static (persistent) variable and get around the fact that Python doesn’t support globals is as follows:

create static variable called ‘midi_channel’ in GameLogic module

GameLogic.midi_channel = 1

I don’t know why, or how this works, but it does. Any data stored in your variable persists for the duration of the run-time program and it is visible to all scripts.

Regards,

Journeyman.