Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkSet Data feature from SL #64

Merged
merged 29 commits into from
Nov 16, 2023
Merged

Conversation

mdickson
Copy link
Collaborator

@mdickson mdickson commented Nov 5, 2023

Changeset with code from Zontreck (Aria) that had originally been posted to OpenSim Core Mantis with permission. The Core team refused the changes. I had to make a few small changes because this branch is still targeting Mono and only implements C# 7.3 and a few C# 8.0 features were used. It's otherwise essentially as it was submitted. Many thanks to Zontreck for making this feature available to our users!

… been posted to OpenSim Core Mantis with permission. I had to make a few small changes because this branch is still targetting Mono and only implements C# 7.3 and a few C# 8.0 features were used. It's otherwise essentially as it was submitted.
… called correctly on completion. Remove the IsRoot check in BuildPrims for linksetdata. At this stage we don't yet have a fully instantiated prim so the SOG is undefined.
…here is no linkdata on a prim. Previously it was left off an being explicitely set and the connector considers that an error.
@mdickson mdickson self-assigned this Nov 6, 2023
@zontreck
Copy link

zontreck commented Nov 7, 2023

okay, i have it working, but YEngine needs to be fixed at some point. It appears to be running statements out of sync. for instance...

EDIT: Updated the script and the sample output to include my final patches

        S([llLinksetDataWrite("Test-001", "This is a test"), llLinksetDataAvailable()]);

Should output


[16:08] Object: 0 ~ 131050 <-- first write statement

Instead, it outputs


[16:08] Object: 0 ~ 131072

As if it called the data available function and caches the value before it finishes evaluating the statement to write. This is a separate issue from Linksetdata of course, but just a inconsistency i am noting. I am going to add the two remaining new functions, that were not in this patch previously. Then it is ready.

Here is a test script

Expected Outputs
  /*
  
      TEST SCRIPT FOR LINKSET DATA IMPLEMENTATION

Output from Second Life

[18:22] Object: [ BEGIN ] : MARK BEGIN
[18:22] Object: [ COUNT ] : 0
[18:22] Object: [ LIST ] : 
[18:22] Object: [ FREE MEM ] : 131072
[18:22] Object: [ Write 001 ] : 0 ~ 131050
[18:22] Object: [ Delete 002 ] : 4 ~ 131050
[18:22] Object: [ Write Protected 003 ] : 0 ~ 131003
[18:22] Object: [ Protection Test ] : 3 ~  ~ Testing
[18:22] Object: [ Delete 003 ] : 3 ~ 131003
[18:22] Object: [ Delete w/ false key 003 ] : 3 ~ 131003
[18:22] Object: [ Delete w/ key 003 ] : 0 ~ 131050
[18:22] Object: [ Write protected 004 ] : 0 ~ 131007
[18:22] Object: [ Write protected 005 ] : 0 ~ 130964
[18:22] Object: [ Write 006 ] : 0 ~ 130951
[18:22] Object: [ Delete w/ false key 006 ] : 3 ~ 130951
[18:22] Object: [ Read w/ false key 006 ] : 
[18:22] Object: [ Write to not be found ] : 0 ~ 130933
[18:22] Object: [ Read 001 ] : This is a test
[18:22] Object: [ COUNT ] : 5
[18:22] Object: [ LIST ] : NotHere-001 ~ Test-001 ~ Test-004 ~ Test-005 ~ Test-006
[18:22] Object: [ FREE MEM ] : 130933
[18:22] Object: [ COUNT 'Test' ] : 4
[18:22] Object: [ MultiDelete Test ] : 2 ~ 0 ~ 2 ~ 2
[18:22] Object: [ END ] : MARK END
[18:22] Object: [ Event ] : 0 ~  ~ 
[18:22] Object: [ Event ] : 1 ~ Test-001 ~ This is a test
[18:22] Object: [ Event ] : 1 ~ Test-003 ~ 
[18:22] Object: [ Event ] : 2 ~ Test-003 ~ 
[18:22] Object: [ Event ] : 1 ~ Test-004 ~ 
[18:22] Object: [ Event ] : 1 ~ Test-005 ~ 
[18:22] Object: [ Event ] : 1 ~ Test-006 ~ Value
[18:22] Object: [ Event ] : 1 ~ NotHere-001 ~ Testing
[18:22] Object: [ Event ] : 3 ~ Test-004,Test-005 ~ 
[18:22] Object: [ Event ] : 3 ~ Test-001,Test-006 ~ 
[18:22] Object: [ Event ] : 0 ~  ~ 

OpenSim w/Patch

[18:38] Object: [ BEGIN ] : MARK BEGIN
[18:38] Object: [ COUNT ] : 0
[18:38] Object: [ LIST ] : 
[18:38] Object: [ FREE MEM ] : 131072
[18:38] Object: [ Write 001 ] : 0 ~ 131072
[18:38] Object: [ Delete 002 ] : 4 ~ 131050
[18:38] Object: [ Write Protected 003 ] : 0 ~ 131050
[18:38] Object: [ Protection Test ] : 3 ~  ~ Testing
[18:38] Object: [ Delete 003 ] : 3 ~ 131003
[18:38] Object: [ Delete w/ false key 003 ] : 3 ~ 131003
[18:38] Object: [ Delete w/ key 003 ] : 0 ~ 131003
[18:38] Object: [ Write protected 004 ] : 0 ~ 131050
[18:38] Object: [ Write protected 005 ] : 0 ~ 131007
[18:38] Object: [ Write 006 ] : 0 ~ 130964
[18:38] Object: [ Delete w/ false key 006 ] : 3 ~ 130951
[18:38] Object: [ Read w/ false key 006 ] : 
[18:38] Object: [ Write to not be found ] : 0 ~ 130951
[18:38] Object: [ Read 001 ] : This is a test
[18:38] Object: [ COUNT ] : 5
[18:38] Object: [ LIST ] : Test-001 ~ Test-004 ~ Test-005 ~ Test-006 ~ NotHere-001
[18:38] Object: [ FREE MEM ] : 130933
[18:38] Object: [ COUNT 'Test' ] : 4
[18:38] Object: [ MultiDelete Test ] : 2 ~ 0 ~ 2 ~ 2
[18:38] Object: [ END ] : MARK END
[18:38] Object: [ Event ] : 0 ~  ~ 
[18:38] Object: [ Event ] : 1 ~ Test-001 ~ 
[18:38] Object: [ Event ] : 1 ~ Test-003 ~ 
[18:38] Object: [ Event ] : 0 ~ Test-003 ~ 
[18:38] Object: [ Event ] : 1 ~ Test-004 ~ 
[18:38] Object: [ Event ] : 1 ~ Test-005 ~ 
[18:38] Object: [ Event ] : 1 ~ Test-006 ~ 
[18:38] Object: [ Event ] : 1 ~ NotHere-001 ~ 
[18:38] Object: [ Event ] : 3 ~ Test-004,Test-005 ~ 
[18:38] Object: [ Event ] : 3 ~ Test-001,Test-006 ~ 
[18:38] Object: [ Event ] : 0 ~  ~ 
  */
Script
  
S(string name, list X)
{
    llOwnerSay("[ " + name + " ] : "+llDumpList2String(X," ~ "));
}
default
{
    state_entry()
    {
        S("BEGIN", [ "MARK BEGIN" ]);
        llLinksetDataReset();
        
        S("COUNT", [llLinksetDataCountKeys()]);
        S("LIST", llLinksetDataListKeys(0, llLinksetDataCountKeys())); // Should output nothing at this stage
        
        
        S("FREE MEM", [llLinksetDataAvailable()]);
        
        S("Write 001", [llLinksetDataWrite("Test-001", "This is a test"), llLinksetDataAvailable()]);
        S("Delete 002", [llLinksetDataDelete("Test-002"), llLinksetDataAvailable()]); // Outputs 4, not found
        S("Write Protected 003", [llLinksetDataWriteProtected("Test-003", "Testing", "Pass"), llLinksetDataAvailable()]);
        S("Protection Test", [llLinksetDataWriteProtected("Test-003", "Testing", "PassInvalid"), llLinksetDataRead("Test-003"), llLinksetDataReadProtected("Test-003", "Pass")]);
        S("Delete 003", [llLinksetDataDelete("Test-003"), llLinksetDataAvailable()]);
        S("Delete w/ false key 003", [llLinksetDataDeleteProtected("Test-003", "PassInvalid"), llLinksetDataAvailable()]);
        S("Delete w/ key 003", [llLinksetDataDeleteProtected("Test-003", "Pass"), llLinksetDataAvailable()]);
        S("Write protected 004", [llLinksetDataWriteProtected("Test-004","Val", "NoMultiDelete"), llLinksetDataAvailable()]);
        S("Write protected 005", [llLinksetDataWriteProtected("Test-005","Val", "NoMultiDelete"), llLinksetDataAvailable()]);
        
        S("Write 006", [llLinksetDataWrite("Test-006", "Value"), llLinksetDataAvailable()]);
        S("Delete w/ false key 006", [llLinksetDataDeleteProtected("Test-006", "Pass"), llLinksetDataAvailable()]);
        S("Read w/ false key 006", [llLinksetDataReadProtected("Test-006", "Pass")]);
        
        S("Write to not be found", [llLinksetDataWrite("NotHere-001", "Testing"), llLinksetDataAvailable()]);
        
        
        S("Read 001", [llLinksetDataRead("Test-001")]);
        
        S("COUNT", [llLinksetDataCountKeys()]);
        S("LIST", llLinksetDataListKeys(0, llLinksetDataCountKeys()));
        
        S("FREE MEM", [llLinksetDataAvailable()]);
        
        S("COUNT 'Test'", [llLinksetDataCountFound("Test")]);
        S("MultiDelete Test", llLinksetDataDeleteFound("Test", "") + llLinksetDataDeleteFound("Test", "NoMultiDelete")); 
        
        llLinksetDataReset();
        
        S("END", [ "MARK END" ]);
    }
    
    linkset_data(integer action, string K, string V)
    {
        S("Event", [action, K, V]);
    }
}

@zontreck
Copy link

zontreck commented Nov 7, 2023

On further testing, it seems, and this is a separate issue altogether, but SL evaluates statements left to right, and YEngine is evaluating from right to left.

…1 is an indication to return all available. Adjust the code to behave that way. It was originally looking at -1 as an indication to do that.
…ction and Property names are MixedCase with Initial upper case letter. Changed references to empty strings to use string.Empty and tests to use string.IsNullOrEmpty in the LinksetDataEntry data model class.
…phabetic order as required. This is a lightweight list with Dictionary behaviour added. Mark the SOG dirty on operations that change the LinksetData field so persistence is reliable. Rework the support functions to use string.Empty and string.IsNullOrEmpty where needed. Cleaned up what should be the last of the CodeQL comments.
…ld and to serialize/deserialize to/from JSON. We calculate size based on the size of the serialization which means there is a little bit of overhead for each field. We'll also let things go slightly over 128k to simplify the cost accounting but the field we're using can store well beyond 128k so thats not an issue.
…etData field. This way we match more closely SL semantics. We'll still serialize in json text format when writing to the database.
… we iterate the copied list. deleted and not_deleted only apply to matches, not all the entries. Thx to Aria for the review comments.
@mdickson mdickson changed the title Draft: LinkSet Data feature from SL LinkSet Data feature from SL Nov 16, 2023
@mdickson mdickson requested a review from zontreck November 16, 2023 15:41
@mdickson mdickson linked an issue Nov 16, 2023 that may be closed by this pull request
Copy link

@zontreck zontreck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LSL Stub needs to be updated

OpenSim/Data/MySQL/OpenSim.Data.MySQL.csproj Outdated Show resolved Hide resolved
OpenSim/Data/Null/OpenSim.Data.Null.csproj Outdated Show resolved Hide resolved
OpenSim/Data/OpenSim.Data.csproj Outdated Show resolved Hide resolved
OpenSim/Data/PGSQL/OpenSim.Data.PGSQL.csproj Outdated Show resolved Hide resolved
OpenSim/Data/SQLite/OpenSim.Data.SQLite.csproj Outdated Show resolved Hide resolved
zontreck
zontreck previously approved these changes Nov 16, 2023
Copy link

@zontreck zontreck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the possible unneeded using statements are okay, then looks good to me!

Copy link

@zontreck zontreck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@mdickson mdickson merged commit 8c9ccc0 into develop Nov 16, 2023
3 checks passed
@mdickson mdickson deleted the feature/zontreck-linkset-data branch November 16, 2023 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implenent SL LinksetData methods
2 participants