Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sat Jun 21, 2008 2:16 pm   

[2.28] COM breaks when done from a module
 
This makes absolutely no sense, but appears to be a scoping issue.

Procedure
1. Launch CMud
2. Close Sessions Window (ESC)
3. Open Package Editor (CTRL-G)
4. Paste (CTRL-V)
Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<module name="a" copy="yes">
  <uid>{35859475-1056-4461-BF8B-B70059967FAA}</uid>
  <var name="WidgetsComTemp" type="COM" usedef="true" copy="yes">
    <notes>Locked with SECTION WidgetsCom, this temp variable is used for various COM functions.</notes>
  </var>
  <func name="GetDirectionSettings" type="Integer" copy="yes">
    <value>$Index=%session.NumDirs
#IF ($Index=0) {#RETURN 0}
DirectionSettings=""
#WHILE ($Index) {
 #ADD $Index -1
 #SECTION WidgetsCom {
  WidgetsComTemp=%session.DirNum($Index)
  #ADDKEY DirectionSettings {@WidgetsComTemp.Name} {%concat(@WidgetsComTemp.ReverseChar,"-",@WidgetsComTemp.MapDir,"-",%replace(@WidgetsComTemp.Value,"|","-"))}
  #ADDKEY DirectionSettings {@WidgetsComTemp.MapDir} {%concat(@WidgetsComTemp.Name,"-",@WidgetsComTemp.ReverseChar,"-",%replace(@WidgetsComTemp.Value,"|","-"))}
  #SHOW DirectionSettings @WidgetsComTemp.Name {%concat(@WidgetsComTemp.ReverseChar,"-",@WidgetsComTemp.MapDir,"-",%replace(@WidgetsComTemp.Value,"|","-"))}
  #SHOW DirectionSettings {@WidgetsComTemp.MapDir} {%concat(@WidgetsComTemp.Name,"-",@WidgetsComTemp.ReverseChar,"-",%replace(@WidgetsComTemp.Value,"|","-"))}
  WidgetsComTemp=""
 }
}
#RESULT 1</value>
    <notes>Builds the DirectionSettings variable, done as part of the initial load.  You would only need to call this if you create or remove directions.</notes>
  </func>
</module>
</cmud>

5. Select from PE menu File|Open, open the EnglishDirections.pkg
6. Enter at the command line
Code:
#CALL @GetDirectionSettings()

You will see it displays a bunch of nulls for all the COM data
7. Bring the PE to the front (CTRL-G)
8. Jump through extra hoops to get the untitlted package back to being displayed, it is a seperate bug that I can't be bothered to write up
9. Drag the GetDirectionSettings function from the 'a' module into the 'untitled' window
10. Enter at the command line
Code:
#CALL @GetDirectionSettings()

Now you will see all the COM references expand properly.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Anaristos
Sorcerer


Joined: 17 Jul 2007
Posts: 821
Location: California

PostPosted: Sat Jun 21, 2008 7:30 pm   
 
This is confirmed.
Actually, I noticed this behavior in 2.18 and just assumed that COM objects had to be located in the session window class, which is where I keep them.
_________________
Sic itur ad astra.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sun Jun 22, 2008 3:46 pm   
 
Hrm, I never noticed this problem with 2.18. I wasn't really actively testing with 2.20 through 2.27, so I have no idea when this bug was intorduced.

What I find most interesting about this bug, is that the line "$Index=%session.NumDirs" puts the correct value into Index. This means the bug stems from using a subsequently created COM object. If I had to guess when this bug was introduced I would say it was when the fix was made so that closing a window didn't destroy all COM objects.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Anaristos
Sorcerer


Joined: 17 Jul 2007
Posts: 821
Location: California

PostPosted: Sun Jun 22, 2008 8:03 pm   
 
By habit I try to put all elements pertaining to a routine in the same class. With this in mind, I created a class to contain COM objects and their associated scripts (open, check, repair, etc). The scripts addressing the objects didn't work until I moved them (the objects) to the session window class. I discovered this in the version in which you introduced the SQLite interface. Perhaps that version wasn't 2.18.
_________________
Sic itur ad astra.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Jun 23, 2008 5:03 pm   
 
Does it only happen with %session? Can you try creating a "normal" COM variable via %comcreate for some other Windows object and try that?

The problem is that %session just points to a predefined COM interface for the current "window" object in CMUD. When you do this within a module, there isn't any "window" object to attach to this variable. So it would be undefined.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Mon Jun 23, 2008 8:11 pm   
 
I had to move both of these function into my main window to do any of the scripting work I was aimed at. These both belong in my global Toolbox package, and the variables MapCon and WidgetsComTemp that they use are still in my Toolbox.
Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <func name="SpecialMapQuery" type="Literal" copy="yes">
    <value>#DELITEM SpecialMapQueryValidation {%threadid()}
#IF (@OpenMapDatabaseForQuery()) {
 #SECTION WidgetsCom {
  WidgetsComTemp=@MapCon.Execute($SQLString)
  #IF (@WidgetsComTemp) {
   #IF (@WidgetsComTemp.BOF) {
    // #SHOW {Query $SQLString produced no results}
    #CALL @WidgetsComTemp.Close
    WidgetsComTemp=""
    #ADDITEM SpecialMapQueryValidation {%threadid()}
    #RETURN ""
   } {
    #IF (@WidgetsComTemp.State=0) {
     // Some error caused the query to fail, release the record set
     WidgetsComTemp=""
     #RETURN ""
    } {
     #VAR $Res {@WidgetsComTemp.GetString(2,-1,$ColumnSeperator,$RowSeperator,"")}
     $Res=%leftback($Res,%len($RowSeperator))
     #CALL @WidgetsComTemp.Close
     WidgetsComTemp=""
     #ADDITEM SpecialMapQueryValidation {%threadid()}
     #RESULT $Res
    }
   }
  }
 }
}</value>
    <arglist>$SQLString,$ColumnSeperator,$RowSeperator</arglist>
    <notes>See also the ValidateSpecialQuery function
The full SQL string is required.  You can use UPDATE, but I would suggest reading the full ADO documentation as I have not tested it with that.</notes>
  </func>
  <func name="OpenMapDatabaseForQuery" type="Integer" copy="yes">
    <value>#IF (%pref(MapFile)="") {#RETURN 0}
#IF (@MapCon) {
 #IF (@MapCon.State=0) {
  #CALL @MapCon.Open(%concat("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=",%pref(MapFile)))
  #IF (@MapCon.State=0) {
   MapCon=""
   #RETURN 0
  }
 } {
  #RETURN 1
 }
} {
 MapCon=%comcreate("ADODB.Connection")
 #CALL @MapCon.Open(%concat("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=",%pref(MapFile)))
 #IF (@MapCon.State=0) {
  MapCon=""
  #RETURN 0
 }
}
#RESULT 1</value>
    <notes>Opens the map file for queries with the SpecialMapQuery function.  This is done as part of the onLoad.</notes>
  </func>
</cmud>
Testing of some of the queries I was working on was what led me to find this, after tweaking some things because the #VAR syntax no longer works with COM objects, I determined that all COM usage was broken when the script was not directly within the window from which the calls are preformed.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Jun 23, 2008 9:19 pm   
 
Quote:
because the #VAR syntax no longer works with COM objects

Huh? That's a new one too. The a=b syntax actually calls the same internal routine as the #VAR command, so I'm not sure how they would be different, but I'll look into that. Do you have any idea what version might have broken this?
Reply with quote
Anaristos
Sorcerer


Joined: 17 Jul 2007
Posts: 821
Location: California

PostPosted: Mon Jun 23, 2008 10:51 pm   
 
I pointed out before that COM objects don't work unless placed in the window session class. I don't work with just one object, currently I have 7 objects that are operational and they all have to reside at the root. Perhaps this has nothing to do with the problem.

EDIT: However, in test operations where I use more than one package, I have no problem using the objects across packages (as long as the package containing the objects has them at the root).
_________________
Sic itur ad astra.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Mon Jun 23, 2008 11:08 pm   
 
You need to be very careful when you talk about things being in the root. Nothing except modules and windows should ever be in the root of a package - if that's really what you mean, something's gone wrong (as well as going right). If that's not what you meant, what did you?
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Anaristos
Sorcerer


Joined: 17 Jul 2007
Posts: 821
Location: California

PostPosted: Tue Jun 24, 2008 12:57 am   
 
We've gone through this before. You don't seem to understand what the root is. The root is the window session, from it all other classes stem. That is why I call it the root. 'Session window' is too long a name for me to use each time I want to refer to it. If it has another name, let me know. But when I look at the compiled script, if it is in what I call the root, it will say <class packagename>. Anywhere else in the world I would be understood when I speak of the root class, I don't see what the problem is here. Another way to look at it is the class where a setting will default to, if no default is specified. If you have an empty package and you create a setting, that setting will go to the root. I hope this explains what I mean by "root". If it has a technical name, please inform me. Anyone who has ever worked with trees should have no problem understanding what I mean.
_________________
Sic itur ad astra.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Jun 24, 2008 1:22 am   
 
I guess I will have to dig through my archives for all the details on which version this first occured in.

The short version of the #VAR syntax not working is that #VAR name {COM type thing} seems to actually put "<COM Object>" into the variable instead of whatever low level reference it used to. It wasn't that much of a bother to change it to name=COM type thing since I was only changing a few functions that were responsible for the low level references.

I really wasn't concerned that much since #VAR was setting the type for the variable to String(expanded), and it was logical to other such uses of the same syntax. I personally would like it better, especially when I have already set the variable type; but it is a minor compatibility item. The specific procedure to demonstrate it is:
1. Launch CMud
2. Close Sessions Window (ESC)
3. Enter at the command line
Code:
#SHOW Hello;#VAR a {%session};#SHOW @a.NumVars;#SHOW Goodbye
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Dumas
Enchanter


Joined: 11 Feb 2003
Posts: 511
Location: USA

PostPosted: Tue Jun 24, 2008 12:57 pm   
 
Anaristos wrote:
We've gone through this before. You don't seem to understand what the root is. The root is the window session, from it all other classes stem. That is why I call it the root. 'Session window' is too long a name for me to use each time I want to refer to it. If it has another name, let me know. But when I look at the compiled script, if it is in what I call the root, it will say <class packagename>. Anywhere else in the world I would be understood when I speak of the root class, I don't see what the problem is here. Another way to look at it is the class where a setting will default to, if no default is specified. If you have an empty package and you create a setting, that setting will go to the root. I hope this explains what I mean by "root". If it has a technical name, please inform me. Anyone who has ever worked with trees should have no problem understanding what I mean.


There is technically an ultimate level called 'root', which is why Fang brought this up. Your window session is based in this, and only windows and modules should be the first tier down. In other words, Fang is making sure that your objects aren't at the same level as windows and modules, but are inside them.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Tue Jun 24, 2008 2:04 pm   
 
Yes, my point's simply that the real root (meaning "having nothing as its parent") is only for modules and windows. If you start calling two things the root - the real root of the package and the session window - then it can get confusing. I was only asking because I didn't know if you meant the real root or something else.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Jun 24, 2008 7:08 pm   
 
Take a look at the Terminology section of the help file. In our official terms, "root" is the same as the "top level" of the settings. The "root" is the top of the package and it contains only windows and modules. By default, CMUD creates the first module/window in a package with the same name as the package file itself, which I know might be confusing.

Your window is *not* the root. The reason your terminology can be confusing to advanced users is that a single package can contain multiple windows and modules. The "root" is the top level of the tree that contains these windows and modules. The actual "node" for the root of the tree is not displayed in the settings editor, so that might also be confusing. The root node is always expanded to show the windows/modules within it.

So, if you mean the top-level of your session window, then you should say that. Don't confuse it with the "root" of the package itself. If you ever see a setting such as a class folder, alias, trigger, etc at the same level in the tree as a window/module, then your package is corrupted.

Anyway, back to the problem from the original post....

I will look into the #VAR problem. When you store a COM object in a variable, the #VAR command will display the contents as <COM Object>, but it shouldn't be using this "string" as the actual value of the variable. But I was able to reproduce the bug with the example that you gave, so it's definitely something I'll try to fix.

The problem with %session stems from how it worked in zMUD where each session only had a single primary window and child windows were treated specially. In CMUD, each window has it's own %session object, and some functions (like SendStr) use this to determine which window to send text to. However, when accessing the Aliases, Variables, etc you are actually accessing the *global* list of all settings for all windows/modules. So, for example, NumVars will display the total number of variables, not just the variables stored within the specific window.

CMUD really needs a new COM API to handle multiple windows/modules properly and to properly handle the new scoping rules. I can certainly see many cases where the COM API won't exactly match how scoping is handled in the rest of CMUD. Also, using %session within a module (which doesn't have any window associated with it) is undefined.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Jun 24, 2008 9:58 pm   
 
Yep, the problem was the {} around %session. That was converting %session into an expanded string, and CMUD wasn't checking first to see if this was a variant value.

So

#VAR a %session

was working, but

#VAR a {%session}

was not. I thought about what you said about the parser consistency, but decided that CMUD should really never convert a COM value into the "" string at any time, so I went ahead and changed it.
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: Thu Jul 03, 2008 3:59 pm   
 
The secondary bug listed here, (#VAR a {%session} ) is fixed.
_________________
Asati di tempari!
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Thu Jul 03, 2008 8:00 pm   
 
I also checked the primary bug and it seems to be completely fixed. I know the version history only listed the secondary bug. Now I can return to script writing. Twisted Evil
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net