Jump to content
Developer Wiki and Function Reference Links Read more... ×
Sign in to follow this  
macoovacany

VS wishlist check.

Recommended Posts

Before I go ahead and put the following features on the VS wish list, I'd like to check that they are definitely not possible in VS:

1) Functions as first class objects.

So I can have and array of functions can call the specific function I need by looking up into an array. At the moment I use a function with a case statement to act the same. (Ugly, but it works.)

2) Expression matching or regular expression matching in criteria.

e.g. length(C=Wall[\wa-zA-z0-9]*))l

count(L='Battens'& C='TH4055'& hLength<600);

3) Passing criteria in and out of procedures or functions, to generate them at run time.

4) Calling a plug-in command from another plug-in. NOT $include, and not DoMenuTextByName.

I'd be grateful for any comments, particularly of the "VS already does this" variety.

Timbo

Apologies for any syntax errors.

Share this post


Link to post

Number 3 should be possible. Criterea are just text. So when you use own functions to pass through criterea, use for example 'C=Wall' as a parameter to your own function and in that function give it to a criterea function. I do this all the time and it works.

Share this post


Link to post

#4) Can you give an example of what you are trying to do? DoMenuTextByName often works well -- it's far less kludgey than you may think.

As a general note, VS is based heavily on Pascal and is also not a high development priority. You may find that you have to wait a bit, even if your requests eventually get implemented. You may want to also post some specific "How do I..." questions.

I noticed that a lot of your requests involve criteria. Personally, I've found that I used a lot of criteria-based functions when I started scripting, but as my code became more sophisticated I used them less and less. You may find that there are other ways of doing what you want that avoid criterium.

-Josh

Share this post


Link to post

#1 - As was stated before, VS is based on the pascal language and do not believe you can have functions as Array parameters.

#2 & 3

If you want to have more specific criteria, it is doable with

ForEachObject as in the following:

PROCEDURE Test;

VAR

gTotObj1,gTotObj2: INTEGER;

FUNCTION CountObjs(layName,className: STRING; maxLng: REAL): INTEGER;

VAR

totObj: INTEGER;

PROCEDURE ProcessObj(objHdl: HANDLE);

VAR

objLng: REAL;

BEGIN

objLng:= HLength(objHdl);

IF objLng < maxLng THEN

totObj:= totObj + 1;

END;

BEGIN

totObj:= 0;

ForEachObject(ProcessObj,((L=layName) & (C=className)));

CountObjs:= totObj;

END;

BEGIN

gTotObj1:= CountObjs('Battens','TH4050',400);

gTotObj2:= CountObjs('Battens','TH4055',600);

END;

Run(Test);

#4 - You need to explain this one because I do not understand what you are expecting. DoMenuTextByName works for menu commands and ResetObject works for plugin objects.

Share this post


Link to post

RE criteria:

All the times I've had to use the criteria it has been of the form

(C=?Edged?) ;{Note the C= isn't a part of the string }

I didn't think that 'C=Wall' would work. I'll try it shortly.

Re foreach:

Yeah that's a pattern I use a lot. Either the ForEachObject or ForEachObjectInLayer function.

Re running plugins

It would be good to have a 'main' plugin which can then customize when to run other plugins. Including a lot source text seems... ugly.

It would cut down on the number of menu items that would clutter the menu system, especially if the sub plugin would only be run as part of a batch.

Does the DoMenuTextByName function have to ahve the plugin as part of the menu user visible menu

Re ResetObject

??? The API reference seems a bit vague as to how this would work with regard to #4.

Miguel:

My code for this case is almost exactly the same, except I'm using foreachobjectinlayer.

Cheers for your replies.

Timbo

Share this post


Link to post
RE criteria:

All the times I've had to use the criteria it has been of the form

(C=?Edged?) ;{Note the C= isn't a part of the string }

I didn't think that 'C=Wall' would work. I'll try it shortly.

It does works, I do this. Criterea are just strings.

Edited by DWorks

Share this post


Link to post
RE criteria:

All the times I've had to use the criteria it has been of the form

(C=?Edged?) ;{Note the C= isn't a part of the string }

I didn't think that 'C=Wall' would work. I'll try it shortly.

You may know this already, but this is important if you are using criteria in scripts so I am including it here.

You can't use a form like

Var Variable:String;

...

Variable:='None';

CriteriaArea((C=Variable));

but you can use

Variable='C=None';

CriteriaArea((Variable));

You can even use the Concat command to build complicated criteria strings.

Share this post


Link to post

Re running plug-ins

Just to clarify, by "plug-in" do you mean plug-in menus, or do you mean objects and tools as well.

VS can run sub-procedures, which seems to be what you need. If the procedure is used be more than one plug-in menu, put it in an include so it can be shared.

What do you mean by "Including a lot of source text seems... ugly"?

-Josh

Share this post


Link to post

You can't use a form like

Var Variable:String;

...

Variable:='None';

CriteriaArea((C=Variable));

Pat,

I do this all the time. The C for class is not a string.

I have not used this in a while but the following also worked for records:

recName,fieldName: STRING;

(recName.fieldname < 100')

Share this post


Link to post

Not what I am seeing here.

Create a drawing with a known number of objects in the None class and run this script:

Procedure Test;

Var S1,S2:String;

Begin
S1:='None';
S2:='C=None';
Message(Count(C=S1),' ** ',Count(S2));
End;

Run(Test);

On VW2009 SP2 Mac, I get zero listed for the S1 case and the correct number listed for the S2 case.

What are you doing differently?

Share this post


Link to post

The following is straight from the VS Language Guide

Search Criteria Format

Syntax

Search criteria in VectorScript are composed of two parts: 
the search attribute type specifier and the search value. 
The search attribute specifier indicates which attribute will 
be used to filter objects in the document; the search value 
specifies the value to be found and matched by the search 
operation. For example, the search criteria term:

 (C=?Edged?)

indicates that a search should be performed for any objects 
whose class is Edged. In the criteria term, the C attribute 
type indicates that the search should be performed on the 
class attribute of objects in the document. The search value 
Edged indicates what class will be a match in the search 
operation.

Unless this was changed in VW 2009, it has worked for me since the addition of records until 2008 which is what I currently have.

Could this be a bug in 2009? If so, it would be another reason not to upgrade because all the programs I have developed use this format.

Share this post


Link to post

I have never been able to use a search string of

SomeCriteria=Variable

Julian gave me the secret of putting the criteria and equals inside the string back in 2005, so I know it has not worked for me for at least that long.

Did you try the script I sent in 2008?

Share this post


Link to post

This works this way since VW11 at least.

Don't worry Miguel, it is still as you always had it.

You never could put the variable straight off mixing it with the dedicated criteria calls: the variable S1b works in "Count".

Procedure Test;
Var S1, S1b, S2:String;

Begin
S1:= 'None';
S1b := Concat('C=', S1);
S2:='C=None';

Message(Count(C=S1),' ** ', Count(S1b),' ** ',Count(S2));
End;
Run(Test);

Share this post


Link to post
#4) I've found that I used a lot of criteria-based functions when I started scripting, but as my code became more sophisticated I used them less and less

Josh, this is weird. The more I script (since 1992) the more I find criteria sophisticated. I turned lots of my library of subroutines into criteria parsing calls, because their flexibility is amazing. And often they avoid loops.

orso

Share this post


Link to post

Pat,

I ran your script and as you said, the first count returned 0.

However, I changed the variable names to cls1 and cls2 and the code executed correctly.

Procedure Test;
Var 
cls1,cls2:String;

Begin
cls1:='None';
cls2:='C=None';
Message(Count(C=cls1),' ** ',Count(cls2));
End;

Run(Test);

It seems that the variable name has to be 4 characters or longer for the code to work.

Share this post


Link to post

Right! How weird.

c2:=Concat('C=None'); { works even with short var name }

c1:= concat('Dimension');

But testing further I find that hard-coding a name is not reliable.

For example:

Concat('C=None')

Try this with some objects classed either "None" or "Dimension". The result for c2 and c4 is simply weird. While the result for c1 and c3 is correct.

Procedure Test;
Var 
c1, c2, c3, c4 :String;

Begin
c1:= Concat('None');
c2:= Concat('C=None');
c3:= Concat('Dimension');
c4:= Concat('C=Dimension');
Message(Count(C=c1),' ** ', Count(c2), '**', Count(C=c3),' ** ', Count(c4));
End;

Run(Test);

But remains the fact that this below will always work without failure or weird behavior, and probably this how we need to work, since most of the time the name only will be in a variable and one builds the criteria string accordingly:

sn := 'None';
s := Concat('C=', chr(39), sn, Chr(39));

Share this post


Link to post

Miguel, Orso,

Interesting that the rules of VS are still obtuse enough that even those of us who who have been doing this a long time still don't understand them.

Interesting that we were all right for the examples we provided.

So, do you think the short variable name not working is a bug we should submit?

I am also fond of the CHR(39) method of assembling strings for this type of strings.

Share this post


Link to post

Yes, I believe it is a bug since it is not giving us the result expected if we follow the language guide.

Using a single string for the criteria should also be documented in the guide. Although I have not needed this functionality, it is nice to know that you can build the criteria as a single string also.

Share this post


Link to post
Miguel, Orso,

So, do you think the short variable name not working is a bug we should submit?

Miguel perhaps should submit (he's the clever discoverer!), but I don't think that after all these years that will be fixed on the spot.

If Miguel doesn't have time/wish to submit, I can do it remarking that he found the issue.

Whereby I don't know if it is really a bug.

Perhaps the bug is that

1- documentation should be more clear

2- an error/warning should be raised upon syntactically invalid criteria also in this case (like when you miss a braket or so).

orso

Share this post


Link to post

I am also fond of the CHR(39) method of assembling strings for this type of strings.

(you both Pat and Miguel perfectly know why)

New users:

always wrap names to be inserted in criteria in "Apostrophe". Exactly as you would do in worksheets criteria.

If your variable contains a name with spaces, the criteria will be simply invalid. In doubt, always wrap.

The name "none" wouldn't need it but the name "none 2" would.

Share this post


Link to post

> Just to clarify, by "plug-in" do you mean plug-in menus, or do you mean objects and tools as well.

Most of my plugins are commands similar to:

"count the length of classes that have "some-text" in their name, and print the result to layer X using class Y.

or

"find the text in layer X and parse it to get some numbers. Count the numbers and print to layer Y"

or

"find the lines in layer X that don't meet spacing requirements and outline them". etc

At the moment there are about a dozen of these plugins, and including all their source code into one command plugin seems ugly. All the commands don't require any inputs, so it's just "GO!" for each. I'd like to have a command like RunPlugin('Plugin1');

RunPlugin('Plugin2');

RunPlugin('Plugin3');

RunPlugin('Plugin4');

RunPlugin('Plugin5');

Timbo

Share this post


Link to post

Timbo,

I think what you're looking for is using includes to define sub-procedures. Each command would be in its own text file:

PROCEDURE Plugin1;

CONST

{your constants}

VAR

{your vars}

BEGIN

{your calls}

END;

Your calling procedure for your menu item would look like:

PROCEDURE Main;

CONST

{your main constants}

VAR

{your main vars}

{$INCLUDE path_and_Plugin1_filename}

{$INCLUDE path_and_Plugin2_filename}

{etc...}

BEGIN

Plugin1;

Plugin2;

{etc}

END;

Run(Main);

Hope this makes sense.

-Josh

Share this post


Link to post

To the best of my knowledge, you cannot call custom Menu Commands from within another Menu Command or Plug-In object. If you find a way to do so, please post it.

Raymond

Share this post


Link to post

In commands you have the workaround to call other dialogs from a dialog. Execute them and do something else upon quitting of the second (or later) dialog.

The simplest solution is to use includes (I just saw that Josh told you the same). Remember that your scripts are now to be treated as subroutines, so remove the call "Run" at the end of each singular script:

PROCEDURE ChainMe;
{$INCLUDE path/to/routine/RunPlugin2}
{$INCLUDE path/to/routine/RunPlugin3}
{$INCLUDE path/to/routine/RunPlugin4}
{$INCLUDE path/to/routine/RunPlugin5}

BEGIN
	RunPlugin2;
	RunPlugin3;
	RunPlugin4;
	RunPlugin5;
END;
Run(ChainMe);

orso

Edited by orso b. schmid

Share this post


Link to post

Timbo,

???If you want a script to be both stand-alone and callable from a larger script you will need a library (folder) of script parts that you can assemble with $INCLUDE statements in other files.

For example:

???PROCEDURE SetLW6;

???PROCEDURE SetFillBlue:

???PROCEDURE SetOutline;

???PROCEDURE SelectAllRects;

might be routines you want to call individually or from another script. In your library, split the small routines into two pieces; one that has the procedure definition in one file; and the other that has two lines, an $INCLUDE and a RUN();

File "SetLW6.px":

???PROCEDURE SetLW6;

???BEGIN

??????PenSize(6);

???END;

File "RunSetLW6":

???{$INCLUDE \YourLibrary\SetLW6.px }

???Run(SetLW6);

???File "RunSetLW6" is the file you would use to make a Menu Command PIO for the stand-alone execution of "SetLW6".

???In a larger script you can access the procedures in your library by adding several $INCLUDE files then calling the included procedures.

File BIG_SCRIPT_1:

???PROCEDURE BIG_SCRIPT_1;

??????{$INCLUDE \YourLibrary\SetLW6.px }

??????{$INCLUDE \YourLibrary\SetFillBlue.px }

??????{$INCLUDE \YourLibrary\SelectAllRects.px }

???BEGIN

??????{ Your code here }

??????SetLW6;

??????SetFillBlue;

??????{ Draw something here }

??????DSelectAll;

??????SelectAllRects;

??????{ More of your code here }

???END;

???Run(BIG_SCRIPT_1);

???If you want to call BIG_SCRIPT_1 from other scripts, then split it in two pieces as shown above. With this setup, you can make changes to any of your files and they will be reflected in all procedures that use them.

???One last caveat, always have at least one blank line at the end of each $INCLUDE file. Without it you will get compiler errors.

HTH,

Raymond

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×