question

Arun Kr avatar image
5 Likes"
Arun Kr asked Matt Long commented

Difference between Object and treenode in FlexScript Dot Syntax

Hi Support,

I am getting an error for the script given below. (The aim is to change the xlocation of the source object by 2)

Error Message:

exception: FlexScript exception: Label property location retrieved on /Source1. Label does not exist. at /0 c: /testlink_instance i: /testlink_associated

treenode src = model().find("Source1");
src.location.x += 2;

Instead of the script lines

treenode src = model().find("Source1");
Object srcAsObject = src; 
src.as(Object).location.x += 2; 

Conceptually both are same right ? Or location can be used only with the object class?

Please correct me, if I had made a wrong question.

But the script given below is working.

treenode src = model().find("Source1");
Object srcAsObject = src; 
srcAsObject.location.x += 2;

Regards,

Arun KR

FlexSim 17.0.0
flexscriptobjecttreenodedot syntax
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

1 Answer

Kaspar Chabot avatar image
5 Likes"
Kaspar Chabot answered Matt Long commented

Dear Arun KR,

I might be totally wrong about this, but for the moment this is how I think it works...

I think the reason this isn't working is the same as pointed out in the answers to this post.

Basically, you cannot use some of the dot syntax specific to certain classes on treenodes, if I'm not mistaken.

Probably you can use .location on the Object class, but e.g. not on the Table class, both of which can be referenced by a treenode

Since the .location syntax cannot be used for everything that can be referenced to as a treenode, src.location will be interpreted as being a label called 'location' attached to the treenode src.

Kind regards,

Kaspar

· 11
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Matthew Gillespie avatar image Matthew Gillespie ♦♦ commented ·

Yes, the Object class is a subclass of treenode meaning it can do everything a treenode can do, but also expands on it by adding more properties and methods. If you look at the FlexScript Class Reference page in the User Manual you'll see that location property is on the Object class, but not the treenode class. Also on the treenode page you'll find this discussion about the relationship between treenode and Object:

The treenode class is the base class for all objects and nodes accessed in FlexSim's tree. While you can access more data and functionality specific to nodes with object data by using the Object class, treenode is the most basic interface. First, it gives access to data and functionality associated with the tree structure itself. Second, it gives access to basic data stored on the nodes themselves, such as node names and data values. Third, since so much modeling logic uses labels, the treenode class provides a mechanism for easy manipulation of labels on objects, tokens, and task sequences.

The treenode class can be automatically down-cast to a subclass such as Object.

treenode src = model().find("Source1");
Object srcAsObject = src; // auto-down-cast to object

You can also explicitly down-cast using the as() keyword

src.as(Object).location.x += 2;

When FlexScript performs a down-cast, if the node is not a valid instance of the target class type, an invalid cast exception will be thrown.

Object src = model().find("Tools");// throws invalid cast exception
model().find("Tools").as(Object).location.x += 2; // throws invalid cast exception

You can check if a node is a given subclass type with the is() keyword.

if (model().find("Source1").is(Object)) {
	...
}
5 Likes 5 ·
Matt Long avatar image Matt Long Matthew Gillespie ♦♦ commented ·

In case it isn't plainly understood from the above comment, you can combine the two lines:

treenode src = model().find("Source1");
Object srcAsObject = src; 

into one line:

Object src = model().find("Source1");
2 Likes 2 ·
Arun Kr avatar image Arun Kr Matt Long commented ·

Thanks Matt, this looks easy

0 Likes 0 ·
Arun Kr avatar image Arun Kr Matthew Gillespie ♦♦ commented ·

Thanks for the detailed explanation.

0 Likes 0 ·
Arun Kr avatar image Arun Kr commented ·

Thanks @Kaspar Chabot , looks like that is the answer.

0 Likes 0 ·
Joris Van Poucke avatar image Joris Van Poucke commented ·

@Matt Long:

As I understand there is no way to retrieve the x-location of for instance a source in one line, comparable to the previous -since 17.1 unusable- command xloc(model().find("Source1")) ?

0 Likes 0 ·
Matthew Gillespie avatar image Matthew Gillespie ♦♦ Joris Van Poucke commented ·

You can do that in one line:

model().find("Source1").as(Object).location.x

Usually though, you'll be doing that on a variable stored as an object. For example, in any of the Fixed Resource triggers current will be defined in the header as an object so getting it's x-location would look like this:

current.location.x
1 Like 1 ·
Joris Van Poucke avatar image Joris Van Poucke commented ·

@Matthew Gillespie, but then I get a cast error. Or is this a bug in 17.1?

0 Likes 0 ·
Matthew Gillespie avatar image Matthew Gillespie ♦♦ Joris Van Poucke commented ·

No, I'm not aware of any bug like that. What code are you using and where is it? Can you attach your model?

0 Likes 0 ·
Joris Van Poucke avatar image Joris Van Poucke Matthew Gillespie ♦♦ commented ·

You are right. I made a seperate demo model to test just this, and everything's working as it should there. I'll figure out what I've done wrong in my real model.

Apologies and thank you!

0 Likes 0 ·
Matt Long avatar image Matt Long Joris Van Poucke commented ·

We didn't update any code headers in older models, so if you had an object created in a 2016 release and then try and use object methods like current.location.x, it won't work. You would need to manually update the code header to say:

Object current = ownerobject(c);
0 Likes 0 ·