Beijer Electronics (formerly QSI Corporation)

Manufacturer of Mobile Data and Human Machine Interface Terminals.
It is currently Wed Nov 22, 2017 7:31 am

All times are UTC - 7 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Tue Jul 28, 2009 9:55 am 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
Let me start off by saying that I do a good amount of Qlarity coding outside of the Foundry editor. I actually prefer the Foundry editor itself, but unfortunately it makes it difficult to separate larger projects into pieces, so it's almost mandatory on our part. With this said, what we have created is a modular application that will load templates that we call "Modules" at runtime, and will allow each to be run separately. We have done this because our intent was to create a handheld terminal that could be used with several pieces of equipment. Our Modules can be created separately from the rest of our application, and can later be compiled (#include'd) in.

I have been working to create an environment in which the Modules can be completely written in Foundry, and later compiled in. So far this works well, but misses some of the great features of the Foundry editor; namely, omnicomplete/intellisense functionality in which an objects functions/properties can be accessed easily within a popup list. I'm not entirely sure how the system works, but as far as I can tell it will only compile and display this information if it is in the immediate buffer/file or in a library that has been included using the GUI. Unfortunately this means that I can't access any of the objects/variables/functions that are in any #include'd files. Is there any way to remedy this? Should I just put it all in a special library with links to any objects I want to be available? Or is there a better way?

Thanks,

Ryan


Top
 Profile  
 
PostPosted: Tue Jul 28, 2009 10:10 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
I am not 100% sure I quite understand what you are doing, but perhaps I can explain adequately how we code here and see if it helps you.

The way we typically code here (as we probably maintain the largest code base of Qlarity code anywhere) is as follows:

We place sensible chunks of Qlarity code in seperate QLY files. Typically this will a single object or a few closely related objects and any global code (enums, functions etc) needed to support them.

We then have a command line utility that we use here to turn them into a library file. This allows us to maintain our objects in individual .qly files that are of reasonable size, and with a single batch command build some or all of our libraries at once.

One advantage of this method is that we can place test code in the same workspace that defines an object. The utility we use is able to filter out test code and other code that is not necessary so that it won't appear in the library.

Because the QF autohelp feature processes any loaded libraries, the autohelp is always available.

Library code is only added to the workspace when it is explicitly included (e.g. library basic source ButtonV2) or implicitly included by adding an object that is defined in the library. This means that a large library such as DataProc does not burden your workspace with all its code unless you actually instantiate one of every type of object in it.

If this would be of interest let us know and we can send you the library building utility.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
PostPosted: Tue Jul 28, 2009 10:29 am 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
Before I reply to everything, are you talking about templates when you say objects? Also, are you talking about NLS?


Top
 Profile  
 
PostPosted: Tue Jul 28, 2009 10:35 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Sorry, yes I mean templates. Although it is possible to create and place object instances in the library as well with this technique, there isn't as much use for that.

And yes, I am referring to NLS.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
PostPosted: Wed Jul 29, 2009 7:40 am 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
Hi Jeremy,

Currently we do use NLS to put all of our templates together, but outside of Foundry using VIM/Crimson editor with syntax highlighting. This works fine for us, but maybe we will consider doing some of this work in the Foundry Editor.

My main question didn't really pertain to that though - our situation is different than most, so I'll try to explain it a little better. Right now, 100% of our code base is written outside of the Foundry editor. We have a global file from which other pieces of our application are included in, for example: 'include "soft_key_bar.qls" <-- This file would contain the softkey bar objects. We also have a Module template that includes certain functions to "start" and "stop" a module. A module is basically just a set of screens and widgets, and represents the ability to control some piece of equipment. We DO use the Foundry editor for simulation though - we just include our global file in the advanced code area.

Instead of building these modules in a plain text editor, I would like to build them in the Foundry editor. I am able to include all of my custom libraries and access those, but the real problem is that certain global system objects are expected to exist, and can be used, for instance, to stop a module. If I want to access these objects in the Foundry editor and have them recognized, I won't be able to because they are instantiated in some external file. Maybe instead of directly linking to these global objects I will just add certain properties to the Module template for objects I will need access to, and I can just assign them to the correct objects at startup. This is probably the best option and will decouple it anyway (but maybe there is another?).

Thanks


Top
 Profile  
 
PostPosted: Wed Jul 29, 2009 7:54 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Quote:
We also have a Module template that includes certain functions to "start" and "stop" a module. A module is basically just a set of screens and widgets, and represents the ability to control some piece of equipment. We DO use the Foundry editor for simulation though - we just include our global file in the advanced code area.


What do you gain from having this in a .qls file versus in a library? With a little bit of work you should be able to poke this bunch of object instances into a library entry. If you do so, you won't gain Layout View access to them, but the autohelp will work, which was what I thought was the original question.

Including object instances is not something that NLS normally does, but using the -i option it can do so. Later versions of NLS allow the -i option to take a regular expression and include only those instances whose name matches the regex.

You would then modify your code from something like

#if USE_MODULE_1
include "Module1.qls"
#endif

to

#if USE_MODULE_1
library rhuffman source Module1
#endif

Same code gets included, but is now subject to autohelp.

Plus, since NLS can intelligently include/ignore items, you could (if you desire) edit Module1 in Qlarity Foundry instead of VIM/Crimson.


You are correct that the autohelp feature does not attempt to follow "include" or "#include" statements

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
PostPosted: Wed Jul 29, 2009 8:57 am 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
Quote:
What do you gain from having this in a .qls file versus in a library? With a little bit of work you should be able to poke this bunch of object instances into a library entry. If you do so, you won't gain Layout View access to them, but the autohelp will work, which was what I thought was the original question.


We don't keep everything in a library because otherwise we can't separate everything across separate files that way, at least not to any great extent. I have one other person I work with, so any modifications would need to be done exclusively, and this would mean having exclusive access to a large number of templates or objects. This also creates a sort of awkwardness for Subversion because new revisions of a file would be affect a large library file, and wouldn't represent incremental changes across multiple files separately.

BUT, keeping everything in separate QLY files and just merging them using NLS when changes are made would also eliminate thit problem as well (assuming edits weren't being made to the lib itself). Or, even, we could just merge our .qls files with NLS and be in the same situation. Correct me if I am wrong, but it sounds like this is essentially what you guys do over there?

It sounds like we have been taking the wrong approach with this. So you think importing our objects and templates into QLY files would be the best, and then use NLS to merge related files together? And then in a main/global sort of QLY file, all the necessary objects would be "imported" using "library ... source ..." statements?

Where can I get an updated copy of NLS? In one of your posts you mentioned that NLS strips away test code - what did you mean by that?

One other semi unrelated question: We've run into the situation where our objects end up having naming collisions, simply because all objects are global. We ended up adopting a naming scheme that fixed this for the most part, but we've ended up with a bunch of awkwardly named objects that are hard to read. Do you have any solution for this? It can just be annoying to have something like an enter button named "EnterButton", but then have to add some prefix to it because otherwise it would collide with other buttons on other pages that have a similar function (and thus, the same name).

Thanks for all the help Jeremy.


Top
 Profile  
 
PostPosted: Wed Jul 29, 2009 9:33 am 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Lets get the global naming question out of the way first.

We do not currently have a solution to this. In a future version of Qlarity we would like to add some sort of feature to reduce the chance of a naming collision. Possibly a namespace type feature. However this would be a long ways out.

For our development, we treat .qlib (and .lib) files as compile outputs (i.e. we don't put them in subversion). * Our qly files are the ones we store in subversion. You get in the habit of running NLS a lot.

Quote:
It sounds like we have been taking the wrong approach with this. So you think importing our objects and templates into QLY files would be the best, and then use NLS to merge related files together? And then in a main/global sort of QLY file, all the necessary objects would be "imported" using "library ... source ..." statements?


That would be best for me. I am not familiar enough with what you are doing to be 100% certain that would be best for you. But it is how we do things. Although we don't have a lot of object instances in libraries, we do keep all our templates and global code there as well as the few library object instances that we do have.** You get a number of benefits with this, including automatic #if guarding in case you have a specific application workspace that needs to specialize the code from a library entry it can.

You are correct, then you have your actual application workspace (the one that would be downloaded to a unit) that can include the library code with the
Code:
library <name of library> source <name of library entry>
syntax.

The latest NLS can be downloaded at http://www.qsicorp.com/engfiles/bleeding_edge/nls.zip

If you were using the -i option in the past, the equivalent option is now -i .* The newer version can be used to select objects with a given prefix only (and thereby omitting any objects that don't have that prefix). For example, if you wish to include object instances that begin with "_fmt" you would use -i _fmt.*

Test code is typically surrounded with #if test blocks. These will be stripped by NLS and not placed in the library.

A normal workspace might look like this:

Code:
#option _SS_Lines
#option _SS_Marquee

#option test
#if test
init default_mbcom_obj := mbcom_1
#endif



NLS, by default strips anything in a #if test block. It also ignores #option test lines. If it encountered a #ifnot test block, the #ifnot test and #endif would be stripped, but the code in the block would remain. Essentially it acts as a form of preprocessor. You can add additional options that will be defined to NLS with -d and ones to be never defined with -u. Although we don't use the -d and -u options very frequently anymore, we used to use them a lot in our old code. (We used to use NLS multiple times on a single block of code to make objects that were nearly identical except that they operated on different data types, however this practice was deprecated with the introduction of the sysfont data type).




-----------------------------------------------------------------
* This is not technically correct, but illustrates the principle. What we do in practice, since NLS cannot actually create a library file is we keep empty .qlib stub files in subversion that are never modified. We then copy the stub file to the real file and proceed to build it. For instance our NLS.ini file for Dataproc.qlib looks like.

#shell "copy ..\_Libraries\stubs\Dataproc.qlib ..\_Libraries > nul"
#Library ..\_Libraries\Dataproc.qlib
-w 2.1
-fa -as SystemStatus SystemInfo.qly -i "_{1,2}SysProp.*"
-fa -as EventLogViewerV2 EventLogViewerV2.qly -i "_elv.*"
-fa -as EventLogV2 EventLogV2.qly
-fa -as TerminalSetup TerminalSetup.qly -i "_PoS_.*"
... more like this ...
-ft -ab _StarIconV2 staricon.bmp -vb _StarIconV2 1.01
#shell "copy ..\_Libraries\Dataproc.qlib %G70NativesPath% >nul"

-----------------------------------------------
** The TerminalStatus object released in 2.60 is a very good example of instances that are created in a library.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
PostPosted: Wed Aug 12, 2009 4:48 pm 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
Hi Jeremy,

Thanks for the thorough reply. Just as an update, I have modified a good portion of our code base to follow this scheme, and so far it has been working well. I'll let you know if I run into any issues.

Thanks!

Ryan


Top
 Profile  
 
PostPosted: Wed Aug 19, 2009 3:54 pm 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
I've run into a problem. I have a certain screen object that is included in a library, and is drawn to the screen in layout view. How can I keep it from being drawn without overriding a bunch of draw functions manually? I would prefer that it did not show up.

Thanks,

Ryan


Top
 Profile  
 
PostPosted: Wed Aug 19, 2009 4:07 pm 
Offline
User avatar

Joined: Thu Mar 02, 2006 2:12 pm
Posts: 487
Location: Salt Lake City, Utah
You can put some pre-compile directives to cause it to appear differently in layoutview.

Example
Code:
#IF _TOOL
init xpos := -1000
#ELSE
init xpos := 0
#ENDIF

_________________
Ron L.

http://www.beijerelectronicsinc.com/


Top
 Profile  
 
PostPosted: Wed Aug 26, 2009 11:53 am 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
That worked great, thanks Ron!


Top
 Profile  
 
PostPosted: Thu Aug 27, 2009 10:31 am 
Offline
User avatar

Joined: Fri Feb 01, 2008 4:50 pm
Posts: 101
I've run into a problem where I am writing a certain library entry that needs certain resources. Is there any way to compile resources into a library, or at least have them compiled in at compile time (i.e. not have the resource statements removed when NLS'ing a library)?

Thanks,

Ryan


Top
 Profile  
 
PostPosted: Thu Aug 27, 2009 12:04 pm 
Offline
QSI Support
QSI Support
User avatar

Joined: Wed Mar 08, 2006 12:25 pm
Posts: 881
Location: Salt Lake City, Utah
Yes.

You need to modify your nls.ini to add the resources to the library itself

For instance

-ab myBitmap myBitmap.bmp

would add a bitmap to the library.

To reference the bitmap, you need to explicitly reference the resource. This would be done with a source code line like

library mylib bitmap myBitmap

(This code line may be in the library itself, in which case importing the code entry would also import the bitmap)

Type nls /? to see all the possible resource options.

_________________
Jeremy
http://www.beijerinc.com


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 7 hours


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 post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group