Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
IntellisenseX and Thor question
Message
From
14/06/2016 03:09:01
 
 
To
13/06/2016 10:17:40
Walter Meester
HoogkarspelNetherlands
General information
Forum:
Visual FoxPro
Category:
VFPX/Sedna
Miscellaneous
Thread ID:
01637273
Message ID:
01637330
Views:
57
95% of perf should be a optimization record hard to crack ;-))
Still, usually you can find a few other places, probably allowing you to cut a couple of ms, making editing a more fluent thing.

>>2 secs is long enough either to sprinkle log calls in or bite the bullet and call a dozen times with coverage and analyze...
>
>I just did, I stumbled across a design mistake. It is heavily relying on EXECSCRIPT() in tight loops.
>I just made some modifications to compile the script once and use many times.
>
>The delay is now getting acceptible: Arround 0.3 seconds
>
>I'll contact Jim Nelson about this
>
>
>** UPDATE** Eliminating all EXECSCRIPTS() now made it near instant. From 2 seconds from the dot to the list, it now only takes 0.1
>
>
>
>Walter,
>
>
>
>
>>>I've installed Thor and played a little with it.
>>>I can't get past the slowness in larger PRG files. Taking up to 2 seconds for the list to popup. Any way arround that ?
>>>
>>>Walter,
>>>
>>>
>>>
>>>
>>>
>>>>There are some very powerful ways to get Thor IntellisenseX to work on your objects/classes when coding.
>>>>
>>>>First, let me tell you this... The best place to get support for Thor questions is to join the Thor google group and post your question there.
>>>>
>>>>https://groups.google.com/forum/#!forum/foxprothor
>>>>
>>>>
>>>>Now, some direct guidance:
>>>>
>>>>There are some plug-ing prgs that get called to help resolve your code reference into the underlying object that you are targeting.
>>>>
>>>>For instance;
>>>>
>>>>thor_proc_gettablefromobject.prg and peme_opentable.prg Watch this video to learn more about these: https://www.youtube.com/watch?v=UGyqlInAfvc&hd=1&rel=0
>>>>
>>>>
>>>>There is also the Alias Dictionary table which can map object names to class names or table schemas. Learn more about it here: https://groups.google.com/forum/#!topic/foxprothor/3D17opqq8JQ
>>>>
>>>>
>>>>
>>>>Each of these plugins and table are used by Thor when it is trying to resolve your code/object reference. In these plugins/table, *you* can write code that helps IntellisenxeX work. In my use case, I use GetTableFromObject parse the object name I am coding with and I return the correct object to Thor and then Thor can perform Intellisense analysis on it.
>>>>
>>>>
>>>>For example, here is my code from my customized thor_proc_gettablefromobject.prg file:
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>	lxResult = GetSQLStructure(lcEntityName)
>>>>	If Vartype(lxResult) = 'O'
>>>>		Return Execscript(_Screen.cThorDispatcher, 'Result=', lxResult)
>>>>	Endif
>>>>
>>>>#Define PROPERTYNAME 'cAlias'
>>>>#Define ccTab Chr[9]
>>>>
>>>>loHost = toParameters.oTopOfForm
>>>>
>>>>
>>>>lnWordCount = GetWordCount(lcEntityName, '.')
>>>>lcLastWord = GetWordNum(lcEntityName, lnWordCount, '.')
>>>>
>>>>If lnWordCount > 1
>>>>	lcNextToLastWord = GetWordNum(lcEntityName, lnWordCount -1 , '.')
>>>>Else
>>>>	lcNextToLastWord = ''
>>>>EndIf
>>>>
>>>>*// Note: The cases below may return and Table Alias, or and object instance of a class
>>>>Do Case
>>>>	* Case Vartype(loForm) # 'O'
>>>>	* 	lcAlias = .F.
>>>>
>>>>	*	Case Lower(lcEntityName) == 'Thisform.oMainObject.oData'
>>>>	*		lcAlias = GetTableAlias(loForm, PROPERTYNAME, .T.)
>>>>
>>>>	Case lcEntityName == 'this.odata' and Vartype(loHost) = 'O' and PemStatus(loHost, 'cFilename', 5) and !Empty(loHost.cFilename)
>>>>			lcAlias = loHost.cFilename
>>>>
>>>>	Case lcEntityName == 'this.odata' and Vartype(loHost) = 'O'
>>>>			lcAlias = GetTableFromBOKey(loHost.Class)
>>>>			
>>>>			
>>>>	*-- Thisform.oMainObject.oData (return the table name)
>>>>	Case ('mainobject.odata' $ lcEntityName or toParameters.lForceIt) and ;
>>>>				Vartype(loHost) = 'O' and ;
>>>>				PemStatus(loHost, lcFormBusinessObjectRef, 5)
>>>>			lcBusinessObjectClass = Alltrim(Lower(Eval('loHost.' + lcFormBusinessObjectRef)))
>>>>			lcAlias = GetTableFromBOKey(lcBusinessObjectClass)
>>>>
>>>>	*---------------------------------------------------------------------------------------
>>>>	*// Blah.Blah.oJob.oCustomer.oData -> Will return an instance of the Customer oData object from the DB
>>>>	Case Lower(lcLastWord) = 'odata' and Left(Lower(lcNextToLastWord), 1) = 'o'
>>>>		lcBusObjKey = Substr(lcNextToLastWord, 2)
>>>>		lcAlias = GetTableFromBOKey(lcBusObjKey)
>>>>
>>>>	*-- Thisform.oMainObject, but loHost not passed yet, return out, it will be called again with loHost
>>>>	Case ('mainobject' $ lcEntityName or toParameters.lForceIt) and ;
>>>>				Vartype(loHost) != 'O'
>>>>			lcAlias = .null.
>>>>
>>>>
>>>>	*-- Thisform.oMainObject (Return an instance of the Business Object in cMainObjectClass --
>>>>	Case ('mainobject' $ lcEntityName or toParameters.lForceIt) and ;
>>>>				Vartype(loHost) = 'O' and ;
>>>>				PemStatus(loHost, lcFormBusinessObjectRef, 5)
>>>>			lcBusinessObjectClass = Alltrim(Lower(Eval('loHost.' + lcFormBusinessObjectRef)))
>>>>			lcAlias = CreateObjectFromBOKey(lcBusinessObjectClass) && Note: Returns asn Object, not an alias string.
>>>>			
>>>>			
>>>>	*---------------------------------------------------------------------------------------
>>>>	*// Blah.Blah.Blah.oVendor -> Will return an instance of the Vendor object
>>>>	Case 'o' = Left(Lower(lcLastWord), 1) and Lower(lcLastWord) != 'odata'
>>>>		lcBusObjKey = Substr(lcLastWord, 2)
>>>>		lcAlias = CreateObjectFromBOKey(lcBusObjKey)
>>>>
>>>>
>>>>	*---------------------------------------------------------------------------------------
>>>>	*// loJob -> Will return an instance of the Job object
>>>>	Case 'lo' = Left(Lower(lcEntityName),2) and !('.' $ lcEntityName)
>>>>		lcObjectRef = GetWordNum(lcEntityName, 1, '.')
>>>>		If Lower(Left(lcObjectRef, 2)) = 'lo'
>>>>			lcBusObjKey = Substr(lcObjectRef, 3)
>>>>			lcAlias = CreateObjectFromBOKey(lcBusObjKey)
>>>>		Endif
>>>>
>>>>	*// loJob.oData or This.oData -> Returns the table name from the BO Dictionary
>>>>	Case '.odata' $ Lower(lcEntityName)
>>>>		lcObjectRef = GetWordNum(lcEntityName, 1, '.')
>>>>		If Lower(Left(lcObjectRef, 2)) = 'lo'
>>>>			lcBusObjKey = Substr(lcObjectRef, 3)
>>>>			lcAlias = GetTableFromBOKey(lcBusObjKey)
>>>>		EndIf
>>>>		
>>>>		*-- If not found using the seed as a BO key, then let's try it as the table name
>>>>		If Empty(lcAlias)
>>>>			lcAlias = lcBusObjKey
>>>>		EndIf
>>>>		
>>>>	Case Left(lcLastWord, 1) == 'o'
>>>>		lcBOKey = Substr(lcLastWord, 2)
>>>>		lcAlias = CreateObjectFromBOKey(lcBOKey) && Note: Returns asn Object, not an alias string.
>>>>
>>>>	*!* Case lcBaseClass == 'custom'
>>>>	*!* 	If (lcClassMatch $ lcEntityName or toInfo.lForceIt)
>>>>	*!* 		lcBusinessObjectClass = Alltrim(Lower(loHost.name))
>>>>	*!* 		lcAlias = GetTableFromBOKey(lcBusinessObjectClass)
>>>>	*!* 	EndIf
>>>>
>>>>	Case llForceit
>>>>		lcAlias = GetTableAlias(loForm, PROPERTYNAME, .T.)
>>>>		
>>>>	Otherwise
>>>>		lcAlias = .F.
>>>>
>>>>Endcase
>>>>
>>>>
>>>>Return Execscript(_Screen.cThorDispatcher, 'Result=', lcAlias)
>>>>
>>>>
>>>>
>>>>*=======================================================================================
>>>>
>>>>
>>>>Procedure GetTableAlias(loForm, tcPropertyName, tlCurrentAlias)
>>>>	* If property <tcPropertyName> exists in object <loForm>, 
>>>>	* calls plug-in <PEME_OpenTable> to select or open the table
>>>>	* with that alias.
>>>>
>>>>	* If this does not result in the desired table, and if
>>>>	* <tlCurrentAlias> is .T., tries to use the current table
>>>>
>>>>	Local lcAlias
>>>>
>>>>	If Pemstatus(loForm, tcPropertyName, 5) And Vartype(loForm.&tcPropertyName) = 'C'
>>>>		lcAlias = loForm.&tcPropertyName
>>>>		If Empty(lcAlias) And Lower(loForm.Name) = 'bo_'
>>>>			lcAlias = OpenMyTable(Substr(loForm.Name, 4))
>>>>		Endif
>>>>		lcAlias = OpenMyTable(lcAlias)
>>>>	Else
>>>>		lcAlias = .F.
>>>>	Endif
>>>>
>>>>	If Empty(lcAlias) And tlCurrentAlias And Not Empty(Alias())
>>>>		lcAlias = Alias()
>>>>	Endif
>>>>
>>>>	Return lcAlias
>>>>
>>>>Endproc
>>>>
>>>>
>>>>Procedure OpenMyTable(tcAlias)
>>>>	If Empty(tcAlias) Or '.' $ tcAlias
>>>>		Return ''
>>>>	Else
>>>>		Return Execscript(_Screen.cThorDispatcher, 'PEME_OpenTable', tcAlias)
>>>>	Endif
>>>>Endproc
>>>>
>>>>
>>>>Procedure GetSQLStructure(lcEntityName)
>>>>	* Sample Procedure that gets the structure for an SQL table
>>>>
>>>>	* The result is a collection, each element containing the field name,
>>>>	* then a tab, then the data type and width
>>>>
>>>>	* This procedure uses a dictionary in a local table. It could just
>>>>	* as well use SQLColumns to read the structure directly.
>>>>
>>>>	#Define DictionaryTableName 'C:\VISUAL FOXPRO\DATA\KONG\DATADICTIONARY.DBF'
>>>>	#Define Table_FieldName     Xtabname
>>>>	#Define Field_FieldName		field_name
>>>>	#Define Type_FieldName		Field_Type
>>>>	#Define Length_FieldName	Field_Len
>>>>	#Define Decimals_FieldName	Field_Dec
>>>>
>>>>	Local lxResult As 'Collection'
>>>>	Local laFields[1], laList[1], lcTableName, lnSelect
>>>>
>>>>	lxResult = .F.
>>>>	If '.' $ lcEntityName
>>>>		Return lxResult
>>>>	EndIf 
>>>>
>>>>	* Assumes beginning of table name is 'SQL_'
>>>>	If Upper(lcEntityName) = 'SQL_'
>>>>		lcTableName = Substr(lcEntityName, 5)
>>>>	Else
>>>>		lcTableName = lcEntityName
>>>>	Endif
>>>>
>>>>	If File(DictionaryTableName)
>>>>		lnSelect = Select()
>>>>		Use(DictionaryTableName) Alias DataDictSource In 0
>>>>
>>>>		Select  Lower(Field_FieldName)    As  field_name,			;
>>>>				Type_FieldName            As  Field_Type,			;
>>>>				Length_FieldName          As  Field_Len,			;
>>>>				Decimals_FieldName        As  Field_Dec				;
>>>>			From DataDictSource										;
>>>>			Where Lower(Table_FieldName)  = Lower(lcTableName)		;
>>>>			Into Array laFields
>>>>
>>>>		If _Tally > 0
>>>>			Dimension laList[1]
>>>>			Execscript(_Screen.cThorDispatcher, 'THOR_PROC_GetFieldNames', @laFields, @laList, 3)
>>>>			lxResult = Createobject('Empty')
>>>>			AddProperty(lxResult, 'aList[1]')
>>>>			Acopy(laList, lxResult.aList)
>>>>		Endif
>>>>
>>>>		Use In DataDictSource
>>>>		Select(lnSelect)
>>>>	Endif && File(DictionaryTableName)
>>>>
>>>>	Return lxResult
>>>>Endproc
>>>>   
>>>>
>>>>
>>>>
>>>>
>>>>>I know I'm late in the game of looking into Thor, but looking into the youtube videos I see that it can be very useful for me.
>>>>>
>>>>>However, two of my most important problems don't seem to get solved. Please tell me I'm wrong on this.
>>>>>
>>>>>You cannot easily use intellisenseX on public objects. For example I've got several public objects
>>>>>Applic: The global Applic object which can be referred to in any piece of code.
>>>>>oPS: Personal Settings
>>>>>oDatacache: Responsible for caching remote data
>>>>>oDF, Datafunctions, Applic specifig function to create lookups
>>>>>etc...
>>>>>
>>>>>They not specifically declared other than in the places where they are created, but I really like to use intellisense on them anywhere in my project.
>>>>>Is there a way to do this?
>>>>>
>>>>>
>>>>>The other question is whether it is possible to easily save all thor tools and settings to be applied to another development machine. Personally I've got 2 desktops and 2 laptops which I use to code and I really hate to install and configure things on all 4 machines. Is there a way of doing that?

UGyqlInAfvc
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform