>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)
>>>
>>>
>>> *---------------------------------------------------------------------------------------
>>> *// 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)
>>>
>>> *!* 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
>>>
>>> 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?