Chris
Sorry, but I am going to have to ask for help again. I can now manage the lifetimes in the database and image. Although it took me a while to get the process repeatable and figure out where all the references were. However, it now works and connectors stay connected. Unfortunately now that I am really retrieving from the database a retrieved app does not work. At least none of the UI events work, but then I am using dynamic techniques to hook everything together. I have a taken a simple case which is one composite component with one button on it. The button fires a block which references self in this case. However, self appears to be nil. This is where it fails.
DoIt | t1 t2 t3 t4 t5 | super initialize. t2 := ImageMorph new. t3 := GraphicPath , 'sdr1000.gif'. t2 setNewImageFrom: (Form fromFileNamed: t3). t1 := SDRButton newWithParams: 'Reset' actionSelector: #(#RESETHW ) actionTarget: [:t6 | self buttonAction: t6]. self borderWidth: 2. self borderColor: #complexFramed. self color: Color gray. self addMorph: t2. self addMorph: t1. t4 := t2 extent. t5 := t1 extent. self extent: t4 x + t5 x + 8 @ (t4 y + 8)
MessageNotUnderstood Undefined object buttonAction. This method called DoIt seems to be my Initialize method with the variables replaced with generated names. GraphicPath refers to a pool dictionary which it also can't resolve, don't know if that's relevant.
I have attached the file. The button is set up in the SDR1000Morph Initialize. It is called through the block in the dictionary set up by SDR1000Controller createServerInterfaceMap at #RESETHW.
I know this is a lot to ask. If it's not obvious what I need to do please don't labour over it.
Thanks Bob
*** Confidentiality Notice *** Proprietary/Confidential Information belonging to CGI Group Inc. and its affiliates may be contained in this message. If you are not a recipient indicated or intended in this message (or responsible for delivery of this message to such person), or you think for any reason that this message may have been addressed to you in error, you may not use or copy or deliver this message to anyone else. In such case, you should destroy this message and are asked to notify the sender by reply email.
Magma does support blocks and I just verified the #testBlocks tests three different BlockContexts with various characteristics, one includes a 'self' reference. So on the surface, it seems like it should work.
Having said that, did you happen to ever save a change to that #initialize method in the debugger at some point? MethodContexts on the stack referring to the CompiledMethod being changed may undergo some transformation. An existing instance of that Morph was persisted in the db; for one its MethodContext on the stack at the time is suddenly not pointing to the CompiledMethod installed in the class.
So you could try to resave the #initialize method and re-commit all your SDR1000Morphs to the db. That might get it working, but there is still the main caveat with storing BlockContext and MethodContexts in the database for "long-term behavior" such as this; they become stale as soon as the code changes because they refer to the old CompiledMethod object, not the current one. This could cause some real confusion much later if you have lots of stored instances not behaving as the current method source indicates; they are running the old CompiledMethod which now executes in a DoIt Context I think.
This is such as simple block anyway that you may want to consider using a MessageSend instead. This is a standard object that can be used instead of the Block. Try changing your assignment to resetButton to something like this:
resetButton := (SDRButton newWithParams: 'Reset' actionSelector: #(#RESETHW) actionTarget: (MessageSend receiver: self selector: #buttonAction:).
Now, I see MessageSend answers to #value and #valueWithArguments: but I don't see #value: which may be required. So you may need to add MessageSend>>#value:.
value: anObject ^ self valueWithArguments: { anObject }
This might help solve your problem and you might be happier with a MessageSend in the long run anyway because it will stay "current" with the code.
Good luck, Chris
--- "Cowdery, Bob [UK]" Bob.Cowdery@CGI-Europe.com wrote:
Chris
Sorry, but I am going to have to ask for help again. I can now manage the lifetimes in the database and image. Although it took me a while to get the process repeatable and figure out where all the references were. However, it now works and connectors stay connected. Unfortunately now that I am really retrieving from the database a retrieved app does not work. At least none of the UI events work, but then I am using dynamic techniques to hook everything together. I have a taken a simple case which is one composite component with one button on it. The button fires a block which references self in this case. However, self appears to be nil. This is where it fails.
DoIt | t1 t2 t3 t4 t5 | super initialize. t2 := ImageMorph new. t3 := GraphicPath , 'sdr1000.gif'. t2 setNewImageFrom: (Form fromFileNamed: t3). t1 := SDRButton newWithParams: 'Reset' actionSelector: #(#RESETHW ) actionTarget: [:t6 | self buttonAction: t6]. self borderWidth: 2. self borderColor: #complexFramed. self color: Color gray. self addMorph: t2. self addMorph: t1. t4 := t2 extent. t5 := t1 extent. self extent: t4 x + t5 x + 8 @ (t4 y + 8)
MessageNotUnderstood Undefined object buttonAction. This method called DoIt seems to be my Initialize method with the variables replaced with generated names. GraphicPath refers to a pool dictionary which it also can't resolve, don't know if that's relevant.
I have attached the file. The button is set up in the SDR1000Morph Initialize. It is called through the block in the dictionary set up by SDR1000Controller createServerInterfaceMap at #RESETHW.
I know this is a lot to ask. If it's not obvious what I need to do please don't labour over it.
Thanks Bob
*** Confidentiality Notice *** Proprietary/Confidential Information belonging to CGI Group Inc. and its affiliates may be contained in this message. If you are not a recipient indicated or intended in this message (or responsible for delivery of this message to such person), or you think for any reason that this message may have been addressed to you in error, you may not use or copy or deliver this message to anyone else. In such case, you should destroy this message and are asked to notify the sender by reply email.
squeak-dev@lists.squeakfoundation.org