Author Topic: Multiple COD file architecture, included functions work but variables are messy.  (Read 976 times)

0 Members and 1 Guest are viewing this topic.

Offline cyanTopic starter

  • Premier Member
  • *****
  • Posts: 644
  • Country: us
  • Gender: Male
While I do the slow and iterative process of gutting COD script infrastructure by way of C# or just making the software do it "out of the box", I am also trying to apply some new concepts to a giant mass of these scripts so that I can make them less redundant.

One of the things I've been building out is a useful "common" set of functions that get re-used throughout all scripts.

Just as an example:

Code: [Select]
rem Gets the connector that contains the connector name
rem provided.
rem returns the connector with that type, or null if
rem none were found.
function firstConnectorOfType(item, connectorName)
    dim result
    dim i
    for i=1 to item.connectors
        if contains(item.connector[i].value, connectorName) then
            result = item.connector[i]
        end if
    next
    return result
end function

rem Unlocks the connector, sets it, then locks the connector again.
function changeConnector(connector, connectorName)
    connector.locked = false
    connector.value = connectorName
    connector.locked = true
end function


I realize that I'm using camel casing in what is a derivative of VB Script. Don't @ me.

This is actually working great and it's helping me to reduce a massive amount of clutter. But the odd thing is that if I define a common variable that I want to use, like this:

Code: [Select]
dim width = "Width"

I can include this and use it within the context that I included it. This is cool because I eliminate "magic strings" with very little overhead.

Here's the problem, if the functions that I define are trying to use it, they can't. Not unless I include the file with that variable within the function. You can't even include the file above the function definition. Functions seem to dispose of any and all information outside of their own scope and vanilla scripting definitions. And one other thing. They are able to reference other previously imported functions. Variables? Nope. Functions? Yep.

So, I do have the option of doing something like
Code: [Select]
function width()
    return "Width"
end function

And now I can reuse it wherever. But it feels a bit weird to write

Code: [Select]
if item.dim[width()].numvalue > 24 then
rem whatever

Anyway, I'm curious if anyone doing some more advanced architecting of a script infrastructure have thoughts on this kind of thing. The reason I would want to do something like this is maybe I consider a specification name or service name as a global default. I would like to define it once in some spot and then always reference it from the same source. Know what I mean?

Offline DotNet

  • .
  • Senior Member
  • ****
  • Posts: 347
  • Country: us
  • Gender: Male
    • MICLOGIC
If you’re proficient with C#, I’d do it all in C# and never look back. That said…

Code: [Select]
function changeConnector(connector, connectorName)
    connector.locked = false
    connector.value = connectorName
    connector.locked = true
end function

This is fantastic. Make a function for anything like this. Insulation, Seams, Specs, everything. Perhaps call Item.Update().

Code: [Select]
function width()
    return "Width"
end function
Quote
And now I can reuse it wherever. But it feels a bit weird to write.

That’s because it is. Don’t do that. Think deeply about anything you are refactoring. Is this useful? Will this save significant time? Am I making things more complicated than they need to be? Don’t do anything unless you have a good reason to do it. Perhaps "GetWidthDimension()" would be a more useful function. It all depends on the above three questions.

I am a huge fan of writing functions that work with any CID, but they must be well thought out. Check out this thread:
https://www.xtracad.com/forum/index.php/topic,16667.msg109756.html#msg109756


Offline DotNet

  • .
  • Senior Member
  • ****
  • Posts: 347
  • Country: us
  • Gender: Male
    • MICLOGIC
Ryan, I've read a few of your posts. Forgive me, I did not know that you were a Jedi, and I see your Schwarts is as big as mine! My comments are for all readers, not necessarily the OP. This is true for all of my posts.

Offline cyanTopic starter

  • Premier Member
  • *****
  • Posts: 644
  • Country: us
  • Gender: Male
As I read your response, my first thought was "This is good information for everyone here". I can't say it bothered me at all even before your follow up. No apology necessary.

My example for essentially declaring a constant was pretty bad. I admit. width() is not great. The constant I'm really trying to establish is default string values that can be pretty large. The example was just for easy comprehension. Really, it would be larger strings that you might ship around the library, like file system reference points or something, for example.

Eventually, everything but skin seams will be in C# from what I can tell. But believe me, this script library is immense. So being the process that it is, refactoring of repetitive scripts is good because it also helps to shape the logic to be more like what it will be when the C# effort arrives.

And for the linked subject, yes. In C#, I always turn on the the nullable flag in the project and Rider keeps me very honest with them. I use them a lot. I actually had a function similar to what you wrote there, although I still had a situation once where I still had a failure purely by trying to index the dim by name.

Code: [Select]
Dim LengthDim = Item.Dim["Length"]
This was failing before I even did anything with it. I was perplexed. If I ever see it again, I'll show you.

This seems to be getting around it. If I'm in a context where I'm not certain that the item will have the dimension, I use it. But otherwise, I just do the item.dim["foo"] like a normal person.

Code: [Select]
rem Safely checks to see if the dimension, by name
rem exists on the item. It does this using a for
rem for loop. This helps to avoid errors because
rem a dimension does not exist by name on the item.
function hasDimension(item, dimension)
    dim result
    dim i
    for i=1 to item.dims
        if item.dim[i].name = dimension then
            result = true
        end if
    next
    return result
end function

« Last Edit: Feb 04, 2026, 22:23:49 PM by cyan »