Change transparency of another object - linden-scripting-language

I'm writing an LSL script attached to an object, and would like to change the transparency of another object which I have the UUID of (stored in a key variable).
I've read the documentation but can't even work out how to change the name/description of another object, let alone the transparency. I can only find methods for modifying the local object.
Does LSL not support modification of the properties of other objects, even when they're in the same region and have the same owner?

If it's in the same region then you could just add llListen() in one prim and use llRegionSay() in the other on a private channel.
Like this:
Prim 1 Script (Prim sending the command)
default
{
state_entry()
{
}
touch_start(integer total_number)
{
llRegionSay(-123456,"1.0"); // Channel -123456 can be anything. "1.0" will be the transparency setting passed to the 2nd prim
}
}
Prim 2 Script (Prim receiving the command)
default
{
state_entry()
{
llListen(-123456, "", "", ""); // Make the prim listen
}
listen( integer channel, string name, key id, string message )
{
if (channel==-123456) { // Match the same private channel
llSetAlpha((float)message, ALL_SIDES); // Convert "message" into an integer and pass to the llSetAlpha() function as the transparency - 0 = invisible 1 = visible
}
}
}

Don't use llRegionSay, use llRegionSayTo so you can specify the UUID of the receiving prim. Also, in the listen state of the second object you should have it ignore any objects with nonmatching owners
1st line of listen:
if(llGetOwnerKey(id) != llGetOwner()) return;

Related

Property does not persist in array?

My goal is to persist a swift-nio Scheduled instance in a struct named Receiver in an array to potentially use later. It creates the Receiver, stores it in the array and adds the Scheduled instance, but the Receiver instance in the array does not contain the Scheduled instance.
What could be causing this and how could I fix it?
It does not occur with anything else and the task associated with the Scheduled instance still executes. The XCode debugger even shows the instance in the Receiver associated with a variable, yet not in the array.
private var receivers: Array<Receiver>
func connect() {
var entry = Receiver(
// ...
)
receivers.append(entry)
connect(&entry)
}
func connect(_ device: inout Receiver) {
startTimeout(&device)
// device contains timeout, but receivers[0] does not
}
private func startTimeout(_ entry: inout Receiver) {
stopTimeout(&entry) // Does nothing initially (timeout not yet set)
var device = entry
// The timeout is added once here
entry.timeout = entry.eventLoop.scheduleTask(in: .seconds(10), {
print("Receiver timeout occurred")
self.reconnect(&device)
return 0
})
}
func someStuff() {
// This does not work. timeout is nil, the timeout still occurs
stopTimeout(&entry) // Cancels the Scheduled timeout
}
struct Receiver {
var timeout: Scheduled<Any>?
}
Your struct Receiver is a value type. Everytime it is passed it gets copied (a new instance is created). Manipulating it will alter only the new instance. You avoided that by using inout parameters.
But with:
receivers.append(entry)
you are appending a new instance to the array. Modifing entry later on will not affect the instance in the array.
In this case you should use a class.
class Receiver {
var timeout: Scheduled<Any>?
}

How to get the read data from a vr_ad_sequence

I have a register read sequence that goes something like this:
extend vr_ad_sequence_kind: [READ_REG];
extend READ_REG vr_ad_sequence {
// register to read
reg_kind : vr_ad_reg_kind;
!reg : vr_ad_reg;
// more fields no longer shown here
body() #driver.clock is {
var reg_item : vr_ad_reg; // reg_item gets a value from a
// method that returns the correct
// register instance from the addr_map,
// which I no longer want to show here
reg = new vr_ad_reg with { .kind = reg_kind; };
read_reg { .static_item == reg_item; } reg;
};
};
Now, I have a virtual sequence that does the vr_ad_sequence above:
extend MAIN MAIN_TEST sample_vseq {
!reg_read : READ_REG vr_ad_sequence;
body() #driver.clock is first {
do reg_read keeping {
.driver == driver.reg_driver;
.reg_kind == MY_REGISTER;
};
// how to get the value of MY_REGISTER.MY_FIELD from
// the reg_read sequence above?
};
};
My main objective is to read the value of a specific register bit field which is MY_FIELD in the above example. Is there a way to do it without modifying anything in the original READ_REG vr_ad_sequence? If it can't be helped, how do I make the READ_REG vr_ad_sequence return the read value to the calling sample_vseq?
Thanks very much in advance.
To obtain the register value after the read you first must make sure that the read is finished on the bus. So either your BFM is blocking (which often it isn't) or you add a flag to the sequence that tells whether the response has been received (this can be set from the BFM/driver).
Next, you can get the value from the vr_ad_map instance.
E.g.
body() #driver.clock is first {
do reg_read keeping {
.driver == driver.reg_driver;
.reg_kind == MY_REGISTER;
};
// Wait for read response
sync true(reg_read != NULL and reg_read.done);
// Access shadow register through pointer to vr_ad_map instance
print addr_map.get_register_by_kind(MY_REGISTER).as_a(MY_REGISTER vr_ad_reg).MY_FIELD;
};
(I can't check the syntax right now)

Duktape/C array element accessors

I am trying to implement something like a HTMLCollection which is an array that can lose/gain elements without JS action.
duk_push_object(ctx);
duk_push_string(ctx, "length");
duk_push_c_function(ctx, my_length_getter, 1);
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER);
duk_push_c_function(ctx, my_item_getter, 1);
duk_put_prop_string(ctx, -2, "item");
Doing it like above I get an object on which I can read the my_array.length property and get an item by calling method my_array.item(index). But I don't get an item by using my_array[index].
If I replace the first line above by
duk_push_array(ctx);
I get an error that the length property is not configurable.
Is it possible to achieve what I want? An array with 'lazy' element binding? I have the impression that NetSurf somehow manages to do this but haven't quite worked out how ...
Ecmascript provides two main standard mechanisms for property virtualization: getters/setters (accessors) and the Proxy object. Getters/setters are limited to properties you explicitly set up beforehand so they don't always work for fully virtualizing an object, but a Proxy object can capture among other things all property reads and writes.
You should be able to implement your use case using a Proxy. Duktape implements a subset of the Proxy traps (documented in http://duktape.org/guide.html#es6-proxy). As a minimal example of capturing all property reads and writes (but forwarding them to the target):
var target = { foo: 'hello' };
var proxy = new Proxy(target, {
get: function (targ, key) {
print('get', key);
// may also return a virtualized value
return targ[key];
},
set: function (targ, key, val) {
print('set', key, val);
// may also capture (virtualize) write, or reject write
targ[key] = val;
return true; // indicate write was allowed
}
});
print(proxy.foo);
proxy.bar = 123;
Running with "duk" this prints:
get foo
hello
set bar 123

Angular - Objects seem bound to eachother but arent

I have an edit page where the user can edit a file in the system, and then save it. When loading the file, I make two objects out of the result, one is bound to the view and the other I wish to keep (in its original state) until "save" is clicked, and then use it to compare vs the view-bound object, to see if any changes have been made.
So, when the page loads, this is being run
$http.get('/api/files/' + $stateParams.id)
.then(function (result) {
vm.fileTemp = result.data;
vm.fileTempCopy = result.data;
The fileTempCopy is not being touched or referenced by anything in the view or elsewhere in the controller, except in the save-method, where i check if they are alike or not. But somehow, both of them are updated when i make changes to the input fields (as if they were both used as ng-model for the inputs).
if(vm.fileTemp === vm.fileTempCopy)//in save-function
is always true, and their fields are exactly the same.
Why does this happen and how can I solve it?
Using the assignment operator, you are actually just referencing the original array. Arrays are reference types. That means, that they don't actually store values, they only store references to those values. What you where doing is copying a reference to a memory location, meaning that any changes to the memory at that location (including removing elements) will be reflected in both arrays.
So you will want to do this instead:
vm.fileTemp = angular.copy(result.data);
vm.fileTempCopy = angular.copy(result.data);
here is a very basic approach to checking an object's "value equality".
function isEquivalent(a, b) {
// Create arrays of property names
var aProps = Object.getOwnPropertyNames(a);
var bProps = Object.getOwnPropertyNames(b);
// If number of properties is different,
// objects are not equivalent
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i];
// If values of same property are not equal,
// objects are not equivalent
if (a[propName] !== b[propName]) {
return false;
}
}
// If we made it this far, objects
// are considered equivalent
return true;
}
//After your update Outputs: false
console.log(isEquivalent(vm.fileTemp, vm.fileTempCopy));

SharedObject for Arrays of Object. Can't get correct data when restart flash

I have an array that stored some Object with its data, and I try to store it in my computer.
If I try to load for the data after I've save the data, I could get a correct data.
Exp: [Object Player]
But if I restart the flash, the data seems to be gone.
What is the problem?
private var sharedObject:SharedObject = SharedObject.getLocal("aquarium", "/");
public function save(n:String):void
{
/* player list will only handle the list of all the Players
* each player data will handle by Player class itself.
*/
registerClassAlias("Player", Player)
player = new Player()
player.newPlayer(n, LATEST_VERSION)
playerArray.push(player)
//saving as shared object
sharedObject.data.aquariumData = playerArray
sharedObject.flush()
load()
}
public function load():void
{
if (sharedObject.size > 0)
{
trace("loading player info")
playerArray = sharedObject.data.aquariumData
trace(playerArray)
}
else
{
trace("there's no record")
}
}
Can you please provide the code how you obtain the shared object ?
Do you use var sharedObject:SharedObject = SharedObject.getLocal("sharedObject"); or something like this ?
Apart from that when calling registerClassAlias("Player", Player) before serialization keep in mind that it must be called before extraction of the data also, so the de-serialization will work correctly and returns array of Player objects not array of Object objects.
And ofc closing the sharedObject is very nice practice after flushing :)
P.S. Your code works as far as i've tested it replacing your Player class with other custom class.

Resources