Jump to content
Developer Wiki and Function Reference Links ×

Getting handle to symbol in symbol definition


Recommended Posts

I have a script where I am am trying to change record format values of a symbol that is inside a symbol definition but I cannot seem to get a handle on it (pun intended). I was using the following to traverse the symbol definition list:

 

ForEachObjectInList(SetFieldsSD,0,2,FSymDef);

 

I thought this would do a deep traversal but it does not seem to do that in this case. This works for individual symbols with the record format attached, but not those that are within another symbol definition. The parent symbol definitions are of the "blue" type (symbol to group). Anyone have any tips that can get me to the nested symbol?

Link to comment

What you have SHOULD (I have not tested this) run the SetFiledSD function once on each symbol definition. 

 

What do you have in SetFieldSD?  I think you will need to use FInSymDef(Handle) to get the first object in the symbol definition. Then step through the objects in the symbol definition and set any that are symbols to attach the record.

 

But you say they are Symbol to Group.  Is there actually another symbol defined inside the blue symbol? Because if not, then you will need to assign the record to something other than the symbol definition because that object goes away when it is converted to the group.

 

If you want to share more info on what you are trying to do be glad to try and help more.

Link to comment

The script runs fine on symbol definitions with the appropriate record format attached - I am changing the value of the fields in the record format using SetRField. The problem is for symbols that are within the symbol definition. For example, I have symbol A by itself and the record format updates fine. But if the same symbol definition A is inside another symbol (say symbol definition B), the version of symbol A inside symbol B will not update. I would have thought that ForEachObjectInList(SetFieldsSD,0,2,FSymDef); would traverse the symbol B to get to symbol A.

 

This is SetFieldSD

 

FUNCTION SetFieldsSD(h :HANDLE) :BOOLEAN; {set symbol fields for objects}

BEGIN
    
    IF (GetRField(h, cpaRF, cpaRF4) = RF4) THEN BEGIN {for symbols with correct serial record field}
        
        SetRField(h, cpaRF, cpaRF1, RF1);
        SetRField(h, cpaRF, cpaRF2, RF2);
        SetRField(h, cpaRF, cpaRF3, RF3);
        
    END; {If}
END; {SetFieldsSD}

 

Thanks Pat.

 

Edited by David Poiron
Link to comment

I think what is happening, is that the "included" symbol is not a symbol definition, but rather a symbol instance. And since in symbol instances there is not link between the record attached to the definition, only the data that was attached to the definition when it was instantiated.

 

As I said, I think you are going to have to walk the contents of the symbol definition and see if each object is a symbol and if you want to attach the record or update the record values if it already exists.  You could probably do this with a nested ForEachObjectIn List, but I think a simple loop with Next Object is probably easier.  Pseudocode below

 

FUNCTION SetFieldsSD(h :HANDLE) :BOOLEAN; {set symbol fields for objects}
BEGIN
    
    IF (GetRField(h, cpaRF, cpaRF4) = RF4) THEN BEGIN {for symbols with correct serial record field}
        
        SetRField(h, cpaRF, cpaRF1, RF1);
        SetRField(h, cpaRF, cpaRF2, RF2);
        SetRField(h, cpaRF, cpaRF3, RF3);
        
    END; {If}

	H2:=FInSymDef(h);

	While H2 <> Nil do
		Begin
			If GetTypeN(H2)=15 then		{Check is symbol}
				Begin
					{Code goes here to check if proper record is attached and update the values}
				End;
			H2:=NextObject(H2);
		End;

END; {SetFieldsSD}

 

HTH. Ask again if you need more info.

  • Like 1
Link to comment
  • 8 months later...

It depends a lot on what you are trying to do and what outcome you want.

 

Vectorscript supports recusion, so you could probably write a custom procedure/function that would enter a symbol and then if it found another symbol in the definition call itself with the new symbol definition.

 

More information on what you are actually trying to do would help.

Link to comment

@Jiajing,

   To get a handle to objects inside a Symbol Instance, you have to take a more circuitous route. First, symbol instances are not container objects. The real container is the Symbol Definition. To get a handle to a Symbol Definition when you start with a handle to a Symbol Instance try this:

 

# return a handle to the first object inside a symbol definition where H points to a symbol instance
if (vs.GetTypeN(H) == 15):
	SymDefName = vs.GetSymName(H)
	SDefHnd = vs.GetObject(SymDefName)
	InsideH = vs.FIn3D(SDefHnd)
	

vs.Message(InsideH, '  ', vs.GetTypeN(InsideH))

 

or you can express it in one line:

 

# return a handle to the first object inside a symbol definition where H points to a symbol instance
InsideH = vs.FIn3D(vs.GetObject(vs.GetSymName(H)))

Raymond

Link to comment

Hi @Jiajing,

   It seems to work on all container objects, as best I can tell. As you can see, it even works on symbol definitions. I think I saw @Julian Carr use it once in an unexpected way a couple of decades ago, and I've been using it ubiquitously ever since. It's never caused a problem, so I keep using it. It's my magic can opener.

 

Raymond

 

PS - Thanks, Julian.

  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...