Tkinter Text and Itemconfigure Memory Leak - python-2.7

Background:
A few months ago, I posted here asking about a memory leak occurring in my Tkinter canvas class. The primary cause of this was an accidental loop over several key bindings, and the removal of these bindings largely alleviated my problem. However, there remained a small memory leak, but I disregarded it as negligible enough to ignore. At this point (after a couple more months of work), the previously small leak has grown to be potentially damaging -- after an hour of continuous use my program can now fill 800mb+ of system memory, which is a serious concern as without the leak, the program should only require ~60mb.
The Issue:
After some testing, I have narrowed the origin down to two causes:
1. Tkinter itemconfigure function
2. Tkinter text objects
The code snippet below recreates the issue on my machine.
from Tkinter import *
stop=0
class Interface:
def Initialise(self,master):
global x
self.master=master
x=50
width,height=master.winfo_screenwidth(),master.winfo_screenheight()
self.c=Canvas(self.master, width=width, height=height, bg='white',scrollregion=(-1500,-1500,10000,10000))
self.c.pack(side=LEFT,expand=True,fill=BOTH)
self.Regenerate()
self.master.bind("<a>", self.auto)
def Regenerate(self):
self.G=UI_Canvas()
self.G.Visualise(self.c,x)
def auto(self, event):
global stop
stop+=1
self.master.after(5, self.auto_rotate)
def auto_rotate(self):
global x
if stop % 2 == 1:
x+=0.1
self.Regenerate()
self.c.after(5, self.auto_rotate)
class UI_Canvas:
def Visualise(self, canvas,x):
self.canvas=canvas
self.canvas.delete('Network')
data=[((x,400,0),1),((x,450,0),2),((x+50,450,0),3),((x+50,400,0),4)]
for (x,y,z), j in data:
self.canvas.create_oval(x-5, y-5, x+5, y+5, fill='gray15', tags=(j,("Node %.5s" % j),'Network'))
#self.canvas.create_text(x-10,y, text=(j), fill='black', font=('Helvetica',12), tags=(j, ("Node %.5s" % j), 'Network'))
root=Tk()
UI=Interface()
UI.Initialise(root)
root.mainloop()
By commenting out all text and itemconfigure objects, the leak disappears and the program runs at a constant memory usage (as required). Specifically, commenting out all text objects (leaving no objects to be configured), removes the leak, and it therefore seems to me that the repeated refresh of text on-screen is causing the leak. Other canvas objects (lines, ovals and polygons) that I use do not cause this issue.
Attempted Solutions
Other memory leak problems posted here seem to revolve around having updates within loops, but I have not relied on this method, and instead delete then re-create objects inside a loop. As previously mentioned, this method works fine with shapes, but apparently not with text. I have moved the text object code into my 'master' canvas class (thereby no longer being directly in a refresh loop), and instead attempted to configure it from the loop, but the issue persists.
Question
The information contained in these text objects is very important to easily using my program, and resolving this issue is essential. My questions are: what is causing this issue? And are there any possible solutions?
Thank you in advance for any assistance!

Related

Loading Box2D b2World from .Dump() file

I am trying to save and load the state of b2World in order to resume a simulation at a later time, but with the states of the Collision Manager, etc being exactly maintained. What is the best way to do this (without getting into library internals, and having to use boost serialize while monitoring public/private members of every class)? Is there a way to repurpose the log file from b2World.dump function to construct the object again?
I think parsing Dump as-is is a dead end.
First, the output of Dump seems to be executable C++ code:
b2ChainShape chainShape;
b2Vec2 vertices[] = {b2Vec2(-5,0), b2Vec2(5,0), b2Vec2(5,5), b2Vec2(4,1), b2Vec2(-4,1), b2Vec2(-5,5)};
chainShape.CreateLoop(vertices, 6);
b2FixtureDef groundFixtureDef;
groundFixtureDef.density = 0;
groundFixtureDef.shape = &chainShape;
Secondly, there is the problem of dumping floating point values with enough precision to recreate the original object.
Finally, some objects don't seem to support Dumping at all.
Some alternatives:
Hack box2d and add your own state-preserving dumping mechanism
Keep all box2d objects in a specific memory area and use memory snapshotting and/or checkpointing techniques to restore that memory again on load. One such library I know of is Ken, but I'm sure there are other implementations.

How do you control a player character in Bullet Physics?

I am not sure how you are supposed to control a player character in Bullet. The methods that I read were to use the provided btKinematicCharacterController. I also saw methods that use btDynamicCharacterController from the demos. However, in the manual it is stated that kinematic controller has several outstanding issues. Is this still the preferred path? If so, are there any tutorials or documentations for this? All I found are snippets of code from the demo, and the usage of controllers with Ogre, which I do not use.
If this is not the path that should be tread, then someone point me to the correct solution. I am new to bullet and would like a straightforward, easy solution. What I currently have is hacked together bits of a btKinematicCharacterController.
This is the code I used to set up the controller:
playerShape = new btCapsuleShape(0.25, 1);
ghostObject= new btPairCachingGhostObject();
ghostObject->setWorldTransform(btTransform(btQuaternion(0,0,0,1),btVector3(0,20,0)));
physics.getWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
ghostObject->setCollisionShape(playerShape);
ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
controller = new btKinematicCharacterController(ghostObject,playerShape,0.5);
physics.getWorld()->addCollisionObject(ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
physics.getWorld()->addAction(controller);
This is the code I use to access the controller's position:
trans = controller->getGhostObject()->getWorldTransform();
camPosition.z = trans.getOrigin().z();
camPosition.y = trans.getOrigin().y()+0.5;
camPosition.x = trans.getOrigin().x();
The way I control it is through setWalkDirection() and jump() (if canJump() is true).
The issue right now is that the character spazzes out a little, then drops through the static floor. Clearly this is not intended. Is this due to the lack of a rigid body? How does one integrate that?
Actually, now it just falls as it should, but then slowly sinks through the floor.
I have moved this line to be right after the dynamic world is created
physics.getWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
It is now this:
broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
I am also using a .bullet file imported from blender, if that is relevant.
The issue was with the bullet file, which has since been fixed(the collision boxes weren't working). However, I still experience jitteryness, unable to step up occasionally, instant step down from to high a height, and other issues.
My answer to this question here tells you what worked well for me and apparently also for the person who asked.
Avoid ground collision with Bullet
The character controller implementations in bullet are very "basic" unfortunately.
To get good character controller, you'll need to invest this much.

How to sort with beginMoveRows without persistent index corruption / duplication?

I'm trying to use beginMoveRows / endMoveRows to make persistent indexes stick, but sometimes expanded state flags / persistent indexes are duplicated, where they should not be.
There is quite a lot of code, so I'll go through what I think I have told the machine to do:
There is a method, sortChildrenOf(item) which does all the magic.
Find children from item and call sortChildrenOf with each child as a
parameter
save old order
quickSort children
find differences in old order and the new
for each difference:
beingMoveRows
apply change
endMoveRows
Everything works perfectly when there are 2 levels, but when I input a "long" tree of data, persistent indexes get corrupted.
The data in the tree is updated from network, but the actual update is done in the gui thread.
Is there some precise order I should do stuff in? Might I have forgotten to inherit some method that causes this?
I'v got these methods implemented:
- data
- flags
- getItem
- index
- parent
- setData
Edit:
forgot to mention, i got emit layoutAboutToBeChanged and emit layoutChanged before and after the main sortChildrenOf call.
I got it to work, but not with beginMoveRows and endMoveRows. I used the old system of emitting layoutAboutToChange getting the list of persistent indexes manipulating that and setting it back with changePersistentIndexList and finally emitting layout changed.
Since this was the fix, I'm lead to believe that there is some bug withtin beginMoveRows, endMoveRows and persistent indexes with tree type data.
Ask if you need a better example of the code.

Retain cycle with CCAction and CCCallFunc/CCCallBlock

I'm in the final stages of releasing my first game, and after running Instruments:Leaks & Allocations, I see that I have a leak in my code caused by a retain cycle. I am using Cocos2d 2.0, and compiling my app with ARC, and I should mention that I started the project pre-ARC, and used the Xcode refactoring tool to convert it. My game has several animated objects per screen, each of which has a small number (1-7) of animated "variants" of that object (i.e. the barn opens to show a horse once and a zebra another time). I have a class that represents each animation, and another class for each variant. The variant creates a CCAnimation from a sequence of frames, and then creates an action which will be run whenever a touch event is received in the correct region. This action is what is causing my retain cycle. My declaration for the action ivar looks like this:
#interface AnimationVariant : NSObject
{
#private
CCAction* _action;
...
}
#property (readonly, nonatomic) CCAction* action;
...
-(void) setupActionWithMask:(int)mask
cycles:(int)cycles
hasScale:(bool)hasScale
scale:(float)scale
masterScale:(float)master_scale
animationFrames:(NSArray*) frames
duration:(float)duration
andBlock:(VoidBlock)block;
#end
In the implementation of the setupActionWithMask method, I build up an NSMutableArray of CCActions, actionList. The sequence of CCActions varies depending on args, but usually it looks something like this:
[actionList addObject:[CCScaleTo actionWithDuration:0.0f scale:scale]];
[actionList addObject: [CCAnimate actionWithAnimation:animation] ];
[actionList addObject:[CCScaleTo actionWithDuration:0.0f scale:master_scale]];
[actionList addObject: [CCCallBlock actionWithBlock:block]];
And I create the action like this:
_action = [CCSequence actionMutableArray:actionList];
The consuming class creates an AnimationVariant instance, sets its properties, calls setupActionWithMask, and passes in a block it wants executed when the action completes. When the consuming class wants to play the animation variant, it does so like this:
[self runAction: variant.action];
I tried declaring _action as:
CCAction* __unsafe_unretained _action;
which of course broke the retain cycle, but the action is destroyed, and is no longer around when it's needed (which is what you would expect, since __unsafe_unretained does not retain). I know __weak is the recommended solution, but as I am targeting iOS 4 and up, I don't think it's available to me.
I had another retain cycle in my code, exactly like this one, also caused by retaining (automatically with ARC of course) a CCSequence containing a CCCallFunc/CCCallBlock. I solved that one by just re-creating it whenever I needed it, which I could also do in this case, but these animations are triggered maybe a couple hundred times in the whole game, so I was hoping to follow the recommended Cocos2d Best Practices and retain the actions.
Thanks!
Retaining actions is not best practice. It's not even good practice. Though it comes heavily recommended by many, quite unfortunately.
Retaining actions works in many cases, but fails in others causing objects to leak. I'm guessing your case may be one of those.
Since you're targeting iOS 4 you can't use weak references. But you should probably reconsider unless you have to target the remaining few 1st and 2nd generation devices. Otherwise, google for iOS 5 adoption rate. The handful of devices that haven't been updated yet are well below a reasonable threshold, in particular if you consider that those users probably don't buy (many) apps (anymore) anyway.
Since you meantioned CCCallFunc, make sure you don't use them and replace with CCCallBlock. CCCallFunc are not safe to use with ARC, in particular whenever you have to __bridge_transfer cast a data object to void* (also bad practice).
There's always the chance that the necessary bridge cast back to the original object never occurs, and then ARC doesn't get the chance to clean up that object. With CCCallFunc this can happen when you run a call func action but the action is stopped before the callback selector is called, for example by changing scenes or stopping the action/sequence.
Cocos2D is also prone to retain cycles if you don't follow this rule:
any node should only retain another node that is one of its children or grandchildren
In all other cases (ie node retains (grand)parent or sibling node) you must make sure to nil those references in the -(void) cleanup method. Doing so in -(void) dealloc is too late because the object will never get to dealloc when there's a retain cycle.

Using Lua to define NPC behaviour in a C++ game engine

I'm working on a game engine in C++ using Lua for NPC behaviour. I ran into some problems during the design.
For everything that needs more than one frame for execution I wanted to use a linked list of processes (which are C++ classes). So this:
goto(point_a)
say("Oh dear, this lawn looks really scruffy!")
mowLawn()
would create a GotoProcess object, which would have a pointer to a SayProcess object, which would have a pointer to a MowLawnProcess object. These objects would be created instantly when the NPC is spawned, no further scripting needed.
The first of these objects will be updated each frame. When it's finished, it will be deleted and the next one will be used for updating.
I extended this model by a ParallelProcess which would contain multiple processes that are updated simultaneously.
I found some serious problems. Look at this example: I want a character to walk to point_a and then go berserk and just attack anybody who comes near. The script would look like that:
goto(point_a)
while true do
character = getNearestCharacterId()
attack(character)
end
That wouldn't work at all with my design. First of all, the character variable would be set at the beginning, when the character hasn't even started walking to point_a. Then, then script would continue adding AttackProcesses forever due to the while loop.
I could implement a WhileProcess for the loop and evaluate the script line by line. I doubt this would increase readability of the code though.
Is there another common approach I didn't think of to tackle this problem?
I think the approach you give loses a lot of the advantages of using a scripting language. It will break with conditionals as well as loops.
With coroutines all you really need to do is:
npc_behaviour = coroutine.create(
function()
goto(point_a)
coroutine.yield()
say("Oh dear, this lawn looks really scruffy!")
coroutine.yield()
mowLawn()
coroutine.yield()
end
)
goto, say and mowLawn return immediately but initiate the action in C++. Once C++ completes those actions it calls coroutine.resume(npc_behaviour)
To avoid all the yields you can hide them inside the goto etc. functions, or do what I do which is have a waitFor function like:
function waitFor(id)
while activeEvents[id] ~= nil do
coroutine.yield()
end
end
activeEvents is just a Lua table which keeps track of all the things which are currently in progress - so a goto will add an ID to the table when it starts, and remove it when it finishes, and then every time an action finishes, all coroutines are activated to check if the action they're waiting for is finished.
Have you looked at Finite State Machines ? If I were you I wouldn't use a linked list but a stack. I think the end result is the same.
stack:push(action:new(goto, character, point_a))
stack:push(action:new(say, character, "Oh dear, this lawn was stomped by a mammoth!"))
stack:push(action:new(mowLawn, character))
Executing the actions sequentially would give something like :
while stack.count > 0 do -- do all actions in the stack
action = stack:peek() -- gets the action on top of the stack
while action.over ~= true do -- continue action until it is done
action:execute() -- execute is what the action actually does
end
stack:pop() -- action over, remove it and proceed to next one
end
The goto and other functions would look like this :
function goto(action, character, point)
-- INSTANT MOVE YEAH
character.x = point.x
character.y = point.y
action.over = true -- set the overlying action to be over
end
function attack(action, character, target)
-- INSTANT DEATH WOOHOO
target.hp = 0
action.over = true -- attack is a punctual action
end
function berserk(action, character)
attack(action, character, getNearestCharacterId()) -- Call the underlying attack
action.over = false -- but don't set action as done !
end
So whenever you stack:push(action:new(berserk, character)) it will loop on attacking a different target every time.
I also made you a stack and action implementation in object lua here. Haven't tried it. May be bugged like hell. Good luck with your game !
I don't know the reasons behind you design, and there might be simpler / more idiomatic ways to it.
However, would writing a custom "loop" process that would somehow take a function as it's argument do the trick ?
goto(point_a)
your_loop(function ()
character = getNearestCharacterId()
attack(character)
end)
Since Lua has closures (see here in the manual), the function could be attached to your 'LoopProcess', and you call this same function at each frame. You would probably have to implement your LoopProcess so that that it's never removed from the process list ...
If you want your loop to be able to stop, it's a bit more complicated ; you would have to pass another function containing the test logic (and again, you LoopProcess would have to call this every frame, or something).
Hoping I understood your problem ...