Script Server Skeleton with Timeout and Debug Mode

Hello.

INTRODUCTION
This is a Script Library Server that unloads ScriptLibraries after a given amount of time in seconds,
and which dies within the same number of seconds after the last library was unloaded from it.

This library server (ScriptLibraryServer) is intended to work in conjunction with both the LibraryLoader and LibrarServer, and therefore all paths to libraries should be hard coded. (At least at this stage).

It does not currently support AppleMods or ScriptFactory’s LibraryLoader mechanisms, but will eventually do so soon, either directly or by providing some semi-compatible mechanisms to make the loading work.

It will be fully supported by both the LibraryLister and the LibraryLoader.

In this post you will find The ScriptLibraryServer skeleton which includes two small libraries for demonstration purposes. The LoaderMaker script to ease installment (coming soon).

About the example libraries:
A little (but very useful) simple library to play with, to see that it actually work. And a more complex library that illustrates usage of intrinsic properties, also just to play with. (It does nothing more useful than showing that get(), set() and is() works through the ScriptLibraryLoader).

It should be possible to use this ScriptLibraryServer in a network context where the Script Libraries are stored in some central locations, -if the right precautions are taken regarding Network Access and login status.

OVERVIEW
You should really know how to write a library which is intended to be used from a Script Server.
Luckily for us Bill Cheeseman has written an excellent article on the subject which can be found here.
To use a script library from a script library server brings some considerations into account, which are needed to be taken height for. I recommend that you play a little with the examples in that article, or make up some of your own while you study it, if your aren’t totally sure of how calling code through a Script Library Server differs from a loading and calling through a regular Script Library.

PRELIMINARY
The ScriptLibraryServer presented is of course only a skeleton, it should contains tons of hard coded code, if you use it properly. :slight_smile: I have provided a script that generates the necessary hardcoded stuff “LoaderMaker”,that makes it easy for you to just paste generated template code right into the Script Library Server’s main script after having answered a few easy questions. You will full understand these questions by reading the section “About Script Libraries” if not, please refer to Bill Cheesemans article referenced above. The template code generated consists of a handler, a script object and a property. -After having pasted in the code you should be good to go.

EXAMPLE USAGE OF THE SCRIPT LIBRARY SERVER RUNTIME

General usage
Say I have entered code for having the Script Server provide a textLib for me, which resides at a given path. In order to access the functionality of that script library I would use code like this:


--> simple example:
tell application "ScriptLirarServer"
	set lf to my textLib()'s LF 
end tell

Observe: I access the library through a Handler in my client code.

→ more complex example:


tell application "ScriptLibraryServer"
	
	tell its objLib()
		-- Notice: we address the specific script object in the Script server by "telling it"
		-- in order for the code to work
		if its isFavcolor() is true then
			set myColor to its getFavColor()
			tell me
				activate
				display dialog "FavColor " & myColor
			end tell
			
		else
			tell me
				activate
				display dialog "No color defined yet"
			end tell
		end if
		
		its setFavColor("Blue")
		set its txtColor to "Blue"
		--	set objLib()'s txtColor to "ORANGE"
		log its txtColor
		
		if its isFavcolor() then
			set myColor to its getFavColor()
			display dialog "FavColor " & myColor
		else
			tell me
				activate
				display dialog "No color defined yet"
			end tell
		end if
		log its txtColor
	end tell
end tell


We have just tested for, set a property, and gotten a result when property was set.

IMPLEMENTATION DETAILS YOU REALLY NEED TO BE AWARE OF
Observe that you in the ScriptLibrarServer will use a handler to access the Script Library in speak.
After calling the handler, you should be able to access what is within that Script Library as you would with any other Script Library created to serve as a script object in a library server.

OTHER IMPLEMENATION DETAILS

You should easily be able to figure out the naming conventions by looking at the supplied Demo/template for the script library server, its internal idle handler, together with the LoaderMaker script. The code is really simple. :slight_smile:

USAGE FOR DEVELOPMENT
The ServerSkeleton has a switch for turning a debug_load mode on. When that switch is encountered for a script object that holds the date of a moduleWe then support debugging of Script Libraries by checking the librarys timestamp on disk, and reloading it before using it. -This may lead to errant situations if the libraries are complex, and you have other applet relying on the script. I recommend that you make a second Script Library Server for development and testing of Script Libraries were you use this feature, with other Script Libraries than the production versions of your code. You turn on debug_load mode for a specific library by setting the debug_load mode property to true.

USAGE FOR DEPLOYMENT
Never use the name “ScriptLibraryServer”: that’s a no no. Use some unique name, also use a version number in its name, (This is something which you agree to in the agreements section of this code in order to use said code.)

Guidance
It is advisible to use unique filenames for the versions of the libraries you are using in order for your users/customers to easily detect what pieces are amiss, than trying to figure out why that applet/script doesn’t work as intended, which may lead to hours and hours of unecessary debugging, -that is if your usere are daring. Otherwise this may result in that your users defaults to using your software, or that you will have to spend time with your users, trying to figure out why it doesn’t work.

Your ScriptServer should also come with a version number, so that you won’t break anything that relied on an older version. You should however not “flatten” the contents of the ScriptLibraryServer but supply the necessary modules/units, and provided some kind of instructions for, or an installer to install them.
Best Practice:
Installation of the necessary modules within the Contents/Resources/Scripts folder may be seen as a best practice and referencing them from there, as then you will have the best control over your product when it is shipped to a users machine.

You can also have your Script Library Server ship the necessary osax’s to make your code work, they should be installed in the “Contents/Resources/Scripting Additions” folder. (Remark the space in Scripting Additions). Be sure to read the license agreement of the osax’s you ship with it carefully!

SOME HELPFUL TOOLS FOR DEPLOYMENT
Luther Fuller has made an excellent tool for creating application bundles which may be useful for this purpose. It can be found here.

Should you wish to make your Application faceless during a later stage, then DockDodger is a great little app that can be found here
(Maybe it it is still better to use ScriptBundler to build a final solution when your are totally sure that it works.

ABOUT SCRIPT LIBRARIES IN GENERAL

We can basically split script librarys into two groups; those that just consists of a group of independent handlers I will refer to this type as “simple libraries” and those that consists of internal script objects or handlers which are used internally within the script library these I denote as complex.

For the type two script library there is special considerations:
The scripts that are loaded in such library servers should contain a script object with all its properties within that script object and nothing at the top level. Those issues is thoroughly treated in Ben Walidies article which is referenced to above.

Aside: I have no ida as we speak wether modules loaded with either the AppleMods loader system nor Tetsuro Kurita’s module loader will work directly from within the ScriptLibraryServer due to the extra condisederations which is needed to be taken in order to make a Script Library Server work. -I haven’t had the time to test it yet.

ABOUT LoaderMaker
This script creates the template for loading your unit of code.

You will have to answer three or four different easy questions! in order for the LoaderMaker script create a template for you to paste into your Script Library Server Script without any further rearrangement!

  1. It will ask for the Script Library you want to make a template for. It will then use the given filename for creating a hardcoded reference to that file at this stage. If it is a complex library, then it will also read out the script objects name in question in order to create a correct template for it. -Or stall if said script object isn’t there.

¢ It will first of all ask if the library only contains handlers, or if it is more complex than so.
It isn’t regarded as a complex one if not all of its contents resides within a script object within that script, so the LoaderMaker will stall if the script library isn’t so.

¢ It will then ask you for the library file through a choose file dialog.

¢ If the library is a complex one it will ask you for the name of the script object to extract from the library file.

¢ In every case it will then ask for the object name to use in the ScriptLibraryServer

It will then ask if the loaded Script Library is in a development state, set the correct value for the load_debug property within the generated script object (a boolean ).

Enjoy! :smiley:

ACCOMPANYING CODE:
USAGE EXAMPLE (snippet above)
Template/Demo of ScriptLibraryServer
LoaderMaker Script Not implemented -Yet!
Example Simple Library
Example Complex Library


-- The Idea and implementation and any faults is totally mine. © McUsr 2010 and put in the Public Domain.
-- The usually guarrantees about nothing what so ever applies, use it at your own risk.
-- Read the documentation.
-- You are not allowed to post this code elsewhere, but may of course refer to the post at macscripter.net.
” macscripter.net/viewtopic.php?pid=131684#p131684
(*
TERMS OF USE. 
This applies only to posting code, as long as you don't post it, you are welcome to do
whatever you want to do with it without any further permission. 
Except for the following: Selling the code as is, or removing copyright statmentents and the embedded link in the code (without the http:// part) from the code. 

SPECIAL TERMS REGARDING SCRIPT LIBRARY SERVER.
Under no circumstance should you ship a Script Library Server with the name Script Library Server You must agree to finding a unique name for any 
script library servers you ship with script in order to use the code. Preferably with a version number. And for the case that you hadn't thought of it:
It would be very wise to ship your libraries from the Contents/Resources/Scripts folder in the bundle of the ScriptLibraryServer of yours.
You must also state what you eventually have done with the original source. This obviously doesn't matter if you distribure AppleScript as read only. I do not require you to embed any properties helding copyright notice for the code.

Credit for having contributed to your product would in all cases be nice!

If you use this code as part of script of yours you are of course welcome to post that code with my code in it here at macscripter.net. If you then wish to post your code elsewhere after having uploaded it to MacScripter.net please email me and ask for permission.

The ideal situation is however that you then refer to your code by a link to MacScripter.net
The sole reason for this, is that it is so much better for all of us to have a centralized codebase which are updated, than having to roam the net to find any usable snippets. Which some of us probabaly originated in the first hand.

I'm picky about this. If I find you to have published parts of my code on any other site without previous permission, I'll do what I can to have the site remove the code, ban you, and sue you under the jurisdiction of AGDER LAGMANNSRETT of Norway. Those are the terms you silently agree too by using this code. 

The above paragraphs are also valid if you violate any of my terms.

If you use this or have advantage of this code in a professional setting, where professional setting means that you use this code to earn money by keeping yourself more productive. Or if you as an employee share the resulting script with other coworkers, enhancing the productivity of your company, then a modest donation to MacScripter.net would be appreciated.
*)
-- © McUsr 2010 and put in Public Domain see: macscripter.net/edit.php?id=131684#p131684 for reference and terms of use.
script libInit
	on init()
		local fileModDate
		
		if contents of my _scriptLIb is missing value then
			-- we have taken the tour with the garbage collector and have to reinitialize
			if my _libtype is 1 then
				LoadType1Library(my _scriptLIb, my _hfsFileName, my _libName)
			else
				LoadType2Library(my _scriptLIb, my _hfsFileName, my _libName, my _libLoader)
			end if
		end if
		if my _reload_on_update then
			try
				tell application "Finder" to set fileModDate to (modification date of (my _hfsFileName as alias))
			on error e number n
				tell me
					activate
					display alert "ScriptLibrary Server _init : " & my _libName & " File probably missing " & e & " : " & n
				end tell
			end try
			
			set end of my unitsExpiryList to {my _thisScript, my _scriptLIb, (current date), my _hfsFileName, fileModDate, my _libName}
		else
			set end of my unitsExpiryList to {my _thisScript, my _scriptLIb, (current date)}
		end if
		set my _index to (count my unitsExpiryList)
	end init
end script

property unitsExpiryList : {}
-- every item of unitsExpiryList holds the following: { ref to the units Script object, ref to the units property (script library), last access time )

(* =====================   SERVER CODE ABOVE ====================== *)
-- Example code below, which illustrates how the contents is intended to be structured.
(* SCRIPT LIBRARY EXAMPLE # 1 ======================================================================*)

property _1_textLib : (load script alias "Macintosh HD:Users:McUsr:Library:Scripts:Modules:TextLib.scpt") -- hardcode
-- EXAMPLE : SIMPLE LIBRARY WHICH ONLY CONTAIN INDIVIDUAL HANDLERS  (TYPE 1)
script _textLib
	-- EXAMPLE : SIMPLE LIBRARY WHICH ONLY CONTAIN INDIVIDUAL HANDLERS  (TYPE 1)
	property parent : libInit
	property _index : 0
	property _reload_on_update : true
	property _hfsFileName : "Macintosh HD:Users:McUsr:Library:Scripts:Modules:TextLib.scpt"
	property _libName : "text_lib"
	property _scriptLIb : a reference to my _1_textLib
	property _thisScript : a reference to my _textLib
	property _libtype : 1
	property _libLoader : ""
end script

on textLib()
	if my _textLib's _index is 0 then
		my _textLib's init()
	else
		if my _textLib's _reload_on_update then my _textLib's checkAndUpdateLibrary(a reference to my _textLib)
		
	end if
	
	return my _1_textLib
end textLib

(* SCRIPT LIBRARY EXAMPLE # 2  ====================================================================== *)

property _1_objLib : objLib of (load script alias "Macintosh HD:Users:McUsr:Library:Scripts:Modules:favColorLib2.scpt")
-- EXAMPLE : LIBRARY WHICH NEED TO GET CONTENTS OF A LIBRARY THROUGH AN OBJECT BECAUSE OF INTERNAL REFERENCES. (TYPE 2)

script _objLib
	-- EXAMPLE : LIBRARY WHICH NEED TO GET CONTENTS OF A LIBRARY THROUGH AN OBJECT BECAUSE OF INTERNAL REFERENCES. (TYPE 2)
	property parent : libInit
	property _index : 0
	property _reload_on_update : true
	property _hfsFileName : "Macintosh HD:Users:McUsr:Library:Scripts:Modules:favColorLib2.scpt"
	property _libName : "objlib"
	property _scriptLIb : a reference to my _1_objLib
	property _thisScript : a reference to my _objLib
	property _libtype : 2 -- We must use an "object of" load script "the lib" in order to get our goodies type 2 in description
	property _libLoader : "objLib of (load script alias \"Macintosh HD:Users:McUsr:Library:Scripts:Modules:favColorLib2.scpt\")"
end script

on objLib()
	if my _objLib's _index is 0 then
		my _objLib's init()
	else
		if my _objLib's _reload_on_update is true then my _objLib's checkAndUpdateLibrary(a reference to my _objLib)
	end if
	return my _1_objLib -- which your code will tell what to do.
end objLib


(* SCRIPT LIBRARY # and so on*)

(* =====================   SERVER CODE BELOW ====================== *)
on LoadType1Library(refObj, txtAHfsFilename, txtAScriptName)
	try
		txtAHfsFilename as alias
	on error e number n
		tell me
			activate
			display alert "Script " & txtAScriptName & "'s LoadType1Library() : Cant find file: " & txtAHfsFilename & " " & e & " : " & n
		end tell
	end try
	
	try
		set contents of refObj to (load script alias txtAHfsFilename) -- ## hardcode
	on error e number n
		tell me
			activate
			display alert "LoadType1Library " & txtAScriptName & ": Cant load Library, something is wrong: " & txtAHfsFilename & " " & e & " : " & n
		end tell
	end try
end LoadType1Library

on LoadType2Library(refObj, txtAHfsFilename, txtAScriptName, txtRunScriptStatement)
	try
		txtAHfsFilename as alias
	on error e number n
		tell me
			activate
			display alert "Script " & txtAScriptName & "'s LoadType2Library() : Cant find file: " & txtAHfsFilename & " " & e & " : " & n
		end tell
	end try
	
	try
		set contents of refObj to (run script txtRunScriptStatement) -- ## hardcode
	on error e number n
		tell me
			activate
			display alert "LoadType2Library " & txtAScriptName & ": Cant get Library from object via run, something is wrong: " & txtAHfsFilename & " " & e & " : " & n
		end tell
	end try
end LoadType2Library

on checkAndUpdateLibrary(refToLib) --Type 1 checkAnd updater, trenger 2 typer.
	local libindex, libtype
	set {libindex, libtype} to {_index of contents of refToLib, _libtype of contents of refToLib}
	local fileModDate
	try
		tell application "Finder" to set fileModDate to (modification date of alias (contents of (item 4 of (item libindex of my unitsExpiryList))))
	on error e number n
		tell me
			activate
			display alert "ScriptLibrary Server checkAndUpdateType1Library : " & item 6 of (item libindex of my unitsExpiryList) & " File probably missing " & e & " : " & n
		end tell
	end try
	if fileModDate is greater than contents of item 5 of (item libindex of my unitsExpiryList) then -- update contents.
		if libtype is 1 then
			my LoadType1Library(item 2 of (item libindex of my unitsExpiryList), contents of (item 4 of (item libindex of my unitsExpiryList)), ¬
				item 6 of (item libindex of my unitsExpiryList))
			-- item2 ref to glob prop helds script object:,  item 4 -> filename., item 6 --> script library name
		else -- type 2
			LoadType2Library(item 2 of (item libindex of my unitsExpiryList), contents of (item 4 of (item libindex of my unitsExpiryList)), item 6 of (item libindex of my unitsExpiryList), _libLoader of contents of refToLib)
			-- the new thing here contra above, is that we pass a string to be executed as a string with it.
		end if
		
		set item 5 of (item libindex of my unitsExpiryList) to fileModDate
	end if
end checkAndUpdateLibrary

on idle
	-- empties buffers on two hours expiry dies when nothing more to do 
	global started
	local hadExpired
	if started is true then 
		set started to false
		return 900
	end if
	set hadExpired to false
	set libCount to (count my unitsExpiryList)
	try
		repeat with i from 1 to libCount
			if (current date) - (contents of item 3 of item i of my unitsExpiryList as date) is greater than 7200 then -- 2 hours
				set (contents of item 1 of item i of my unitsExpiryList)'s _index to 0
				--  so that the handler can see that it must reload the script object before returning result
				set contents of item 2 of item i of my unitsExpiryList to missing value
				-- effectively kills the script object in speak
				set hadExpired to true
			end if
		end repeat
		if hadExpired is true then set my unitsExpiryList to my unitsExpiryList's lists
	on error e number n
		tell me
			activate
			display alert "LibraryServers 's Idle handler : error " & e & " : " & n
		end tell
	end try
	if hadExpired is false and libCount is 0 then
		tell me to quit
	end if
	return 900 -- 15 minutes
end idle

on quit
	continue quit
end quit

on run 
	global started
	set started to true
(*	
	-- This is the calling convention which must be used.
	set theName to textLib()'s LF
	
	log theName
*)
end run

LoaderMaker Script
Past the code it generates directly into the server, no need for rearranging! :slight_smile:


-- © McUsr 2010 and put in Public Domain see: macscripter.net/edit.php?id=131684#p131684 for reference and terms of use.
set choice to button returned of (display dialog "Will you make a simple or complex load statment for a ScriptLibraryServer (simple is with indepedent handlers, complex means with internal dependencies or properties)?" with title "LoaderMaker" buttons {"Cancel", "Simple", "Complex"} cancel button 1 default button 2)

set theLibaryFile to (choose file of type {"com.apple.applescript.script"} with prompt "Choose the Library you want to make a load statement for") as text


if choice is "Complex" then
	repeat
		set libName to text returned of (display dialog "Enter the name of the script object you will extract from the library  file" default answer "" with title "LoaderMaker")
		if libName is not "" then exit repeat
	end repeat
end if

repeat
	set ServerLibName to text returned of (display dialog "Enter the name the script object shall have in the Script Library Server " default answer "" with title "LoaderMaker")
	if ServerLibName is not "" then exit repeat
end repeat

set reloadOnUpdate to button returned of (display dialog "Enter the initial status of \"_reload_on_update\"" with title "LoaderMaker" buttons {"Cancel", "true", "false"} cancel button 1 default button 2)

if choice is "Complex" then
	mkType2Template(ServerLibName, libName, theLibaryFile, reloadOnUpdate)
else
	mkType1Template(ServerLibName, theLibaryFile, reloadOnUpdate)
end if

on mkType1Template(T1, T2, T3)
	-- T1 : scrObj of server, T2: script file  T3 load_debug , T4 lib name for debug.
	local theText
	set theText to "(* SCRIPT LIBRARY T1 OF TYPE 1 ======================================================================*)

property _1_T1 : (load script alias \"T2\") -- hardcode
--  SIMPLE LIBRARY WHICH ONLY CONTAIN INDIVIDUAL HANDLERS  (TYPE 1)
script _T1
	-- SIMPLE LIBRARY WHICH ONLY CONTAIN INDIVIDUAL HANDLERS  (TYPE 1)
	property parent : libInit
	property _index : 0
	property _reload_on_update : T3
	property _hfsFileName : \"T2\"
	property _libName : \"T1\"
	property _scriptLIb : a reference to my _1_T1
	property _thisScript : a reference to my _T1
	property _libtype : 1
	property _libLoader : \"\"
end script

on T1()
	if my _T1's _index is 0 then
		my _T1's init()
	else
		if my _T1's _reload_on_update then my _T1's checkAndUpdateLibrary(a reference to my _T1)
		
	end if
	
	return my _1_T1
end textLib
"
	set theText to swapText(theText, "T1", T1)
	set theText to swapText(theText, "T2", T2)
	set theText to swapText(theText, "T3", T3)
	--	set theText to swapText(theText, "T4", t4)
	set the clipboard to theText
	tell me
		activate
		display alert "The text is ready to be pasted into the clipboard"
	end tell
	
	
end mkType1Template

on mkType2Template(T1, T2, T3, t4)
	-- T1 : scrObj of server, T2: scrObj of library, T3 filename, T5 reload_debug.
	
	local theText
	set theText to "(* SCRIPT LIBRARY  T1  OF TYPE 2 ====================================================================== *)

property _1_T1 : T2 of (load script alias \"T3\")
-- COMPLEX LIBRARY WHICH NEED TO GET CONTENTS OF A LIBRARY THROUGH AN OBJECT BECAUSE OF INTERNAL REFERENCES. (TYPE 2)

script _T1
	-- COMPLEX LIBRARY WHICH NEED TO GET CONTENTS OF A LIBRARY THROUGH AN OBJECT BECAUSE OF INTERNAL REFERENCES. (TYPE 2)
	property parent : libInit
	property _index : 0
	property _reload_on_update : T4
	property _hfsFileName : \"T3\"
	property _libName : \"T1\"
	property _scriptLIb : a reference to my _1_T1
	property _thisScript : a reference to my _T1
	property _libtype : 2 -- We must use an \"object of\" load script \"the lib\" in order to get our goodies type 2 in description
	property _libLoader : \"T2 of (load script alias \\\"T3\\\")\"
end script

on T1()
	if my _T1's _index is 0 then
		my _T1's init()
	else
		if my _T1's _reload_on_update is true then my _T1's checkAndUpdateLibrary(a reference to my _T1)
	end if
	return my _1_T1 -- which your code will tell what to do.
end objLib"
	set theText to swapText(theText, "T1", T1)
	set theText to swapText(theText, "T2", T2)
	set theText to swapText(theText, "T3", T3)
	set theText to swapText(theText, "T4", t4)
	set the clipboard to theText
	tell me
		activate
		display alert "The text is ready to be pasted into the clipboard"
	end tell
end mkType2Template

to swapText(theText, swapOut, swapIn)
	(* This bit comes from Apple's own "Replace Text in Item Names" script
with some of the variables changed to make it a call-able handler *)
	if the theText contains the swapOut then
		-- replace target string using delimiters
		set AppleScript's text item delimiters to the swapOut
		set the text_item_list to every text item of theText
		set AppleScript's text item delimiters to the swapIn
		set the theText to the text_item_list as string
		set AppleScript's text item delimiters to ""
	end if
	return theText
end swapText

Example Simple Library (But with great handlers!)


property LF : (run script "\"\\n\"") as Unicode text -- Nigel Garvey

to extractAllBetween(SearchText, startText, endText) ”Yvan Koenig
	set tid to AppleScript's text item delimiters -- save them for later.
	set AppleScript's text item delimiters to startText -- find the first one.
	set liste to text items of SearchText
	set AppleScript's text item delimiters to endText -- find the end one.
	-- causes "copy text item 1" to only copy text before the end text.
	set extracts to {}
	repeat with subText in liste
		if subText contains endText then
			copy text item 1 of subText to end of extracts
		end if
	end repeat
	set AppleScript's text item delimiters to tid -- back to original values.
	return extracts
end extractAllBetween

to swapText(theText, swapOut, swapIn)
	(* This bit comes from Apple's own "Replace Text in Item Names" script
with some of the variables changed to make it a call-able handler *)
	if the theText contains the swapOut then
		-- replace target string using delimiters
		set AppleScript's text item delimiters to the swapOut
		set the text_item_list to every text item of theText
		set AppleScript's text item delimiters to the swapIn
		set the theText to the text_item_list as string
		set AppleScript's text item delimiters to ""
	end if
	return theText
end swapText

on indexOfItem(theItem, itemsList) -- credit to Emmanuel Levy but I modified it with the considering case statements
	local rs
	considering case
		set text item delimiters to return
		set itemsList to return & itemsList & return
		set text item delimiters to {""}
		try
			set rs to -1 + (count (paragraphs of (text 1 thru (offset of (return & theItem & return) in itemsList) of itemsList)))
		on error
			return 0
		end try
		rs
	end considering
end indexOfItem


Example Complex Library ( it stores and retrieves properties )


script objLib
	property txtColor : missing value
	
	on isFavcolor()
		
		log "FAVCOLOR LIB isFavcolor  : my new color is : " & (txtColor of my objLib)
		if txtColor of objLib is missing value or txtColor of objLib is "" then
			return false
		else
			return true
		end if
	end isFavcolor
	
	on setFavColor(theColor)
		
		set txtColor of objLib to theColor
		log "FAVCOLOR LIB setFavColor() : my new color is : " & (txtColor of objLib)
		
	end setFavColor
	
	on getFavColor()
		log "FAVCOLOR LIB getFavColor() : my new color is : " & (txtColor of objLib)
		return (txtColor of objLib)
	end getFavColor
end script

Hello.
The LoaderMaker script is added, I have updated the documentation to reflect any changes from idea to implementation, I have also changed a variable name to better reflect its intention.

Hello. I had to upgrade the idle handler to not kick in during startup of the ScriptLibraryServer.

Hello.

I have had one more issue, that was beyond and far above -also with the idle handler, it turned out that some way or another, there were a spelling error of a variable in one of of the scripts that held the library object’s properties.

_textLIb were spelled _texLib in this line


property _thisScript : a reference to my _textLib

in script _textLib

Hello.

There was one more issue in the [b]init/b handler of the script libinit, where I had forgotten the keyword my in front of the property _libType, and thereby effectively broke polymorphism during reloading of libraries after had been purged from the ScriptServersMemory earlier.

I must say that everything is thoroughly tested at this stage, and what remains are support for AppleMods and Tetsuro Kurita’s loader systems. If you only use hardcoded library paths, maybe inserted with my library loader, then this release is for you.