FIXES - Use Lua consistently ------------------------ I noticed that the internal messages seem to be mostly LSL, but really should be Lua at this early stage. LSL should be kept strictly inside the LSL scripts. This might get tricky. Also, massage these notes into docs later. LuaSL Script server in C. Opens a socket for script commands. Accepts "compile(...)", "run(...)", and "exit()", "run(...)" Creates a script via scriptAdd(), with send2server included. Either runs it directly, or stuffs it into the worker thread queue. otherwise send2script(SID, command) NOTE: treats "return ..." different to "function(...)". send2script C function that adds the message to the scripts messages, then runs the script worker thread. Runnr.c send2server() C function that either directly runs certain LSL functions, or - LuaSL_main.c takeScript(me); send2(me->client, me->SID, message); releaseScript(me); Runnr.c worker thread Starts or resumes the script running. If there's a message, push it as an argument. Expects the script to eventually call Runnr.receive(). Runnr.receive() Does a Lua yeild, which will return once there is a message for this script. Runnr.send() Either send2script(SID, message), or send2server(message) lib/LSL.lua Lua script that supplies all the LSL functions, and the basic LSL script support. LSL.Lua runs the main loop of each LSL script. waitAndProcess(false, "LSL.mainLoop") LSL.lua assumes that it gets Lua messages from Runnr.receive(), and tries to run them via loadstring() and pcall(). "start()" while paused is handled special, and likely should stay that way. Sets the environment to that of LSL.lua, unless it's an event, before calling pcall. Says it runs the return, but also sends the return via Runnr.send(nil, result1), which is commented out. Sooo, doesn't do anything with the result, unless returnWanted. Returns whatever the pcall returns, if returWanted, which we don't during the main loop. Some of the ll functions are defined as a wrapper around waitAndProcess, that first Runnr.send(nil, ...) the function call details. Which is currently the LSL version of the name, with LSL arguments. NOTE: the wrappers don't currently deal with casting arguments, but should, and it has enough info to do so. love.c World server in C. Runs / connects to LuaSL server. Sends "compile(...)" commands for each script it finds. Accepts "compilerError/Warning(...)", "compiled(...)" Once "compiled(...)", sends "run(...)" commands for them. otherwise, a whole bunch of LSL functions, mostly faked, some simply sent to the client. otherwise just log it as INFO. Opens a socket for client stuff. For each new client - send2(client, "loadSim(...)" Accepts "events.touch_start()", and "events.listen()" passing them onto LuaSL, though with some extra info if it's a touch - send2(ourGlobals->serverLuaSL, me->SID, "events.detectedKeys({\"%s\"})", ownerKey); send2(ourGlobals->serverLuaSL, me->SID, "events.detectedNames({\"%s\"})", ownerName); send2(ourGlobals->serverLuaSL, me->SID, "events.touch_start(1)"); otherwise complains with a WARNING. At some point - send2(LuaSL, SID, "return ...") send2(LuaSL, SID, "events.*(...)") send2(LuaSL, ownerKey, "exit()") extantz.c Client in C and lua. Runs / connects to love server. Accepts a bunch of LSL functions, "loadSim(...)", llSay() and friends, llDialog() otherwise log as INFO. At some point - send2(love, SID, "events.touch_start(1)") send2(love, SID, "events.listen(...)") What should happen (though leaving the Nailer step for much later, so use Lua instead of Nails ) - LuaSL converts LSL into Lua runs everything in the Lua domain sends Lua to the LuaNailer deal with LSL -> Lua argument casting accepts Lua from the LuaNailer deal with Lua -> LSL return value casting LuaNailer converts Lua <-> Nails love accepts Nails commands from LuaNailer sends some of them onto extantz sends some back in response relays / modifies Nails commands from extantz to LuaSL extantz accepts Nails commands from love sends Nails commands to love What does this internal Lua look like? The internal Lua should be more SledjHamr flavour than LSL flavour, so we get a chance to design it right. What's right though? Handled by extantz - For all of these, we need to know who / what sent it, and when, also where the sender was at the time for some of these. llSay(integer channel, string text)+ also llOwnerSay(string text) llRegionSayTo(key target, integer channelID, string text) Actually, if this sends messages to objects, then love should handle it, only handled here if it's for a person. llInstantMessage(string user, string message) llDialog(key avatar, string caption, list arseBackwardsMenu, integer channel) llListen(integer channel, string name, key id, string msg) Sent from extantz - events.listen(integer channel, string name, key id, string message) events.touch_start(integer num_detected) Handled by love - object information get avatar info get llRequestPermissions() position and rotation get alpha get inventory and link details get free memory get "notecard" get Sent from love - events.detected*({"",}) events.*(...) return ... Handled by the script server - time stuff get / set script state get / set Communication say(key source, vector location, integer timestamp, text message, string filter, ...) Source is the key of the avatar / object / script saying things. Location is the location of that source in world at the time of the timestamp. Though in the case of IMs, avatar might not be in world at the time. filter is a comma separated string - ",," llSay()+ include , and a distance restriction in meters. The distance restriction is one of a fixed four in LL - whisper, say, shout, region. What these mean depends on how an OpenSim region is configured, or the default SL values. So stuff in the SL values in LuaSL, convert to OS values in love, calculate objects / avatars within that radius in love, then pass it onto the objects scripts, or the avatar's client. "Region" is the default, in other words, no distance restriction. would be a persons ID for llOwnerSay() and llInstantMessage(), but object/person ID for llRegionSayTo() would be a channel name / number. LSL only has numbers, with two being fixed function. We can relax that and add strings. NOTE: llRegionSayTo() includes both and . llDialog() includes a string and a list, er I mean table, Lua table. Objects that are interested in things said register listeners with love, and get events.listen()'s sent to them. Some sort of filter is needed for this as well. listen(string filter, string text, integer flags) filter - ,,, In this case, isn't actually needed by any LSL function, but I include it for completeness sake. means don't listen to yourself, which is usually what you get in LSL, but I'm leaving that option open. text - a string to match, might be a regex flags - include the regex flags from the OS version The last two arguments are optional. Flags is itself optional if text is there, defaulting to "not a regex". returns a can be in/actived, or removed. This includes llDialog() and llTextBox(). Note that these two are LL specific things, we use skang for the more general case. Though both need client side support, which means love has to pass these things around. Link messages include the number of the link (to or from, depending on which end you are at), a number, a string, and a key. These are entirely internal to LuaSL though. purkle registers a listener, with no filter. llDialog's client side sends a say() to love. Normally, that wont be bounced back to extantz. SL and OS however, bounce all channels across the viewer, which is why some of them can peek at other channels. Which is why purkle registers with no filter, gotta gettem all. Later we should default to just channel 0. Soooo, every one sends their say() commands to love. Love decides who to send listen() events to, which may include sending back to the source. May need to start name spacing Lua stuff. scripts.compile(), scripts.run(), scripts.reset() scripts.listen() which would include avatar's clients registering via purkle pretending to be a Lua script, world.say() The only place where there is any ambiguity is LuaSL. Purkle accepts event.say() from love, LSLGuiMess sends world.say() to love. Love routes world.say()'s around, even back to the source if needed, sending them as event.say(). LuaSL sends world.say() to love. LuaSL accepts event.say() from love for scripts. When a say() comes in, it's executed, which triggers the say() that sends to love. OOPS!!!! world.say() -> events.say() More generic event system? There are other events flying around. BASIC event Just send it to LuaSL, it loops through all scripts, sending the event to them all if they have an event function in their current state. REGISTER event Script has to register for these events with love. Can have filter. love loops through all regisitered "scripts", applies filters, sends events. REQUEST event Script has to request an event from love. Can have a filter. Love sends event straight back to the script. Once. This covers the "wait for return value" case as well. events.return()? touch_start goes from extantz to LuaSL, via love. Most of the rest go from love to LuaSL I think. link_message, state_entry, state_exit are internal to LuaSL, timer should be. All manner of arguments sent to events. Some of them include the llDetected*() functions for getting more info. So we need some way of sending arbitrary data, as well as a bunch of fixed data, over the network when we send events. Listen events are common? collision, land_collision, not_at_*_target , and touch might be ongoing? llCollisionFilter(string name, id, integer accept) llTarget(vector position, float range) llTargetRemove(integer number) llVolumeDetect(integer detect) Sensor and no_sensor might be common, but you request those, your silly fault, they have filters though. llSensor(string name, string id, integer type, float range, float arc) llSensorRepeat(string name, string id, integer type, float range, float arc, float rate) Event types can have filters? Events can be types? In otherwords, generic filter system, attach say filters to say events, etc. Figure this all out as we go along. LuaSL crashes ----------------- Hmmm, empty functions get no end, that's NOT legal in Lua. Project paths ----------------- The executables currently live in ...../SledjHamr. Test executables stay in the src directory. Media and other data in SledjHamr/media (includes the test sim and Irrlicht examples). External libraries are in SledjHamr/libraries (Irrlicht and lemon). Irrlicht is statically linked, so except for it's media, we don't need it at run time. We could probably move the Irrlicht examples we actually use (all test data anyway) to Test sim. Lemon is only used at build time. Builders should be able to - put binaries in /usr/local/bin put libraries - /usr/local/lib/SledjHamr put media in /usr/local/share/SledjHamr If they don't, those things should be in the build directory, where they are now. User should be able to - Run sims from where ever they like. Write GuiLua modules that reference media that is where ever it is. Normally media would come along with the module. So on disk modules would include media in the same directory as the module. In world modules would be in some object, and the media should be in that object to. Client side modules from the net ... dunno yet. Write their own skins, using their own media. SOOOO ... install.lua should - (doesn't exist yet) SledjHamr binaries -> prefix .. '/bin' SledjHamr/libraries -> prefix .. '/lib/SledjHamr' SledjHamr/media -> prefix .. '/share/SledjHamr/media' This should not include data that could be changable, so maybe the test sim should move elsewhere? LuaSL at least puts compiled scripts in the test sim. Nails will eventually make changes to the test sim during testing. For now, we don't care, there's no actual installing going on. SledjHamr/locale -> prefix .. '/share/SledjHamr/locale' Irrlicht is flickering like crazy. Hmm, might be Irrlicht's fault, mostly it flickers to black, but I've seen it flicker to the first frame of the GL demo. On the other hand, it shows the Elm background usually. GL viewport aspect ratio should remain stable through resizes. FEATURES - Er, all of them I think. B-) Make the existing toolbar / tab thingy a bit more tab like, and have the scroll in effect be position / direction aware. Combining window title, menu, top level tabs, and toolbar widgets might be good. Perhaps auto spreading across two lines (menu + tools / tabs) on window shrinkage first before going to the "More.." thing (for both tabs and tools). Need pie menus! Generic scrolling text area, with time stamps, clickable URLs (including internal links to profiles and stuff), logging to file, reading history from file (both a few dozen lines, or the entire thing). EFL log domains should be able to feed into these, with colours, and should be able to split / filter bits to different areas. Two Elm_entry's, one not editable. See "Entry 7" test. IM tabs should show a very faded version of the others profile image/s. IDEAS - Internal window manager. ------------------------ Write my own, use ePhysics. Hopefully ePhysics has some sort of magnetism / attraction thingy. See the forces demo, should be doable. Collision restraints and impulses? See if Evas allows detaching stuff from one canvas and adding it to another canvas. This allows things like tearing off tabs from windows, tearing off sub menus, and switching windows between internal and external windows, without having to entirely recreate the UI stack within. Hmm, think this is what swallow / unswallow is all about. Think that only covers stuff in the same Evas though. Not sure this can be done currently. Maybe the Elm socket and plug thingy can be used? Some or all of the windows could be external processes anyway. The socket seems to be some sort of server, which can share it's content to other plugs (processes), each one sees identical stuff, including interactions. The plugs can come and go as they please. Or perhaps elm_object_part_content_set/get/unset or elm_object_item_part_content_set/get/unset might work for this. An internal window has a title bar, with a centered title, and the usual widgets. The title part is split into three, if you grab and drag from the middle bit, it moves as normal. If you grab and drag from the others, it dangles from that corner as you move it. ePhysics magnetism can be used for the usual "snap to nearby window" thingy. Grabbing and flicking a window means it will move as a physics object, bouncing off stuff until it looses enough energy to stick magnetically to something, or lay on the bottom. Minimised windows could be small transparent ePhysics buttons showing just the title. Can be dragged, flicked, or maybe double clicked to open. Right click for menu as usual. Windows need title bar, close, minimize, and if they are resizable, resize grab edges/corners, and bottom right corner resize. Some need menus. They need to remember their size, position, minimized state, closed state. Try to put top toolbar style widgets in the title, and / or menus. Have the toolbar "Menu" flip down on hover. Also add the "tear out of window" widget for making an internal window external, again with drag and drop or widget to bring them back in again. All tabs should be tear off? All menus are. Currently menus reattach when you close their windows. Currently tabs re attach when you click on their tear off button again. Hmmm, maybe should re attach both if you drag and drop them? With some sort of quivering with anticipation effect when they are in the drop zone? Menu window can start to shrink towards their origin menu when dragged close. Dragging the tab button should tear them off. Though they currently can be dragged to re arrange them, so that will be dragging them in the other axis then I guess? Tearing off should have some sort of rip and wobble effect, maybe an ePhysics soft body? Windows like the prim edit window should do like Elm toolbars when resized too small, low priority widgets shrink down to a "More.." button. Optional hover focus on windows, maybe even on some widget types. Focused windows should be not quite as transparent as unfocused ones. Allow control over transparency levels (press on scroll wheel and wiggle it?). Current windows use the horrid "click anywhere to focus and raise", should have an option for proper layering. :-P ELM - What is - Conformant? Squeezes things to make room for virtual keyboards and other mobile stuff. CTX popup? A pop up simple list of items. Mapbuf? Used in the launcher tests, so that might provide a clue. I think it just stuffs the entire container widget into a single image so that resizing and moving is faster. A performance tweak. Store (under helpers)? Threaded content getter for genlist, and other widgets in future. Basically the content of a genlist is fetched in the background, to slowly populate a genlist. The store can do any sort of arbitrary mapping of what it fetches to genlist item content. Currently this is file system based. Might be useful for inventory, though we really need a tree widget, which happily genlist does. Stored surface buffer (Launcher tests)? Just the mapbuf thingy above I think. Trees. ------ From a discussion https://plus.google.com/u/0/105915569012457699790/posts/e5ZXmTQp4ig?cfem=1 By Tara Li. "the Linden Trees are based on L-System generative techniques. 4a) Add randomization to those L-System generations, so while the tree looks like it's the same species, it's not the exact same specimen over and over. You would need a seed value that might can be locked if you do want identical copies, but that could be transmitted with the plant so that it looks the same for all viewers, and 4b) Add a flag so that the Linden Plant prim includes a particle system with data defining a bark texture, a leaf billboard texture, and the parameters of the L-systems, so you can define your own 1-prim Linden Plants. Include editor in the client for Linden Plants to modify and create your own." Contacts. --------- Have a system of multiple sets of contacts. The defaults will be Everyone and Friends, each set contains an email address, and zero or more IM addresses. Recommend people use a spam catcher for the Everyone contact, and don't make it mandatory. Even the Friends one isn't mandatory. At all times err on the privacy side of things. OTR --- Since I would be adding OTR to the IM system anyway, here's a cool idea. Wrap all the data transfers in OTR.