KnowBrainer Speech Recognition
Decrease font size
Increase font size
Topic Title: Code Reuse in KnowBrainer / Dragon commands
Topic Summary: Q: Shared functions, please? A: '#Use ...
Created On: 05/11/2020 05:04 PM
Status: Post and Reply
Linear : Threading : Single : Branch
 Code Reuse in KnowBrainer / Dragon commands   - Ag - 05/11/2020 05:04 PM  
 Code Reuse in KnowBrainer / Dragon commands   - Ag - 05/11/2020 05:06 PM  
 Code Reuse in KnowBrainer / Dragon commands   - Ag - 05/11/2020 05:07 PM  
 Code Reuse in KnowBrainer / Dragon commands   - Ag - 05/11/2020 05:22 PM  
 Code Reuse in KnowBrainer / Dragon commands   - PG LTU - 05/11/2020 05:48 PM  
 Code Reuse in KnowBrainer / Dragon commands   - Ag - 05/11/2020 07:58 PM  
 Code Reuse in KnowBrainer / Dragon commands   - PG LTU - 05/11/2020 10:12 PM  
Keyword
 05/11/2020 05:04 PM
User is offline View Users Profile Print this message

Author Icon
Ag
Top-Tier Member

Posts: 495
Joined: 07/08/2019

In other threads, such as referred to in one of the items quoted below, I bashfully ask "How do I share functions between KnowBrainer or Dragon Commands?"

 

Bashfully, because such code reuse is the very first baby step of programming, and after using KnowBrainer for almost 9 months I still haven't started doing it.

 

Fortunately, Edgar replied, and I will embed his reply here.

 

Starting this new thread, to make it easier for the next person to find it.

 



-------------------------

DPG15.6 (also DPI 15.3) + KB, Sennheiser MB Pro 1 UC ML, BTD 800 dongle, Windows 10 Pro, MS Surface Book 3, Intel Core i7-1065G7 CPU @ 1.3/1.5GHz (4 cores, 8 logical, GPU=NVIDIA Quadro RTX 3000 with Max-Q Design.



 05/11/2020 05:06 PM
User is offline View Users Profile Print this message

Author Icon
Ag
Top-Tier Member

Posts: 495
Joined: 07/08/2019

The following was actually posted by Edgar in answer to my question in a different thread:

 

'#Uses "C:\Program Files (x86)\KnowBrainer\KnowBrainer Professional 2017\WindowsAPI.txt"

 

http://www.knowbrainer.com/forums/forum/messageview.cfm?catid=11&threadid=34338&enterthread=y

 

@Ag - sorry if that was too cryptic, I was sitting in the dark with no Dragon!

For functions and constants what you want to do is put them in a text file then put the text file somewhere obvious (as you can see, I use the KnowBrainer install folder but "where" does not matter).
Here is a "snipped" idea of what that file would look like:
' WindowsAPI.txt
' efm5 30 November 2016
[change log details removed]
'references these Windows API functions:
'FindWindow (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
'GetCursorPos (lpPoint As POINT) As Long
'GetForegroundWindow () As Long
'GetMonitorInfo (ByVal hMonitor As Long, lpMonitorInformation As MONITORINFO) As Long
'GetSystemMetrics (ByVal n As Long) As Long
[the above list is in alphabetical order - I removed a whole bunch as this is just an example]
 
'mouse_event (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal dwData As Long, ByVal dwExtraInfo As Long)
 
' defines these custom functions:
'ActivateWindow (ByVal windowClass As String, ByVal windowTitle As String, ByVal timeout As Long) As Boolean (ByVal windowClass As String, ByVal windowTitle As String, ByVal timeout As Long) As Boolean
   'ActivateWindow is currently unused and commented out
'SecondaryMonitorRectangle (lpPrimaryMonitorRectangle As RECTANGLE) As RECTANGLE
'ActiveWindowTitle() As String
'WaitForDialog()
'WaitForWindow (WindowTitle As String, WaitTime As Integer) As Integer
 
' constants & Types
[many removed as this is just an example]
Type RECTANGLE
   Left As Long
   Top As Long
   Right As Long
   Bottom As Long
End Type
 
type WINDOWPLACEMENT
  length As Long
  flags  As Long
  showCmd  As Long
  ptMinPosition As POINT
  ptMaxPosition As POINT
  rcNormalPosition As RECTANGLE
End Type
 
' WINDOWPLACEMENT pound defines for showCmd:
Enum WindowPlacements
SW_HIDE = 0
SW_SHOWNORMAL = 1
SW_SHOWMINIMIZED = 2
SW_MAXIMIZE = 3
'SW_SHOWMAXIMIZED = 3' I wonder if this is a mistake in the documentation
SW_SHOWNOACTIVATE = 4
SW_SHOW = 5
SW_MINIMIZE = 6
SW_SHOWMINNOACTIVE = 7
SW_SHOWNA = 8
SW_RESTORE = 9
End Enum
Dim WindowPlacement As WindowPlacements
 
' Constants for mouse_event
Const MOUSEEVENTF_LEFTDOWN = &H2
Const MOUSEEVENTF_LEFTUP = &H4
Const MOUSEEVENTF_MIDDLEDOWN = &H20
Const MOUSEEVENTF_MIDDLEUP = &H40
Const MOUSEEVENTF_RIGHTDOWN = &H8
Const MOUSEEVENTF_RIGHTUP = &H10
 
' declare virtual key constant for the left Windows key, control key, shift key, alt key & space key
Const VK_LWIN = &h5B
Const VK_CTRL = &h11
Const VK_SHIFT = &h10
Const VK_ALT = &h12
Const VK_SPACE = &h20
 
' declare Win32 API functions
Declare Function keybd_event Lib "user32.dll" (ByVal vKey As Long, bScan As Long, ByVal Flag As Long, ByVal exInfo As Long) As Long
 
Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint As POINT) As Long
 
Declare Function GetTickCount Lib "kernel32" () As Long
[many of the "Declare Function..."s removed]
 
' Custom functionsdo not need to be "Declared")
[most removed - just an example]
 
Function SecondaryMonitorRectangle (lpPrimaryMonitorRectangle As RECTANGLE) As RECTANGLE
   Dim secondaryRectangle As RECTANGLE
   Dim monitorInformation As MONITORINFO
   Dim monitorHandle As Long
   ' given a grid like the Mouse Grid:
   ' 1 2 3
   ' 4 5 6
   ' 7 8 9
   ' and that the primary monitor is 5 and the secondary monitor is 4
   secondaryRectangle.Left = lpPrimaryMonitorRectangle.Left - 1
   secondaryRectangle.Top = lpPrimaryMonitorRectangle.Top
   secondaryRectangle.Right = lpPrimaryMonitorRectangle.Left - 1
   secondaryRectangle.Bottom = lpPrimaryMonitorRectangle.Top
   ' if the secondary monitor were 6
   ' secondaryRectangle.Left = lpPrimaryMonitorRectangle.Right + 1
   ' etc.
   monitorHandle = MonitorFromRect secondaryRectangle, MONITOR_DEFAULTTONEAREST
   GetMonitorInfo monitorHandle, monitorInformation
   SecondaryMonitorRectangle = monitorInformation.rcWork
End Function

Here's what it looks like and use:
 
   
     
      '   the ultimate goal is to paste that set of values to the clipboard in the form:
'  ###, ###
'  with no leading zeros
'#Uses "C:\Program Files (x86)\KnowBrainer\KnowBrainer Professional 2017\WindowsAPI.txt"
 
Sub Main
   Dim z As POINT
   GetCursorPos z
   preface = "The captured screen-relative mouse position was: X = "
   windowX = Str (z.x)
   windowY = Str (z.y)
   middle = " Y = "
   message = preface+windowX+middle+windowY
   MsgBox message, 0, "Mouse Screen Position"
   clip = "SetMousePosition 0, " + windowX + ", " + windowY
   clip = Replace (clip, "  ", " ")
   Clipboard clip
End Sub
notice that the Type "Point" and the Windows API function "GetCursorPos" get picked up from the WindowsAPI.txt file.

-------------------------
-Edgar
DPI 15.3, 64-bit Windows 10 Pro, OpenOffice & Word 365, Norton Security, Shure X2U XLR to USB mic adapter with Audio Technica DB135 vocal mic, Asus X299-Deluxe Prime, Intel Core i9-7940X (14 core, 4.3 GHz overclocked to 4.9 GHz), G.SKILL TridentZ Series 64GB (4 x 16GB) DDR4 3333 (PC4 26600) F4-3333C16Q-64GTZ, NVIDIA GIGABYTE GeForce GTX 1060 GV-N1060G1 GAMING-6GD REV 2.0 6GB graphics card

From



-------------------------

DPG15.6 (also DPI 15.3) + KB, Sennheiser MB Pro 1 UC ML, BTD 800 dongle, Windows 10 Pro, MS Surface Book 3, Intel Core i7-1065G7 CPU @ 1.3/1.5GHz (4 cores, 8 logical, GPU=NVIDIA Quadro RTX 3000 with Max-Q Design.



 05/11/2020 05:07 PM
User is offline View Users Profile Print this message

Author Icon
Ag
Top-Tier Member

Posts: 495
Joined: 07/08/2019

Thank you, Thank You, THANK YOU Edgar!!!

-------------------------

DPG15.6 (also DPI 15.3) + KB, Sennheiser MB Pro 1 UC ML, BTD 800 dongle, Windows 10 Pro, MS Surface Book 3, Intel Core i7-1065G7 CPU @ 1.3/1.5GHz (4 cores, 8 logical, GPU=NVIDIA Quadro RTX 3000 with Max-Q Design.

 05/11/2020 05:22 PM
User is offline View Users Profile Print this message

Author Icon
Ag
Top-Tier Member

Posts: 495
Joined: 07/08/2019

'#Uses is described in the KnowBrainer help (from KB Command Editior > ? > WinWrap Basic Language > WWB.NET language

> '#Uses Comment

Bad terminology: this is certainly not a comment, i.e. not ignorable. Although it uses comment syntax, it is what in other languages would be called a #pragma.


I'm guessing that this is standard Basic / .NET terminology. I was not noticing it because of my UNIX anti-Basic bias. (Yeah, yeah, it's like "Use" in Perl.)



'#Uses "C:\Program Files (x86)\KnowBrainer\KnowBrainer Professional 2017\WindowsAPI.txt"



Q: is this textual, or is the '#Use'd module compiled or otherwise optimized?



The help files calling it a macro/module using public and friend symbols from the module/project suggests that it is optimized in some way, e.g. that functions and symbols are defined once and only once. However, your (Edgar's) example of a .txt file suggests textual inclusion, which might result in including the same file more than once defining multiple instances of the same functions.



-------------------------

DPG15.6 (also DPI 15.3) + KB, Sennheiser MB Pro 1 UC ML, BTD 800 dongle, Windows 10 Pro, MS Surface Book 3, Intel Core i7-1065G7 CPU @ 1.3/1.5GHz (4 cores, 8 logical, GPU=NVIDIA Quadro RTX 3000 with Max-Q Design.



 05/11/2020 05:48 PM
User is offline View Users Profile Print this message

Author Icon
PG LTU
Top-Tier Member

Posts: 2116
Joined: 03/21/2007

Maybe it's KnowBrainer, but you seem to be missing the actual comment (' = apostrophe) part of the uses comment?

The syntax (and why it is called "Uses Comment") is:
'#Uses "path to\pgGlobal.bas.txt" ' note the leading apostrophe

The help (why don't people refer to Nuance's help more?) makes it pretty clear:
https://www.nuance.com/products/help/dragon/dragon-for-pc/scriptref/Content/vbs/uses_comment.htm

I have fully described this as far back as 2007 here: http://www.knowbrainer.com/forums/forum/messageview.cfm?catid=4&threadid=1900&discTab=true&messid=7493&parentid=7490&FTVAR_FORUMVIEWTMP=Single.
And I didn't invent it, it was taught to me by forum members - yes, I admit, the help, especially in the older versions, was not exactly user friendly. Most of what I know came from others at some point.

 

As to textual or compiled? I dunno.  It's as if you pasted the text from the file into your command.  So, no, you cannot re-use a function name as then there would be two and they would conflict.

Hth,



-------------------------




PG





Remember folks, my comments and this forum are for entertainment value only, please, no wagering or other reliance on the contents herein.  I permit no commercial use of my ideas (whether expressions or embodiments) without my written consent.



 05/11/2020 07:58 PM
User is offline View Users Profile Print this message

Author Icon
Ag
Top-Tier Member

Posts: 495
Joined: 07/08/2019

Originally posted by: PG LTU

As to textual or compiled? I dunno.  (1) It's as if you pasted the text from the file into your command.  So, no, (2) you cannot re-use a function name as then there would be two and they would conflict.

(1) suggests textual inclusion ('#USE-ion ?)

but (2) suggests that inclusion from different commands lives in the same namespace.

It is possible that you were talking about reusing function names within the same command. As you say, I would expect that to be an error, since probably a single command is a single namespace, modulo the namespace management rules of the language (with comments).

--

The reason I ask is:

Q: Is it reasonable to define one or more libraries, each of which contain many, many functions, where any given command probably only uses one or a few of the functions?

Or does that result in each command instance (in XML?) being bloated, and hence bad for performance?

Textual inclusion implies the latter. Shared code optimizations imply the former.

--

Anyway, I expect this will be evident when I try it out.

 

 

Maybe it's KnowBrainer, but you seem to be missing the actual comment (' = apostrophe) part of the uses comment? The syntax (and why it is called "Uses Comment") is: '#Uses "path to\pgGlobal.bas.txt" ' note the leading apostrophe[\q]

Thanks for catching my error. I have edited my earlier posts to say '#Use.

My bad. '#Use is not a pragma - I see that .NET C# has #pragma, imitating cpp, the C Pre-Processor. '#Use is less nevertheless not a comment; more like a pre-processor directive, again imitating cpp. Albeit a directive written using comment syntax. Comments can be ignored. This directive cannot be ignored.

(I'm just whining over terminology.)

 

 

Thanks for the reference.

 

 

(why don't people refer to Nuance's help more?)

Probably because googling standard terminology like "code reuse in Dragon commands" or "function libraries for Dragon commands" gives many, many, search hits of relative garbage?

Again, thanks for the reference.

 

 

And I didn't invent it, it was taught to me by forum members - yes, I admit, the help, especially in the older versions, was not exactly user friendly. Most of what I know came from others at some point.

I would hope that you did not invent it - AFAICT it has to be part of the languag3 (unless you are your own preprocessor (as I am considering doing, if this is a textual inclusion mechanism)).

As to finding stuff in the forums: forums are for discussion. They are not so good for reference. That's what wikis are for. 

Too bad we do not have a wiki.

 

 

 

 

 

 



-------------------------

DPG15.6 (also DPI 15.3) + KB, Sennheiser MB Pro 1 UC ML, BTD 800 dongle, Windows 10 Pro, MS Surface Book 3, Intel Core i7-1065G7 CPU @ 1.3/1.5GHz (4 cores, 8 logical, GPU=NVIDIA Quadro RTX 3000 with Max-Q Design.

 05/11/2020 10:12 PM
User is offline View Users Profile Print this message

Author Icon
PG LTU
Top-Tier Member

Posts: 2116
Joined: 03/21/2007

These are scripts, so are run by an interpreter. No matter the size of the included module, the interpreter will only run (or even look at) the functions that are actually called by the script (and only when they are called). Nothing gets "compiled" and certainly not the unused portions. I suppose a really large module might take some extra milliseconds to load, and for the interpreter to find things, but I wouldn't imagine that is significant in overall timing.

While a given function can be called multiple times, my point was that you can't define a function in your script with the same name as an included function (which oop allows overriding this way). If the function name exists twice, you'll get a runtime error.

-------------------------




PG





Remember folks, my comments and this forum are for entertainment value only, please, no wagering or other reliance on the contents herein.  I permit no commercial use of my ideas (whether expressions or embodiments) without my written consent.

Statistics
31892 users are registered to the KnowBrainer Speech Recognition forum.
There are currently 0 users logged in.
The most users ever online was 12124 on 09/09/2020 at 04:59 AM.
There are currently 582 guests browsing this forum, which makes a total of 582 users using this forum.

FuseTalk Standard Edition v4.0 - © 1999-2021 FuseTalk™ Inc. All rights reserved.