FIXES - Black bug ------------- Evas3D and Elementary don't get along well with more than one mesh that has textures. After hiding the window, by iconifying it, or moving to a different virtual desktop for a bit, or after waiting a few minutes. The textures are replaced by blackness, a shiny blackness sometimes. Only seems to happen in Elementary. 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 sends the message to the love server. send2parser() will intercept the send2() call. LuaSL_main.c takeScript(me); send2(me->client, me->SID, message); releaseScript(me); send2parser() C function that intercepts send2(), and deals with time, script states, and resetting scripts. 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 yield, 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. What should happen is that instead of "return somevalue", it's just "someValue", but that could be "someValue + thingy". So, execute it, return the result if returnWanted. 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 world.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 do listen to yourself, which is usually not 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. events.say(key source, vector location, integer timestamp, text message, string filter, ...) 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, except they bounce up to love to get to other prims in the link set? 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(), events.say() The only place where there is any ambiguity is LuaSL. Purkle accepts events.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 events.say(). LuaSL sends world.say() to love. LuaSL accepts events.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? Events are different from state changes. The Nails web page mostly talks about the state of objects, and changing them. Events are for a variety of things, not all of which can be represented by a state change message. 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 registered "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. 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 other words, generic filter system, attach say filters to say type events, etc. Figure this all out as we go along. parseStream() / send2() both - lookup command in conn->commands if found, use that found function pointer else try conn->unknownCommand for the function pointer call the function pointer or bitch / send to love LuaSL open a server stream incoming -> parseStream() commands scripts.compile(), scripts.run(), scripts.return(), etc. unknown events.eventName() -> loop through each script looking for "function" = type(currentState.[eventName]) otherwise send2script() bitch outgoing -> send2() commands scripts.state(), scripts.reset(), scripts.link_message(), and timer.*() commands currently in LuaSL_main.c->send2parser() unknown NULL actually send it love open a stream to LuaSL incoming -> parseStream() commands various compiling results, world functions, and event registrations / requests unknown NULL bitch outgoing -> send2() commands NULL unknown NULL filter as needed actually send it open a server stream incoming -> parseStream() commands various world functions, and event registrations unknown NULL bitch outgoing -> send2() commands NULL unknown NULL filter as needed actually send it extantz open a stream to love incoming -> parseStream() commands events.say(), events.dialog(), events.textBox(), events.loadSim() unknown check for valid Lua bitch outgoing -> send2() commands NULL unknown NULL actually send it 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' ~/.SledjHamr/ Contains an index.omg, and / or a bunch of sim directories / OAR files / etc.. ~/.SledjHamr/.downloaded/ Contains downloaded sims in their original format, like OAR files. ~/.SledjHamr/.cache/ unpacked/ converted/ sha1/ types/ compiled/ Contains various cached stuff that can be deleted at any time. unpacked/ is for anything that's in an archive file, unpack it all in there. converted/ is for anything that is converted to SledjHamr formats, from legacy formats. sha1/ is for the sha1 sums of asset files, and other details? types/ is for storing the types of asset files? compiled/ is for translated and compiled scripts. 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. The big merge ------------- At some point, some parts of this system will become useful enough to start merging it into Imprudence and OpenSim. Actually, merge it into meta-impy, that's my experimental Impy fork now, then Imprudence later. This discussion may not cover stuff that has not been written yet. There's a bunch of stuff that could just run on the end of a pipe / socket that wont need GTK / EFL integration, so I'll list those first. Might even be good to merge these sorts of things into meta-impy first, it uses less of the EFL libraries, and could live on the end of a pipe, so no need for GTK / EFL integration. I could combine running a love server, with the libg3d work, to load SledjHamr style sims into meta-impy. Then morph the login screen into a local sim in world screen. Later could use this to allow people you meet in OS/SL to come to your world, so long as they also have a SledjHamr viewer (or use HG when that bit gets written). The script library might merge into the viewer oddly enough. I want the viewer to be user scriptable, and LSL is a language users might be familiar with. Once the hybrid Lua / LSL thing is working, that's going to be great. Just like now, where LuaSL relies on it's client (the love world server) to perform in world stuff, it can rely on the viewer to perform in world stuff. Obviously there will be some things that a viewer can't do that an in world LSL script can, we will just have to live with that. Then use it as a feature of SledjHamr, which will have no such limitation. B-) My AO script might work perfectly with this script engine, so I get to include it in SledjHamr. The love server integration mentioned above gives this to us for free, but we can do both. woMan is designed to be stand alone, or called out from the meta-impy login screen. meta-impy uses GTK2+ I think for it's library, and EFL has some sort of GTK integration. If I can get that to work, then the skang based stuff can merge. I'll list those next. I can use the llDialog() or purkle widgets, especially when you can rip them out of the main window to be their own windows. Once the files widget morphs into a proper inventory widget, I can use it in meta-impy for inventory AND an asynchronous file requester. Finally (I think) I could rip the meta-impy graphics pipeline a new one. Also, try to merge the script engine into OpenSim, though that might get a lot less of a work out. Adding server side skang to LuaSL could be interesting.