Re: camera in CroquetEvent?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: camera in CroquetEvent?

Andreas.Raab
Hi Howard -

Sorry for not getting back earlier but something struck me about your
message as being really, really wrong and I finally realized what my
problem with it is:

Howard Stearns wrote:
> Andreas, you're right about the TFarRef happening outside a future
> message. It happens in:
>
> TChattyAvatarReplica>>prointerLeave: evt
>     super pointerLeave: evt.
>     self root signal: #hideID with: evt with: nickname.

No, this can't be it. If, at this point, the event contains a TFarRef
for the camera we're already hosed and need to look at where that
reference came from. The reason being that pointerLeave: should have
been invoked as a future message, and future messages *never* create
FarRefs for their arguments (all arguments in future messages are copied
verbatim). So if there's a FarRef in the event at that point things
already went wrong. I strongly suspect that the problem is happening
elsewhere.

> Or we can change it to pass a copy of the event, as is done by:
>
> TAvatarUserMenu>>doBlueButtonUp: event
>     | eventCopy |
>     eventCopy := event copy.
>     eventCopy selection: event selection copy.
>     eventCopy selection target future signal: #blueButtonUp with:
> eventCopy.

Huh? This works? How very strange. You're not changing the camera in the
above so the copy should refer to the camera just like the old event and
should cause precisely the same problems.

> But I'm not clear on the philosophy by which to decide what the right
> path is. (I guess it would be up to Tony.)  Naively, it seems weird to
> have events be #passByClone:, only to have to have to make copies
> whenever we want to actually pass one.

Yeah, that's certainly not the right way to deal with it. Well, first
let's try to nail the issue with the camera in the event - if there's
really a FarRef in there then something is really, really wrong and we
need to find out where that reference is coming from. If there isn't a
FarRef in there it's back to square one, e.g., find the sync message
that causes the camera to be "injected" into the replicated space by way
of some far ref.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: camera in CroquetEvent?

Howard Stearns

On Aug 11, 2006, at 6:00 PM, Andreas Raab wrote:

> Hi Howard -
>
> Sorry for not getting back earlier but something struck me about  
> your message as being really, really wrong and I finally realized  
> what my problem with it is:
>
> Howard Stearns wrote:
>> Andreas, you're right about the TFarRef happening outside a future  
>> message. It happens in:
>> TChattyAvatarReplica>>prointerLeave: evt
>>     super pointerLeave: evt.
>>     self root signal: #hideID with: evt with: nickname.
>
> No, this can't be it. If, at this point, the event contains a  
> TFarRef for the camera we're already hosed and need to look at  
> where that reference came from. The reason being that pointerLeave:  
> should have been invoked as a future message, and future messages  
> *never* create FarRefs for their arguments (all arguments in future  
> messages are copied verbatim). So if there's a FarRef in the event  
> at that point things already went wrong. I strongly suspect that  
> the problem is happening elsewhere.

Could it be a script in myEventMap that is a FarRef but shouldn't be?  
Otherwise I'm without a clue.

When I wave the mouse around over portals, before attempting to  
supply a snapshot, I see this:

TIsland>>execute: aTMessage (for #doPointerLeave:)
=> TFrame>>doPointerLeave:
   => TChattyAvatarReplica>>pointerLeave:
           ....
          Transcript show: '', evt, ' ',  evt camera; cr.
               "This prints: a CroquetEvent a TCamera (not a TFarRef  
in sight)
                Is that because these are on-island copies which are  
(correctly) made in a proper future message?
               Otherwise, I would be confused because this code should (I  
think) be executed on the island,
                and so evt and it's camera would be TFarRefs from in  
here."
           self root signal: #hideID with: evt with: nickname
             => ...TSpace(Object)>>signalEvent:
               => TSpace(Object)>>privateSignalEvent: anEvent
                    | map list msg |
                        map := self myEventMap ifNil:[^self].
                        list := map at: anEvent selector ifAbsent:[^self].
                        1 to: list size do:[:i|
                           (msg := list at: i) ifNotNil:[msg valueWithEvent:  
anEvent clone]].  "we're at #valueWithEvent: at this point"
                 =>passByCopy: aScriptEvent
                          => passByClone: aCroquetEvent
                             => pass: aCamera  <- This defaults to  
passByProxy:, which creates the TFarRef for the camera.

It seems that the msg local variable in #privateSignalEvent: is a  
FarRef (not a TFarRef) to a ScriptMessageSend on the Squeak Island,  
and thus it tries to pass anEvent clone using the island copier.  Is  
that where things are getting goofy?


>
>> Or we can change it to pass a copy of the event, as is done by:
>> TAvatarUserMenu>>doBlueButtonUp: event
>>     | eventCopy |
>>     eventCopy := event copy.
>>     eventCopy selection: event selection copy.
>>     eventCopy selection target future signal: #blueButtonUp with:  
>> eventCopy.
>
> Huh? This works? How very strange. You're not changing the camera  
> in the above so the copy should refer to the camera just like the  
> old event and should cause precisely the same problems.

It may do. Not my code, so I don't know whether the event copy is  
intended to avoid this sort of problem being discussed or something  
else, or whether it succeeds in doing so.

There are also a bunch of TAvatarUserVehicle methods that do evt  
camera: nil, which could conceivably be another attempt at this issue.

Tony?

>
>> But I'm not clear on the philosophy by which to decide what the  
>> right path is. (I guess it would be up to Tony.)  Naively, it  
>> seems weird to have events be #passByClone:, only to have to have  
>> to make copies whenever we want to actually pass one.
>
> Yeah, that's certainly not the right way to deal with it. Well,  
> first let's try to nail the issue with the camera in the event - if  
> there's really a FarRef in there then something is really, really  
> wrong and we need to find out where that reference is coming from.  
> If there isn't a FarRef in there it's back to square one, e.g.,  
> find the sync message that causes the camera to be "injected" into  
> the replicated space by way of some far ref.
>
> Cheers,
>   - Andreas
>


Reply | Threaded
Open this post in threaded view
|

Re: camera in CroquetEvent?

Howard Stearns
In reply to this post by Andreas.Raab
OK, I think I've got it!

The problem is that CroquetParticipant>>drawOn: is happening on-
island in my app:
1. There's a TranscriptStream>>show: in  
TLoad3DSMax>>initializeMumble. (Reasonable.)
2. The TLoad3DSMax is happening on-island. (My particular island  
builds some meshes. Reasonable.)
3. The Transcript stuff does a PluggableTextMorph(Morph)
 >>refreshWorld, which allows the CroquetParticipant>>drawOn:.  
(Reasonable, by itself.)
4. But CroquetParticipant>>drawOn: will sometimes (e.g., initially)  
send CroquetHarness>>bounds:, which creates a new TCamera.
5. TCamera is a TFrame, and therefore its #initialize always  
registers a TFarRef object for it in the island of the current  
process. (Not used in this case, but OK in general.)

Thus the Harness makes an on-island camera that gets stored in the  
ocean (e.g., in pointer, ogl, event, etc.).
When we try to sync, the same identical camera is pointed to from the  
ocean and by the island's far ref map.

So the problem, I think, is that harness rendering should never  
happen on island. Maybe the fix is to have  
CroquetParticipant>>drawOn: bail out if
self island ~= Island default?

(Man, this was a bitch to find!)
(Tony, I never did find out what the camera: nil, and event copy  
stuff was for, but if it was only to avoid this, then I think they  
should be pulled.)

A log is attached which shows:
TCamera>>initialize
TCamera class(TFrame class)>>new
WisconsinHarness(CroquetHarness)>>bounds:
WisconsinParticipant(CroquetParticipant)>>drawOn:
...
PluggableTextMorph(Morph)>>refreshWorld
...
TranscriptStream>>show:
TLoad3DSMax>>initializeWithFileName:scale:shadeAngle:textureMode:


On Aug 11, 2006, at 9:52 PM, Howard Stearns wrote:

>
> On Aug 11, 2006, at 6:00 PM, Andreas Raab wrote:
>
>> Hi Howard -
>>
>> Sorry for not getting back earlier but something struck me about  
>> your message as being really, really wrong and I finally realized  
>> what my problem with it is:
>>
>> Howard Stearns wrote:
>>> Andreas, you're right about the TFarRef happening outside a  
>>> future message. It happens in:
>>> TChattyAvatarReplica>>prointerLeave: evt
>>>     super pointerLeave: evt.
>>>     self root signal: #hideID with: evt with: nickname.
>>
>> No, this can't be it. If, at this point, the event contains a  
>> TFarRef for the camera we're already hosed and need to look at  
>> where that reference came from. The reason being that  
>> pointerLeave: should have been invoked as a future message, and  
>> future messages *never* create FarRefs for their arguments (all  
>> arguments in future messages are copied verbatim). So if there's a  
>> FarRef in the event at that point things already went wrong. I  
>> strongly suspect that the problem is happening elsewhere.
>
> Could it be a script in myEventMap that is a FarRef but shouldn't  
> be? Otherwise I'm without a clue.
>
> When I wave the mouse around over portals, before attempting to  
> supply a snapshot, I see this:
>
> TIsland>>execute: aTMessage (for #doPointerLeave:)
> => TFrame>>doPointerLeave:
>   => TChattyAvatarReplica>>pointerLeave:
>           ....
>  Transcript show: '', evt, ' ',  evt camera; cr.
>               "This prints: a CroquetEvent a TCamera (not a TFarRef  
> in sight)
>                Is that because these are on-island copies which are  
> (correctly) made in a proper future message?
>       Otherwise, I would be confused because this code should (I  
> think) be executed on the island,
>                and so evt and it's camera would be TFarRefs from in  
> here."
>           self root signal: #hideID with: evt with: nickname
>             => ...TSpace(Object)>>signalEvent:
>               => TSpace(Object)>>privateSignalEvent: anEvent
>                     | map list msg |
>                map := self myEventMap ifNil:[^self].
>                list := map at: anEvent selector ifAbsent:[^self].
>                1 to: list size do:[:i|
>           (msg := list at: i) ifNotNil:[msg valueWithEvent:  
> anEvent clone]].  "we're at #valueWithEvent: at this point"
>                 =>passByCopy: aScriptEvent
>                          => passByClone: aCroquetEvent
>                             => pass: aCamera  <- This defaults to  
> passByProxy:, which creates the TFarRef for the camera.
>
> It seems that the msg local variable in #privateSignalEvent: is a  
> FarRef (not a TFarRef) to a ScriptMessageSend on the Squeak Island,  
> and thus it tries to pass anEvent clone using the island copier.  
> Is that where things are getting goofy?
>
>
>>
>>> Or we can change it to pass a copy of the event, as is done by:
>>> TAvatarUserMenu>>doBlueButtonUp: event
>>>     | eventCopy |
>>>     eventCopy := event copy.
>>>     eventCopy selection: event selection copy.
>>>     eventCopy selection target future signal: #blueButtonUp with:  
>>> eventCopy.
>>
>> Huh? This works? How very strange. You're not changing the camera  
>> in the above so the copy should refer to the camera just like the  
>> old event and should cause precisely the same problems.
>
> It may do. Not my code, so I don't know whether the event copy is  
> intended to avoid this sort of problem being discussed or something  
> else, or whether it succeeds in doing so.
>
> There are also a bunch of TAvatarUserVehicle methods that do evt  
> camera: nil, which could conceivably be another attempt at this issue.
>
> Tony?
>
>>
>>> But I'm not clear on the philosophy by which to decide what the  
>>> right path is. (I guess it would be up to Tony.)  Naively, it  
>>> seems weird to have events be #passByClone:, only to have to have  
>>> to make copies whenever we want to actually pass one.
>>
>> Yeah, that's certainly not the right way to deal with it. Well,  
>> first let's try to nail the issue with the camera in the event -  
>> if there's really a FarRef in there then something is really,  
>> really wrong and we need to find out where that reference is  
>> coming from. If there isn't a FarRef in there it's back to square  
>> one, e.g., find the sync message that causes the camera to be  
>> "injected" into the replicated space by way of some far ref.
>>
>> Cheers,
>>   - Andreas
>>
>


SqueakDebug.save (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: camera in CroquetEvent?

Andreas.Raab
In reply to this post by Andreas.Raab
Howard Stearns wrote:
> Thus the Harness makes an on-island camera that gets stored in the ocean
> (e.g., in pointer, ogl, event, etc.).
> When we try to sync, the same identical camera is pointed to from the
> ocean and by the island's far ref map.

Sounds logical.

> So the problem, I think, is that harness rendering should never happen
> on island. Maybe the fix is to have CroquetParticipant>>drawOn: bail out if
> self island ~= Island default?

I think there are two problems (at least). Like you say, rendering
on-island is completely evil, and I think we should raise an error (not
just suppress it).

This leaves us to deal with Transcript and we got two options here:
a) Make Transcript a FarRef and allow only future messages to it. This
would have the advantage that it's clearly The Right Thing To Do but it
will break a lot of other code.

b) Ensure that Transcript is only flushed from Island>>default, e.g.,
something like
TranscriptStream>>endEntry
     Processor activeIsland == Island default
         ifFalse:[^Island default future flushTranscript].
     "regular flushing goes here"
The advantage of which is that it will likely work okay in the current
situation at the cost of some uglyness that will come back to haunt us ;-)

In the current situation I'd prefer the latter.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: camera in CroquetEvent?

Howard Stearns
In reply to this post by Andreas.Raab
I think it is quite valuable for Croquet to be able to leverage all the
great stuff that has been built for Squeak. (Or at least, as much as
possible.) The fantasy is that WITHIN an island, one should be able to
use any fun thing like Sophie or Seaside or Plopp, or whatever --
without rewriting it's internals. Maybe it's not practical for it to be
that easy, but I'd like to keep that as a goal. Or to be able to tell
people that with an almost straight face.

So I'm nervous about both (a) and (b), below.  As you note, (a) says
that other code that uses Transcript would have to be rewritten.[There's
another problem, embedded below.]  (b) says that other code that is
brought in may have to have some of its more system-like internals
changed, even if the interface to them remains the same.

Now, we already sort of have a simple case of requiring change: the
underscore for assignment issue. And I'm ok with that.

But I really want to resist making a full break with existing stuff.  I
don't know what the right answer is. I'm just expressing...
uncomfortableness.

Andreas Raab wrote:

> Howard Stearns wrote:
>> Thus the Harness makes an on-island camera that gets stored in the
>> ocean (e.g., in pointer, ogl, event, etc.).
>> When we try to sync, the same identical camera is pointed to from the
>> ocean and by the island's far ref map.
>
> Sounds logical.
>
>> So the problem, I think, is that harness rendering should never
>> happen on island. Maybe the fix is to have
>> CroquetParticipant>>drawOn: bail out if
>> self island ~= Island default?
>
> I think there are two problems (at least). Like you say, rendering
> on-island is completely evil, and I think we should raise an error
> (not just suppress it).
>
> This leaves us to deal with Transcript and we got two options here:
> a) Make Transcript a FarRef and allow only future messages to it. This
> would have the advantage that it's clearly The Right Thing To Do but
> it will break a lot of other code.
I'm not clear on how this would work. Would Transcript be a FarRef proxy
to a Transcript object on the Island default?  I thought we were not
supposed to use future to send messages from a replicated island to
Island default? I thought instead we were supposed to use #signal:. (I'm
thinking of the discussion we had about chat, "how we did peer-to-peer
chat with tweak" 3/15/06)

>
> b) Ensure that Transcript is only flushed from Island>>default, e.g.,
> something like
> TranscriptStream>>endEntry
>     Processor activeIsland == Island default
>         ifFalse:[^Island default future flushTranscript].
>     "regular flushing goes here"
> The advantage of which is that it will likely work okay in the current
> situation at the cost of some uglyness that will come back to haunt us
> ;-)
>
> In the current situation I'd prefer the latter.
>
> Cheers,
>   - Andreas

--
Howard Stearns
University of Wisconsin - Madison
Division of Information Technology
mailto:[hidden email]
jabber:[hidden email]
voice:+1-608-262-3724