Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Data Storage

Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
09-23-2009 12:22
i fixed the script in my post above if anyone's interested
_____________________
Dark Heart Emporium

http://www.xstreetsl.com/modules.php?name=Marketplace&MerchantID=133020

want more layers for tattoos, specifically for the head? vote here
http://jira.secondlife.com/browse/VWR-1449?

llDetectedCollision* Functions similar to touch
http://jira.secondlife.com/browse/SVC-3369
Klug Kuhn
Registered User
Join date: 7 Sep 2007
Posts: 126
09-23-2009 22:13
i think the most tricky part you were facing was to play around the notecards(NC) after inventory changed. It is a very common question arises when making vendor or rezzer, especially the rezzing version with which items to rez and to sell. To be able to update the vendor content automatically instead of hardcoding or re-write config NC by copy-and-paste the inventory names.

First off, any bit of content change detection will trigger the "changed(integer change)" event. For instance if you add or delete 5 NC at the same time, the content will be reloaded not only 1 time and the changed event will probably occur 4-5 times depends on the lag performance. This is very unstable and hard to follow which line is it up to. To overcome this issue, i usually use a separate script to handle this multiple content changes. Simply keep sending a message to itself and tells the script that "Oi!! Content change hasn't finished yet, don't do things until i say so". It will trigger a timer event in 2 sec (should be enough for the sake of lag) and send a link_msg notice to where i indeed need the content change event originally.

Then there're 3 possibilities after a content change:
- the number of NC remains unchanged, but one or more of the NC was edited and saved.
- the number of NC increased.
- the number of NC decreased.

To achieve more script memory, beside the main NC update script, i've also made a storage script which holds all NC UUID(key). When the number of NC unchanged, the main script send all the NC keys to the storage script and compare which NC is edited/saved. As the number of NC changed, the main script will check which NC is added or deleted simply by comparing between the original NC list and the new NC list after content changed.

The example below demos the use of the idea. To see how it works, drop the 3 scripts into a prim. Add as many NC as you like to the content as long as the script memory can handle, then when you add, delete or save any NC in the content. A owner message will tell you which and how much NC has been changed. You don't have to worry about the names or the order of the NC in the content.

Afterward you could use the result whatever you like to create menus or upload NC etc. Hope you find it useful. :)

CODE

// CONTENT CHANGING SCRIPT
default
{
state_entry()
{
}
changed(integer change)
{
if (change & CHANGED_INVENTORY)
{
llMessageLinked(LINK_THIS,0,"changing_content",NULL_KEY);
}
}
link_message(integer sender,integer num,string msg,key id)
{
if (msg == "changing_content")
{
llSetTimerEvent(2.0);
}
}
timer()
{
llSetTimerEvent(0.0);
llMessageLinked(LINK_THIS,0,"content_changed",NULL_KEY);
}
}



CODE

// MAIN NC UPDATE SCRIPT
integer total_NC = 0;
list NC_name_list = [];
integer i = 0;
//===========================
integer check_NC_exist(string NC_name,integer flag)
{ // flag: 0-NC increased; 1-NC decreased;
integer output = FALSE;
string inventory_NC = "";
integer j = 0;

if (flag == 0)
{
for (j = 0; j < llGetListLength(NC_name_list); j++)
{
inventory_NC = llList2String(NC_name_list,j);

if (inventory_NC == NC_name)
{
output = TRUE;
j = 999999; // NC exists matched, force stop the for-loop
}
}
}
else if (flag == 1)
{
for (j = 0; j < total_NC; j++)
{
inventory_NC = llGetInventoryName(INVENTORY_NOTECARD,j);

if (inventory_NC == NC_name)
{
output = TRUE;
j = 999999; // NC exists matched, force stop the for-loop
}
}
}

return output;
}
//===========================
default
{
state_entry()
{
}
link_message(integer sender,integer num,string msg,key id)
{
if (msg == "content_changed")
{
total_NC = llGetInventoryNumber(INVENTORY_NOTECARD);
string NC_name = "";
key NC_key = NULL_KEY;
list temp_NC_key_list = [];
list temp_NC_name_list = [];

for (i = 0; i < total_NC; i++) // update current temp lists
{
NC_name = llGetInventoryName(INVENTORY_NOTECARD,i);
NC_key = llGetInventoryKey(NC_name);

temp_NC_key_list += NC_key;
temp_NC_name_list += NC_name;
}

// store the previous list and check if the number of NC is different
integer original_list_length = llGetListLength(NC_name_list);

if (total_NC == original_list_length) // the number of NC unchanged
{
llMessageLinked(LINK_THIS,1,llList2CSV(temp_NC_key_list),NULL_KEY); // send all the NC keys to storage script and compare which NC is changed
}
else if (total_NC > original_list_length) // the number of NC increased
{
// check which NC is added
string checking_NC = "";
list added_NC_name_list = [];

for (i = 0; i < llGetListLength(temp_NC_name_list); i++)
{
checking_NC = llList2String(temp_NC_name_list,i);

if (!(check_NC_exist(checking_NC,0)))
{
added_NC_name_list += checking_NC;
}
}

llOwnerSay(" "+(string)llGetListLength(added_NC_name_list)+" notecard(s) is added:\n"+llList2CSV(added_NC_name_list));

NC_name_list = temp_NC_name_list;
llMessageLinked(LINK_THIS,3,llList2CSV(temp_NC_key_list),NULL_KEY); // update NC_name_list in storage script
}
else if (total_NC < original_list_length) // the number of NC decreased
{
// check which NC is removed
string checking_NC = "";
list deleted_NC_name_list = [];

for (i = 0; i < original_list_length; i++)
{
checking_NC = llList2String(NC_name_list,i);

if (!(check_NC_exist(checking_NC,1)))
{
deleted_NC_name_list += checking_NC;
}
}

llOwnerSay(" "+(string)llGetListLength(deleted_NC_name_list)+" notecard(s) is deleted:\n"+llList2CSV(deleted_NC_name_list));

NC_name_list = temp_NC_name_list;
llMessageLinked(LINK_THIS,3,llList2CSV(temp_NC_key_list),NULL_KEY); // update NC_name_list in storage script
}
}
else if (num == 2)
{
if (msg != "")
{
list changed_NC_index_list = llCSV2List(msg);
list changed_NC_name_list = [];

for (i = 0; i < llGetListLength(changed_NC_index_list); i++)
{
changed_NC_name_list += llList2String(NC_name_list,llList2Integer(changed_NC_index_list,i));
}

llOwnerSay(" "+(string)llGetListLength(changed_NC_name_list)+" notecard(s) is changed:\n"+llList2CSV(changed_NC_name_list));
}
}
}
}




CODE

// STORAGE SCRIPT
list NC_key_list = [];
//===========================
default
{
state_entry()
{
}
link_message(integer sender,integer num,string msg,key id)
{
if (num == 1)
{
list temp_NC_key_list = llCSV2List(msg);
integer temp_list_length = llGetListLength(temp_NC_key_list);
integer i = 0;

list changed_NC_index_list = [];

for (i = 0; i < temp_list_length; i++)
{
key original_NC_key = llList2Key(NC_key_list,i);
key new_NC_key = llList2Key(temp_NC_key_list,i);

if (original_NC_key != new_NC_key)
{
NC_key_list = llListReplaceList(NC_key_list,[new_NC_key],i,i);
changed_NC_index_list += i;
}
}

llMessageLinked(LINK_THIS,2,llList2CSV(changed_NC_index_list),NULL_KEY);
}
else if (num == 3)
{
NC_key_list = llCSV2List(msg);
}
}
}
1 2