太激动人心了,终于看到一个章节叫做The Lingo Core。
让我们再来看看这激动人心的字句:In order for the server to use Lingo, it must be accompanied by Lingo VM Xtra, located in the server's Xtra folder. The Lingo VM Xtra contains Lingo's core engine. The core is a subset of Lingo as a whole.It includes all the fundamental commands and functions that make up a programming language, such as terms for working with variables and lists, testing conditions, and repeating instructions.
希望这个子集能不吝赐教!
作为核心部分,它包含了解释一门语言必须的指令。就像编译器一样,必须处理数据类型,有各种控制流。也像编译器一样,它并没有把和Director相关的数据类型啊指令啊啥的内置到那么低的层次。像prite啊movie啊cast member这些东西,就好比CRT里面的那些个std::string啊神马的。所以,Lingo Core是不知道stageColor神马的,因为Lingo Core里面根本就没有这种东西。Lingo本身也是由Director的Xtra提供的,它并不在Lingo Core中。
Lingo Core包含最基本的东东:关键字、指令和方法、基本数据和对象。
Keywords:
case , if/then/else, put, return, delete, next repeat, repeat, set, exit.
Commands and functions:
abort, abs(), append, atan(), bitAnd(), bitNot(), bitOr(), bitXor(), call(), callAncestor(), chars(), charToNum(), color(), cos(), date, do, exp(), float(), floatP(), ilk(), inside(), integer(), integerP(), intersect(), length(), list(), listP(), log(), map, max(), maxInteger, min(), new(), nothing, numToChar(), objectP(), offset(), param(), paramCount, pictureP(), point(), power(), propList(), random(), rect(), result, return, rgb(), runMode(), sin(), sqrt(), string(), stringP(), symbol(), symbolP(), systemDate, tan(), text, time, union(), value(), voidP()
Data types and objects
child objects, color, compressedMedia, date, float, integer, list, the media, the picture, point, property list, rect, script objects, string, symbol, void
Lingo Core有了以上东东,然后,server端的Lingo VM Xtra扩展出其他的Lingo元素,然后就有最终的lingo的样子了。
------------------
About server-side scripting
呃,@__@。。突然。。没有了吗?关于Lingo Core就结束了么?挠墙。。。
Server的可编程环境是建立在三个文件的基础上,是的,它们是刘关张,一个xtra和两个脚本,Lingo VM Xtra,Dispatcher.ls和Scriptmap.ls。
Server运行的时候,首先会加载Lingo VM Xtra,然后Lingo VM Xtra会读Dispatcher.ls,把里面的内容作为服务器端脚运行之;然后Dispatcher.ls呢,会加载Scriptmap.ls,也将其作为server-side script.(原文中称dispatcher.ls以a running server script,其和server-side script有种不一样的赶脚。)
Dispathcer提供了server-side scripting会用到的一些handler,例如on initialize, on configCommand, on serverEvent, on incomingMessage神马的。这4个handler都可以编辑修改,但不能删除,必须有。
Dispatcher有了,server就会调用它的initialize,在此处,就会加载Scriptmap.ls文件,读入内容作为string,然后将这string作为脚本添加到server。(lingo似乎特别爱好这种读string作脚本的行为)
再看Scriptmap.ls,它内部维护了一个map -__-#,名叫 theMap,每一项记录了#movieID,#scriptFileName,还可能有#groupID。它的意思就是,看起来就是,不同的movie,过来同样的命令,server可以为之调用不同的脚本。为甚马有一种废话的赶脚。
要自定义脚本,也就是首先创建一个ls文件yourScriptFile.ls,然后在Scriptmap.ls的Handler on scriptMap 中theMap.append([#movieID:"yourMovieID", #scriptFileName, "yourScriptFile.ls"])。
Scriptmap.ls修改了以后,并不是非要重启Server才会加载新的theMap,可以向Server发送一个Reciepts是System.Script.Admin.Reload,subject随意的message。然后请跟我来。。。到Dispatcher.ls的on incomingMessage中看看,对了有一段已经被注释掉了的 case subject of "System.Script.Admin.Reload",
-- These commands may be useful during development; be sure to
-- disable them for a production server
--
-- case subject of
-- "System.Script.Admin.Reload":
-- put "LingoVM: reloading all scripts."
-- tlist = thread().list
-- repeat with t in tlist
-- t.forget()
-- end repeat
-- the timeoutList = []
-- me.loadScriptMap()
-- exit
-- "System.Script.Admin.Ping":
-- sender.sendMessage(subject, msg)
-- exit
-- "System.Script.Admin.ShowState":
-- showServerState()
-- exit
-- end case
这段代码若打开,红字部分就会在接收到消息后重新加载theMap了。是的,没看错,是多线程!关于多线程,改期到page 46再解。
movieID和scriptFile并不是强迫是一对一的关系,可以是一对多,谁多都可以。而且神奇的ls允许你用通配符,例如前文示例若是theMap.append([#movieID:"yourMovieID*", #scriptFileName, "yourScriptFile.ls"]),则意味着,所有名字前面有那啥的那些movie它们都用的是yourScriptFile.ls。
Standard Server events
自定义的ls文件,和Dispatcher.ls类似,有些Handler必须要有。这些Handler是用来响应标准服务器事件的,比如user log-ons, gourp creation神马的。当标准服务器事件standard server event发生了,首先响应的是dispatcher.ls的on serverEvent handler,然后它会向合适的script转发。这些事件包括:
- on movieCreate
- on movieDelete
- on userLogOn
- on userLogOff
- on groupCreate
- on groupDelete
- on groupJoin
- on groupLeave
- on incomingMessage
- on serverShutDown
- ..custom events created by th lingo author
Sending custom events to server-side scripts
调用server-side handler,客户端需要发一个#subject为HandlerName,#recipients为system.scripts的消息;server端需要在incomingMessage中处理。
Sending message from server-side scripts
客户端调用server-side handler之后,server会返回消息,server-side script是这样的发送消息的,user.sendMessage(fullMsg.senderID, "subjectName", "message from server")。fullMsg就是server收到的消息,user是发送消息的movie所使用的MultiUser Xtra的实例的LocalID(多读几遍)。
Multithreading
theThread = thread().new("testThread")
-- get a random number by assigning the calculateRandomNumber
-- handler to the newly created thread
theNumber = theThread.call(#HandlerName, me)
!!!!
Sharing data between threads
....
lock神马的略
Server security
略