Complete native extension milestone gate (#84)
This commit is contained in:
@@ -15,8 +15,12 @@ on:
|
|||||||
- "tools/check_milestone_10_issue_81.py"
|
- "tools/check_milestone_10_issue_81.py"
|
||||||
- "tools/check_milestone_10_issue_82.py"
|
- "tools/check_milestone_10_issue_82.py"
|
||||||
- "tools/check_milestone_10_issue_83.py"
|
- "tools/check_milestone_10_issue_83.py"
|
||||||
|
- "tools/check_milestone_10.py"
|
||||||
|
- "tools/test_milestone_10.py"
|
||||||
- "tools/generate_lsl_tables.py"
|
- "tools/generate_lsl_tables.py"
|
||||||
- "codegen/inputs/lsl_tools_grammar.json"
|
- "codegen/inputs/lsl_tools_grammar.json"
|
||||||
|
- "docs/extension-milestone-gate.md"
|
||||||
|
- "api/SHIM-COVERAGE.md"
|
||||||
- "**/*.rs"
|
- "**/*.rs"
|
||||||
- "**/Cargo.toml"
|
- "**/Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
@@ -34,8 +38,12 @@ on:
|
|||||||
- "tools/check_milestone_10_issue_81.py"
|
- "tools/check_milestone_10_issue_81.py"
|
||||||
- "tools/check_milestone_10_issue_82.py"
|
- "tools/check_milestone_10_issue_82.py"
|
||||||
- "tools/check_milestone_10_issue_83.py"
|
- "tools/check_milestone_10_issue_83.py"
|
||||||
|
- "tools/check_milestone_10.py"
|
||||||
|
- "tools/test_milestone_10.py"
|
||||||
- "tools/generate_lsl_tables.py"
|
- "tools/generate_lsl_tables.py"
|
||||||
- "codegen/inputs/lsl_tools_grammar.json"
|
- "codegen/inputs/lsl_tools_grammar.json"
|
||||||
|
- "docs/extension-milestone-gate.md"
|
||||||
|
- "api/SHIM-COVERAGE.md"
|
||||||
- "**/*.rs"
|
- "**/*.rs"
|
||||||
- "**/Cargo.toml"
|
- "**/Cargo.toml"
|
||||||
- "Cargo.lock"
|
- "Cargo.lock"
|
||||||
@@ -48,11 +56,15 @@ jobs:
|
|||||||
OPENJPEG_PREFIX: /tmp/metacrate-openjpeg-${{ github.run_id }}
|
OPENJPEG_PREFIX: /tmp/metacrate-openjpeg-${{ github.run_id }}
|
||||||
PKG_CONFIG_PATH: /tmp/metacrate-openjpeg-${{ github.run_id }}/lib/pkgconfig
|
PKG_CONFIG_PATH: /tmp/metacrate-openjpeg-${{ github.run_id }}/lib/pkgconfig
|
||||||
LD_LIBRARY_PATH: /tmp/metacrate-openjpeg-${{ github.run_id }}/lib
|
LD_LIBRARY_PATH: /tmp/metacrate-openjpeg-${{ github.run_id }}/lib
|
||||||
|
CARGO_BUILD_JOBS: 1
|
||||||
|
CARGO_INCREMENTAL: 0
|
||||||
|
CARGO_PROFILE_DEV_DEBUG: 0
|
||||||
|
CARGO_PROFILE_TEST_DEBUG: 0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
components: rustfmt
|
components: rustfmt, clippy
|
||||||
- name: Install audited OpenJPEG 2.5.4
|
- name: Install audited OpenJPEG 2.5.4
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -80,7 +92,16 @@ jobs:
|
|||||||
python3 tools/check_milestone_10_issue_82.py
|
python3 tools/check_milestone_10_issue_82.py
|
||||||
python3 tools/check_milestone_10_issue_83.py
|
python3 tools/check_milestone_10_issue_83.py
|
||||||
python3 tools/generate_lsl_tables.py --check
|
python3 tools/generate_lsl_tables.py --check
|
||||||
|
python3 tools/check_milestone_10.py
|
||||||
- name: Test the complete native world milestone
|
- name: Test the complete native world milestone
|
||||||
run: python3 tools/test_milestone_09.py
|
run: python3 tools/test_milestone_09.py
|
||||||
|
- name: Test the complete native extension milestone
|
||||||
|
run: python3 tools/test_milestone_10.py
|
||||||
- name: Compile every workspace target with bounded memory
|
- name: Compile every workspace target with bounded memory
|
||||||
run: cargo check --workspace --all-targets --locked -j 1
|
run: cargo check --workspace --all-targets --locked -j 1
|
||||||
|
- name: Lint every native extension target with bounded memory
|
||||||
|
run: cargo clippy -p libremetaverse-rendering-simple -p libremetaverse-rendering-mesh-foundry -p libremetaverse-rlv -p libremetaverse-lsl-tools --all-targets --locked -j 1 -- -D warnings
|
||||||
|
- name: Document every native extension crate
|
||||||
|
env:
|
||||||
|
RUSTDOCFLAGS: -D warnings
|
||||||
|
run: cargo doc -p libremetaverse-rendering-simple -p libremetaverse-rendering-mesh-foundry -p libremetaverse-rlv -p libremetaverse-lsl-tools --no-deps --locked -j 1
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Generated by `python3 tools/generate_api_shims.py`; do not edit by hand.
|
|||||||
| `LibreMetaverse.Imaging.Skia` | 1 | 3 | native implementation: 1 type / 3 members; no generated shims remain |
|
| `LibreMetaverse.Imaging.Skia` | 1 | 3 | native implementation: 1 type / 3 members; no generated shims remain |
|
||||||
| `LibreMetaverse.LslTools` | 164 | 768 | native implementation: 164 types / 768 members; no generated shims remain |
|
| `LibreMetaverse.LslTools` | 164 | 768 | native implementation: 164 types / 768 members; no generated shims remain |
|
||||||
| `LibreMetaverse.PrimMesher` | 17 | 207 | native implementation: 15 types / 200 members; remaining surface is callable failure-only shims |
|
| `LibreMetaverse.PrimMesher` | 17 | 207 | native implementation: 15 types / 200 members; remaining surface is callable failure-only shims |
|
||||||
| `LibreMetaverse.RLV` | 28 | 499 | native implementation: 17 types / 200 members; remaining surface is callable failure-only shims |
|
| `LibreMetaverse.RLV` | 28 | 499 | native implementation: 28 types / 499 members; no generated shims remain |
|
||||||
| `LibreMetaverse.Rendering.MeshFoundry` | 1 | 14 | native implementation: 1 type / 14 members; no generated shims remain |
|
| `LibreMetaverse.Rendering.MeshFoundry` | 1 | 14 | native implementation: 1 type / 14 members; no generated shims remain |
|
||||||
| `LibreMetaverse.Rendering.Simple` | 1 | 6 | native implementation: 1 type / 6 members; no generated shims remain |
|
| `LibreMetaverse.Rendering.Simple` | 1 | 6 | native implementation: 1 type / 6 members; no generated shims remain |
|
||||||
| `LibreMetaverse.StructuredData` | 16 | 295 | native implementation: 16 types / 295 members; no generated shims remain |
|
| `LibreMetaverse.StructuredData` | 16 | 295 | native implementation: 16 types / 295 members; no generated shims remain |
|
||||||
|
|||||||
@@ -131,188 +131,90 @@ pub trait IRlvActionCallbacks: Send + Sync {
|
|||||||
factor: f32,
|
factor: f32,
|
||||||
delta: f32,
|
delta: f32,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.AdjustHeightAsync(System.Single,System.Single,System.Single,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.AttachAsync(System.Collections.Generic.IReadOnlyList{LibreMetaverse.RLV.AttachmentRequest},System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.AttachAsync(System.Collections.Generic.IReadOnlyList{LibreMetaverse.RLV.AttachmentRequest},System.Threading.CancellationToken)`.
|
||||||
fn attach(
|
fn attach(
|
||||||
&self,
|
&self,
|
||||||
items_to_attach: Vec<libremetaverse_rlv::AttachmentRequest>,
|
items_to_attach: Vec<libremetaverse_rlv::AttachmentRequest>,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.AttachAsync(System.Collections.Generic.IReadOnlyList{LibreMetaverse.RLV.AttachmentRequest},System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.DetachAsync(System.Collections.Generic.IReadOnlyList{System.Guid},System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.DetachAsync(System.Collections.Generic.IReadOnlyList{System.Guid},System.Threading.CancellationToken)`.
|
||||||
fn detach(
|
fn detach(
|
||||||
&self,
|
&self,
|
||||||
item_ids: Vec<libremetaverse_types::compat::Guid>,
|
item_ids: Vec<libremetaverse_types::compat::Guid>,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.DetachAsync(System.Collections.Generic.IReadOnlyList{System.Guid},System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.RemOutfitAsync(System.Collections.Generic.IReadOnlyList{System.Guid},System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.RemOutfitAsync(System.Collections.Generic.IReadOnlyList{System.Guid},System.Threading.CancellationToken)`.
|
||||||
fn rem_outfit(
|
fn rem_outfit(
|
||||||
&self,
|
&self,
|
||||||
item_ids: Vec<libremetaverse_types::compat::Guid>,
|
item_ids: Vec<libremetaverse_types::compat::Guid>,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.RemOutfitAsync(System.Collections.Generic.IReadOnlyList{System.Guid},System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SendInstantMessageAsync(System.Guid,System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SendInstantMessageAsync(System.Guid,System.String,System.Threading.CancellationToken)`.
|
||||||
fn send_instant_message(
|
fn send_instant_message(
|
||||||
&self,
|
&self,
|
||||||
target_user: libremetaverse_types::compat::Guid,
|
target_user: libremetaverse_types::compat::Guid,
|
||||||
message: String,
|
message: String,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SendInstantMessageAsync(System.Guid,System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SendReplyAsync(System.Int32,System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SendReplyAsync(System.Int32,System.String,System.Threading.CancellationToken)`.
|
||||||
fn send_reply(
|
fn send_reply(
|
||||||
&self,
|
&self,
|
||||||
channel: i32,
|
channel: i32,
|
||||||
message: String,
|
message: String,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SendReplyAsync(System.Int32,System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetCamFOVAsync(System.Single,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetCamFOVAsync(System.Single,System.Threading.CancellationToken)`.
|
||||||
fn set_cam_fov(
|
fn set_cam_fov(
|
||||||
&self,
|
&self,
|
||||||
fov_in_radians: f32,
|
fov_in_radians: f32,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SetCamFOVAsync(System.Single,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetDebugAsync(System.String,System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetDebugAsync(System.String,System.String,System.Threading.CancellationToken)`.
|
||||||
fn set_debug(
|
fn set_debug(
|
||||||
&self,
|
&self,
|
||||||
setting_name: String,
|
setting_name: String,
|
||||||
setting_value: String,
|
setting_value: String,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SetDebugAsync(System.String,System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetEnvAsync(System.String,System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetEnvAsync(System.String,System.String,System.Threading.CancellationToken)`.
|
||||||
fn set_env(
|
fn set_env(
|
||||||
&self,
|
&self,
|
||||||
setting_name: String,
|
setting_name: String,
|
||||||
setting_value: String,
|
setting_value: String,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SetEnvAsync(System.String,System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetGroupAsync(System.Guid,System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetGroupAsync(System.Guid,System.String,System.Threading.CancellationToken)`.
|
||||||
fn set_group_with_guid_string_cancellation_token(
|
fn set_group_with_guid_string_cancellation_token(
|
||||||
&self,
|
&self,
|
||||||
group_id: libremetaverse_types::compat::Guid,
|
group_id: libremetaverse_types::compat::Guid,
|
||||||
role_name: Option<String>,
|
role_name: Option<String>,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SetGroupAsync(System.Guid,System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetGroupAsync(System.String,System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetGroupAsync(System.String,System.String,System.Threading.CancellationToken)`.
|
||||||
fn set_group_with_string_string_cancellation_token(
|
fn set_group_with_string_string_cancellation_token(
|
||||||
&self,
|
&self,
|
||||||
group_name: String,
|
group_name: String,
|
||||||
role_name: Option<String>,
|
role_name: Option<String>,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SetGroupAsync(System.String,System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetRotAsync(System.Single,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SetRotAsync(System.Single,System.Threading.CancellationToken)`.
|
||||||
fn set_rot(
|
fn set_rot(
|
||||||
&self,
|
&self,
|
||||||
angle_in_radians: f32,
|
angle_in_radians: f32,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SetRotAsync(System.Single,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SitAsync(System.Guid,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SitAsync(System.Guid,System.Threading.CancellationToken)`.
|
||||||
fn sit(
|
fn sit(
|
||||||
&self,
|
&self,
|
||||||
target: libremetaverse_types::compat::Guid,
|
target: libremetaverse_types::compat::Guid,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SitAsync(System.Guid,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SitGroundAsync(System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.SitGroundAsync(System.Threading.CancellationToken)`.
|
||||||
fn sit_ground(
|
fn sit_ground(
|
||||||
&self,
|
&self,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.SitGroundAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.TpToAsync(System.Single,System.Single,System.Single,System.String,System.Nullable{System.Single},System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.TpToAsync(System.Single,System.Single,System.Single,System.String,System.Nullable{System.Single},System.Threading.CancellationToken)`.
|
||||||
fn tp_to(
|
fn tp_to(
|
||||||
&self,
|
&self,
|
||||||
@@ -322,26 +224,12 @@ pub trait IRlvActionCallbacks: Send + Sync {
|
|||||||
region_name: Option<String>,
|
region_name: Option<String>,
|
||||||
lookat: Option<Option<f32>>,
|
lookat: Option<Option<f32>>,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.TpToAsync(System.Single,System.Single,System.Single,System.String,System.Nullable{System.Single},System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.UnsitAsync(System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvActionCallbacks.UnsitAsync(System.Threading.CancellationToken)`.
|
||||||
fn unsit(
|
fn unsit(
|
||||||
&self,
|
&self,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvActionCallbacks.UnsitAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// C# type: `T:LibreMetaverse.RLV.IRlvQueryCallbacks`.
|
/// C# type: `T:LibreMetaverse.RLV.IRlvQueryCallbacks`.
|
||||||
@@ -350,40 +238,20 @@ pub trait IRlvQueryCallbacks: Send + Sync {
|
|||||||
fn is_sitting(
|
fn is_sitting(
|
||||||
&self,
|
&self,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<bool, crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<bool, crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.IsSittingAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.ObjectExistsAsync(System.Guid,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.ObjectExistsAsync(System.Guid,System.Threading.CancellationToken)`.
|
||||||
fn object_exists(
|
fn object_exists(
|
||||||
&self,
|
&self,
|
||||||
object_id: libremetaverse_types::compat::Guid,
|
object_id: libremetaverse_types::compat::Guid,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<bool, crate::Error>> + Send + '_>>
|
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<bool, crate::Error>> + Send + '_>>;
|
||||||
{
|
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.ObjectExistsAsync(System.Guid,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetActiveGroupNameAsync(System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetActiveGroupNameAsync(System.Threading.CancellationToken)`.
|
||||||
fn try_get_active_group_name(
|
fn try_get_active_group_name(
|
||||||
&self,
|
&self,
|
||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<
|
) -> std::pin::Pin<
|
||||||
Box<dyn std::future::Future<Output = Result<(bool, String), crate::Error>> + Send + '_>,
|
Box<dyn std::future::Future<Output = Result<(bool, String), crate::Error>> + Send + '_>,
|
||||||
> {
|
>;
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetActiveGroupNameAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetCameraSettingsAsync(System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetCameraSettingsAsync(System.Threading.CancellationToken)`.
|
||||||
fn try_get_camera_settings(
|
fn try_get_camera_settings(
|
||||||
&self,
|
&self,
|
||||||
@@ -398,13 +266,7 @@ pub trait IRlvQueryCallbacks: Send + Sync {
|
|||||||
> + Send
|
> + Send
|
||||||
+ '_,
|
+ '_,
|
||||||
>,
|
>,
|
||||||
> {
|
>;
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetCameraSettingsAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetDebugSettingValueAsync(System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetDebugSettingValueAsync(System.String,System.Threading.CancellationToken)`.
|
||||||
fn try_get_debug_setting_value(
|
fn try_get_debug_setting_value(
|
||||||
&self,
|
&self,
|
||||||
@@ -412,13 +274,7 @@ pub trait IRlvQueryCallbacks: Send + Sync {
|
|||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<
|
) -> std::pin::Pin<
|
||||||
Box<dyn std::future::Future<Output = Result<(bool, String), crate::Error>> + Send + '_>,
|
Box<dyn std::future::Future<Output = Result<(bool, String), crate::Error>> + Send + '_>,
|
||||||
> {
|
>;
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetDebugSettingValueAsync(System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetEnvironmentSettingValueAsync(System.String,System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetEnvironmentSettingValueAsync(System.String,System.Threading.CancellationToken)`.
|
||||||
fn try_get_environment_setting_value(
|
fn try_get_environment_setting_value(
|
||||||
&self,
|
&self,
|
||||||
@@ -426,13 +282,7 @@ pub trait IRlvQueryCallbacks: Send + Sync {
|
|||||||
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
cancellation_token: libremetaverse_types::compat::CancellationToken,
|
||||||
) -> std::pin::Pin<
|
) -> std::pin::Pin<
|
||||||
Box<dyn std::future::Future<Output = Result<(bool, String), crate::Error>> + Send + '_>,
|
Box<dyn std::future::Future<Output = Result<(bool, String), crate::Error>> + Send + '_>,
|
||||||
> {
|
>;
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetEnvironmentSettingValueAsync(System.String,System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetInventoryMapAsync(System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetInventoryMapAsync(System.Threading.CancellationToken)`.
|
||||||
fn try_get_inventory_map(
|
fn try_get_inventory_map(
|
||||||
&self,
|
&self,
|
||||||
@@ -444,13 +294,7 @@ pub trait IRlvQueryCallbacks: Send + Sync {
|
|||||||
> + Send
|
> + Send
|
||||||
+ '_,
|
+ '_,
|
||||||
>,
|
>,
|
||||||
> {
|
>;
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetInventoryMapAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetSitIdAsync(System.Threading.CancellationToken)`.
|
/// C# member: `M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetSitIdAsync(System.Threading.CancellationToken)`.
|
||||||
fn try_get_sit_id(
|
fn try_get_sit_id(
|
||||||
&self,
|
&self,
|
||||||
@@ -462,13 +306,7 @@ pub trait IRlvQueryCallbacks: Send + Sync {
|
|||||||
> + Send
|
> + Send
|
||||||
+ '_,
|
+ '_,
|
||||||
>,
|
>,
|
||||||
> {
|
>;
|
||||||
Box::pin(async {
|
|
||||||
libremetaverse_types::not_implemented(
|
|
||||||
"M:LibreMetaverse.RLV.IRlvQueryCallbacks.TryGetSitIdAsync(System.Threading.CancellationToken)",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// C# type: `T:LibreMetaverse.RLV.InventoryMap`.
|
/// C# type: `T:LibreMetaverse.RLV.InventoryMap`.
|
||||||
|
|||||||
113
docs/extension-milestone-gate.md
Normal file
113
docs/extension-milestone-gate.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# Rendering, RLV, and LSL extension gate
|
||||||
|
|
||||||
|
Milestone 10 replaces the pinned rendering, Restrained Love Viewer, and LSL
|
||||||
|
tooling assemblies with native Rust. The four extension crates are normal
|
||||||
|
workspace dependencies with no opt-in compatibility feature: adding one of
|
||||||
|
them selects its Rust implementation on every supported platform. None loads
|
||||||
|
a CLR assembly, starts a .NET process, or delegates to a platform-only API.
|
||||||
|
|
||||||
|
## Choosing an extension
|
||||||
|
|
||||||
|
| Previous C# assembly | Rust crate | Primary entry points |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `LibreMetaverse.Rendering.Simple` | `libremetaverse-rendering-simple` | `SimpleRenderer`, `IRendering` |
|
||||||
|
| `LibreMetaverse.Rendering.MeshFoundry` | `libremetaverse-rendering-mesh-foundry` | `MeshFoundry`, `IRendering`, `MeshFaceAux` |
|
||||||
|
| `LibreMetaverse.RLV` | `libremetaverse-rlv` | `RlvService`, `RlvPermissionsService`, callback traits |
|
||||||
|
| `LibreMetaverse.LslTools` | `libremetaverse-lsl-tools` | `Lexer`, `Parser`, `Grammar`, generated tables |
|
||||||
|
|
||||||
|
The mapped PascalCase C# surface remains represented in the API ledger, while
|
||||||
|
the callable Rust names follow the workspace's snake-case mapping. New code
|
||||||
|
should use owned Rust values and `Result` instead of nullable CLR containers or
|
||||||
|
exceptions. `api/SHIM-COVERAGE.md` is generated evidence that all 194 types and
|
||||||
|
1,287 members in these four assemblies are native; the milestone audit rejects
|
||||||
|
an owned `not_implemented`, `unimplemented_api`, `todo!`, or `unimplemented!`.
|
||||||
|
|
||||||
|
## Rendering migration
|
||||||
|
|
||||||
|
Both renderers consume the native core `Primitive` and common `IRendering`
|
||||||
|
types. Use `SimpleRenderer` for prim and decoded sculpt geometry. Use
|
||||||
|
`MeshFoundry` when an LLSD mesh asset, skin weights, secondary UVs, tangents,
|
||||||
|
terrain, or physics hulls are required. Both keep coordinates prim-local; the
|
||||||
|
world service remains responsible for object transforms, asset retrieval, and
|
||||||
|
scene ownership.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
use libremetaverse::Primitive;
|
||||||
|
use libremetaverse::rendering::{DetailLevel, IRendering};
|
||||||
|
use libremetaverse_rendering_simple::SimpleRenderer;
|
||||||
|
|
||||||
|
fn render(primitive: Primitive) -> Result<usize, libremetaverse_types::Error> {
|
||||||
|
let renderer = SimpleRenderer::new()?;
|
||||||
|
Ok(renderer
|
||||||
|
.generate_simple_mesh(primitive, DetailLevel::High)?
|
||||||
|
.indices
|
||||||
|
.len())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Inputs are bounded before allocation: a face stays in the 16-bit index domain,
|
||||||
|
and MeshFoundry caps encoded/decompressed assets, sections, total geometry,
|
||||||
|
joints, and convex data. Rendering is deterministic and performs no network,
|
||||||
|
GPU, window-system, or callback work.
|
||||||
|
|
||||||
|
## RLV host integration and teardown
|
||||||
|
|
||||||
|
`RlvService` separates deterministic protocol/state handling from world side
|
||||||
|
effects. A host implements every required method of `IRlvQueryCallbacks` and
|
||||||
|
`IRlvActionCallbacks`, then passes owned trait objects to `RlvService::new`.
|
||||||
|
There are no generated fallback methods: an incomplete adapter fails to
|
||||||
|
compile. `RlvCallbacksDefault` and `RlvActionCallbacksDefault` are complete,
|
||||||
|
cancellation-aware adapters for hosts that intentionally use conservative
|
||||||
|
query values and no-op actions.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
use libremetaverse_rlv::{RlvActionCallbacksDefault, RlvCallbacksDefault, RlvService};
|
||||||
|
|
||||||
|
fn service() -> Result<RlvService, libremetaverse_types::Error> {
|
||||||
|
RlvService::new(
|
||||||
|
Box::new(RlvCallbacksDefault::new()?),
|
||||||
|
Box::new(RlvActionCallbacksDefault::new()?),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Core/world adapters should snapshot manager data before returning a future and
|
||||||
|
perform network actions through the corresponding manager APIs. The RLV crate
|
||||||
|
releases its locks before awaiting a callback, checks cancellation between
|
||||||
|
commands, bounds each message to 64 KiB and 128 commands, and never starts a
|
||||||
|
background task. Drop event `Subscription` guards when a host shuts down; drop
|
||||||
|
the service and its callback objects after outstanding host futures complete.
|
||||||
|
|
||||||
|
## LSL tooling migration
|
||||||
|
|
||||||
|
Use `generated_lexer()` and `generated_parser()` for the reviewed checked-in
|
||||||
|
grammar, or build typed `Dfa` and `Grammar` values for another language. Source
|
||||||
|
locations use UTF-16 code units to preserve the mapped contract. Generation is
|
||||||
|
an explicit development operation; parsing never generates or compiles code at
|
||||||
|
runtime.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
use libremetaverse_lsl_tools::{Lexer, Parser, generated_lexer, generated_parser};
|
||||||
|
|
||||||
|
fn parse(source: String) -> Result<String, libremetaverse_types::Error> {
|
||||||
|
let lexer = Lexer::new(generated_lexer()?)?;
|
||||||
|
let mut parser = Parser::new(generated_parser()?, lexer)?;
|
||||||
|
Ok(parser.parse_with_string(source)?.yyname())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Source, token, DFA, parser-state, stack, operation, recovery, and generator
|
||||||
|
sizes have fixed limits. The checked table is reproducible with
|
||||||
|
`python3 tools/generate_lsl_tables.py --check`; API generation is checked with
|
||||||
|
`python3 tools/generate_api_shims.py --check`.
|
||||||
|
|
||||||
|
## Complete milestone verification
|
||||||
|
|
||||||
|
`python3 tools/check_milestone_10.py` audits native ownership, reviewed parity
|
||||||
|
metadata, deterministic generation, resource limits, integration evidence,
|
||||||
|
migration documentation, and the ubuntu-only workflow. Run
|
||||||
|
`python3 tools/test_milestone_10.py` to execute the four crate suites, all 616
|
||||||
|
reviewed RLV compatibility cases, rendering compatibility, the cross-extension
|
||||||
|
core/world integration, and the compile-only mapped API fixture. The workflow
|
||||||
|
runs these gates on `ubuntu-latest`.
|
||||||
@@ -67,10 +67,7 @@ fn extension_flows_have_typed_callable_signatures() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn extension_constructors_have_expected_native_or_failure_behavior() {
|
fn extension_constructors_have_expected_native_or_failure_behavior() {
|
||||||
assert!(YyParser::new().is_ok());
|
assert!(YyParser::new().is_ok());
|
||||||
assert_eq!(
|
assert!(RlvActionCallbacksDefault::new().is_ok());
|
||||||
member_id(RlvActionCallbacksDefault::new()),
|
|
||||||
"M:LibreMetaverse.RLV.RlvActionCallbacksDefault.#ctor"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
member_id(TCPPipe::new()),
|
member_id(TCPPipe::new()),
|
||||||
"M:LibreMetaverse.Voice.Vivox.TCPPipe.#ctor"
|
"M:LibreMetaverse.Voice.Vivox.TCPPipe.#ctor"
|
||||||
|
|||||||
80
tests/compat/tests/milestone_10_integration.rs
Normal file
80
tests/compat/tests/milestone_10_integration.rs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
//! Milestone 10 integration coverage across core primitives and native extensions.
|
||||||
|
|
||||||
|
use libremetaverse::rendering::{DetailLevel, SimpleMesh};
|
||||||
|
use libremetaverse::{Primitive, PrimitiveConstructionData};
|
||||||
|
use libremetaverse_compat_tests::block_on;
|
||||||
|
use libremetaverse_compat_tests::rlv_support::RlvHarness;
|
||||||
|
use libremetaverse_lsl_tools::{Lexer, Parser, generated_lexer, generated_parser};
|
||||||
|
use libremetaverse_rendering_mesh_foundry::MeshFoundry;
|
||||||
|
use libremetaverse_rendering_simple::SimpleRenderer;
|
||||||
|
use libremetaverse_types::{HoleType, PCode, PathCurve, ProfileCurve};
|
||||||
|
|
||||||
|
fn world_primitive() -> Primitive {
|
||||||
|
let mut primitive = Primitive::new_with_constructor().expect("Primitive constructor");
|
||||||
|
let mut construction = PrimitiveConstructionData::new_with_constructor()
|
||||||
|
.expect("PrimitiveConstructionData constructor");
|
||||||
|
construction.p_code = PCode::Prim;
|
||||||
|
construction.path_curve = PathCurve::Line;
|
||||||
|
construction.set_profile_curve_with_property(ProfileCurve::Square);
|
||||||
|
construction.set_profile_hole(HoleType::Same);
|
||||||
|
construction.path_scale_x = 1.0;
|
||||||
|
construction.path_scale_y = 1.0;
|
||||||
|
construction.path_end = 1.0;
|
||||||
|
construction.profile_end = 1.0;
|
||||||
|
construction.path_revolutions = 1.0;
|
||||||
|
primitive.prim_data = construction;
|
||||||
|
primitive
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mesh_signature(mesh: &SimpleMesh) -> u64 {
|
||||||
|
let mut hash = 0xcbf2_9ce4_8422_2325_u64;
|
||||||
|
for vertex in &mesh.vertices {
|
||||||
|
for value in [
|
||||||
|
vertex.position.x,
|
||||||
|
vertex.position.y,
|
||||||
|
vertex.position.z,
|
||||||
|
vertex.normal.x,
|
||||||
|
vertex.normal.y,
|
||||||
|
vertex.normal.z,
|
||||||
|
vertex.tex_coord.x,
|
||||||
|
vertex.tex_coord.y,
|
||||||
|
] {
|
||||||
|
hash = (hash ^ u64::from(value.to_bits())).wrapping_mul(0x0000_0100_0000_01b3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hash
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn native_extensions_consume_core_models_and_preserve_service_state() {
|
||||||
|
let primitive = world_primitive();
|
||||||
|
let simple = SimpleRenderer::new()
|
||||||
|
.expect("simple renderer")
|
||||||
|
.generate_simple_mesh(primitive.clone(), DetailLevel::High)
|
||||||
|
.expect("simple mesh");
|
||||||
|
let foundry = MeshFoundry::new()
|
||||||
|
.expect("mesh foundry")
|
||||||
|
.generate_simple_mesh(primitive, DetailLevel::High)
|
||||||
|
.expect("foundry mesh")
|
||||||
|
.expect("legacy primitive is renderable");
|
||||||
|
assert_eq!(simple.vertices.len(), foundry.vertices.len());
|
||||||
|
assert_eq!(mesh_signature(&simple), mesh_signature(&foundry));
|
||||||
|
assert_eq!(simple.indices, foundry.indices);
|
||||||
|
|
||||||
|
let lexer = Lexer::new(generated_lexer().expect("generated lexer")).expect("lexer");
|
||||||
|
let mut parser =
|
||||||
|
Parser::new(generated_parser().expect("generated parser"), lexer).expect("parser");
|
||||||
|
let symbol = parser
|
||||||
|
.parse_with_string("Widget(value;):base(new Child[])".to_owned())
|
||||||
|
.expect("generated class body");
|
||||||
|
assert_eq!(
|
||||||
|
(symbol.yyname(), symbol.yynum()),
|
||||||
|
("ClassBody".to_owned(), 19)
|
||||||
|
);
|
||||||
|
|
||||||
|
let rlv = RlvHarness::new().expect("RLV service");
|
||||||
|
assert!(block_on(rlv.process("@fly=n")).expect("add restriction"));
|
||||||
|
assert!(!rlv.service.permissions().can_fly().expect("permission"));
|
||||||
|
assert!(block_on(rlv.process("@fly=y")).expect("remove restriction"));
|
||||||
|
assert!(rlv.service.permissions().can_fly().expect("permission"));
|
||||||
|
}
|
||||||
252
tools/check_milestone_10.py
Normal file
252
tools/check_milestone_10.py
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Audit the complete native rendering, RLV, and LSL milestone boundary."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import generate_api_shims
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
ASSEMBLIES = {
|
||||||
|
"LibreMetaverse.Rendering.Simple": (1, 6),
|
||||||
|
"LibreMetaverse.Rendering.MeshFoundry": (1, 14),
|
||||||
|
"LibreMetaverse.RLV": (28, 499),
|
||||||
|
"LibreMetaverse.LslTools": (164, 768),
|
||||||
|
}
|
||||||
|
CRATES = (
|
||||||
|
"libremetaverse-rendering-simple",
|
||||||
|
"libremetaverse-rendering-mesh-foundry",
|
||||||
|
"libremetaverse-rlv",
|
||||||
|
"libremetaverse-lsl-tools",
|
||||||
|
)
|
||||||
|
RLV_GENERATED_TYPES = {
|
||||||
|
"T:LibreMetaverse.RLV.IRlvActionCallbacks",
|
||||||
|
"T:LibreMetaverse.RLV.IRlvQueryCallbacks",
|
||||||
|
"T:LibreMetaverse.RLV.RlvAttachmentPoint",
|
||||||
|
"T:LibreMetaverse.RLV.RlvGestureState",
|
||||||
|
"T:LibreMetaverse.RLV.RlvGetDebugType",
|
||||||
|
"T:LibreMetaverse.RLV.RlvGetEnvType",
|
||||||
|
"T:LibreMetaverse.RLV.RlvPermissionsService.HoverTextLocation",
|
||||||
|
"T:LibreMetaverse.RLV.RlvPermissionsService.ObjectLocation",
|
||||||
|
"T:LibreMetaverse.RLV.RlvPermissionsService.TouchLocation",
|
||||||
|
"T:LibreMetaverse.RLV.RlvRestrictionType",
|
||||||
|
"T:LibreMetaverse.RLV.RlvWearableType",
|
||||||
|
}
|
||||||
|
STUB_RE = re.compile(
|
||||||
|
r"\b(?:not_implemented|unimplemented_api)\b|\b(?:todo|unimplemented)!\s*\("
|
||||||
|
)
|
||||||
|
PLATFORM_RE = re.compile(r"unsafe\s*\{|unsafe\s+impl|target_os\s*=\s*\"macos\"")
|
||||||
|
|
||||||
|
|
||||||
|
def require_markers(path: Path, markers: tuple[str, ...]) -> None:
|
||||||
|
text = path.read_text()
|
||||||
|
missing = [marker for marker in markers if marker not in text]
|
||||||
|
if missing:
|
||||||
|
raise SystemExit(f"{path}: audit evidence missing: " + ", ".join(missing))
|
||||||
|
|
||||||
|
|
||||||
|
def catalog_assemblies() -> dict[str, dict]:
|
||||||
|
catalog = json.loads((ROOT / "api" / "public-api.json").read_text())
|
||||||
|
return {assembly["identity"]["name"]: assembly for assembly in catalog["assemblies"]}
|
||||||
|
|
||||||
|
|
||||||
|
def member_is_native(item: dict, member: dict) -> bool:
|
||||||
|
doc_id = item["doc_id"]
|
||||||
|
return (
|
||||||
|
doc_id in generate_api_shims.NATIVE_TYPES
|
||||||
|
or doc_id in generate_api_shims.NATIVE_GENERATED_TYPES
|
||||||
|
or (
|
||||||
|
doc_id in generate_api_shims.NATIVE_DECLARATIONS
|
||||||
|
and member["kind"] in {"field", "constant"}
|
||||||
|
)
|
||||||
|
or generate_api_shims.native_member_body(member["doc_id"]) is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_catalog_ownership() -> None:
|
||||||
|
assemblies = catalog_assemblies()
|
||||||
|
native_types = (
|
||||||
|
set(generate_api_shims.NATIVE_TYPES)
|
||||||
|
| set(generate_api_shims.NATIVE_DECLARATIONS)
|
||||||
|
| set(generate_api_shims.NATIVE_GENERATED_TYPES)
|
||||||
|
)
|
||||||
|
for name, expected in ASSEMBLIES.items():
|
||||||
|
assembly = assemblies[name]
|
||||||
|
actual = (
|
||||||
|
len(assembly["types"]),
|
||||||
|
sum(len(item["members"]) for item in assembly["types"]),
|
||||||
|
)
|
||||||
|
if actual != expected:
|
||||||
|
raise SystemExit(f"{name}: expected catalog counts {expected}, found {actual}")
|
||||||
|
missing_types = [
|
||||||
|
item["doc_id"] for item in assembly["types"] if item["doc_id"] not in native_types
|
||||||
|
]
|
||||||
|
missing_members = [
|
||||||
|
member["doc_id"]
|
||||||
|
for item in assembly["types"]
|
||||||
|
for member in item["members"]
|
||||||
|
if not member_is_native(item, member)
|
||||||
|
]
|
||||||
|
if missing_types or missing_members:
|
||||||
|
raise SystemExit(
|
||||||
|
f"{name}: non-native types={missing_types}, members={missing_members}"
|
||||||
|
)
|
||||||
|
if generate_api_shims.NATIVE_GENERATED_TYPES != RLV_GENERATED_TYPES:
|
||||||
|
raise SystemExit("milestone 10 generated-native RLV declaration set changed")
|
||||||
|
|
||||||
|
|
||||||
|
def check_sources_and_manifests() -> None:
|
||||||
|
offenders: list[str] = []
|
||||||
|
platform_offenders: list[str] = []
|
||||||
|
for crate in CRATES:
|
||||||
|
crate_root = ROOT / "crates" / crate
|
||||||
|
manifest = (crate_root / "Cargo.toml").read_text()
|
||||||
|
if "[features]" in manifest:
|
||||||
|
raise SystemExit(f"{crate}: native implementation must be active without a feature")
|
||||||
|
if re.search(r"\b(?:dotnet|csc|mcs)\b", manifest, re.IGNORECASE):
|
||||||
|
raise SystemExit(f"{crate}: manifest depends on a C#/.NET tool")
|
||||||
|
for source in (crate_root / "src").glob("*.rs"):
|
||||||
|
text = source.read_text()
|
||||||
|
if STUB_RE.search(text):
|
||||||
|
offenders.append(str(source.relative_to(ROOT)))
|
||||||
|
if PLATFORM_RE.search(text):
|
||||||
|
platform_offenders.append(str(source.relative_to(ROOT)))
|
||||||
|
if offenders:
|
||||||
|
raise SystemExit("milestone 10 owned Rust stubs remain: " + ", ".join(offenders))
|
||||||
|
if platform_offenders:
|
||||||
|
raise SystemExit(
|
||||||
|
"milestone 10 unsafe or macOS-only sources remain: "
|
||||||
|
+ ", ".join(platform_offenders)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_parity() -> None:
|
||||||
|
catalog = json.loads((ROOT / "tests" / "upstream-tests.json").read_text())
|
||||||
|
related = [
|
||||||
|
test
|
||||||
|
for test in catalog["tests"]
|
||||||
|
if test["source"].startswith("LibreMetaverse.Tests/RLV/")
|
||||||
|
or test["source"].startswith("LibreMetaverse.Rendering.Tests/")
|
||||||
|
]
|
||||||
|
if len(related) != 691:
|
||||||
|
raise SystemExit(f"milestone 10 expected 691 upstream parity cases, found {len(related)}")
|
||||||
|
bad = [
|
||||||
|
test["id"]
|
||||||
|
for test in related
|
||||||
|
if test["status"] != "translated" or test.get("semantic_review") != "reviewed"
|
||||||
|
]
|
||||||
|
if bad:
|
||||||
|
raise SystemExit("milestone 10 parity cases are not reviewed: " + ", ".join(bad))
|
||||||
|
missing = sorted(
|
||||||
|
{
|
||||||
|
test["rust_file"]
|
||||||
|
for test in related
|
||||||
|
if not (ROOT / test["rust_file"]).is_file()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if missing:
|
||||||
|
raise SystemExit("milestone 10 translated files are missing: " + ", ".join(missing))
|
||||||
|
|
||||||
|
|
||||||
|
def check_contract_evidence() -> None:
|
||||||
|
require_markers(
|
||||||
|
ROOT / "crates" / "libremetaverse-rendering-simple" / "src" / "simple_renderer.rs",
|
||||||
|
("MAX_FACE_VERTICES", "checked_add", "u16::try_from"),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "crates" / "libremetaverse-rendering-mesh-foundry" / "src" / "mesh_foundry.rs",
|
||||||
|
("MAX_ASSET_BYTES", "MAX_TOTAL_VERTICES", "MAX_JOINTS", "checked_add"),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "crates" / "libremetaverse-rlv" / "src" / "service.rs",
|
||||||
|
(
|
||||||
|
"MAX_RLV_MESSAGE_BYTES",
|
||||||
|
"MAX_RLV_COMMANDS",
|
||||||
|
"Arc<dyn IRlvQueryCallbacks>",
|
||||||
|
"Arc<dyn IRlvActionCallbacks>",
|
||||||
|
"throw_if_cancellation_requested",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "crates" / "libremetaverse-lsl-tools" / "src" / "parser.rs",
|
||||||
|
("MAX_PARSER_STATES", "MAX_PARSER_STACK", "MAX_PARSER_STEPS", "MAX_RECOVERY_ERRORS"),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "crates" / "libremetaverse-lsl-tools" / "src" / "lexer.rs",
|
||||||
|
("MAX_SOURCE_UNITS", "MAX_TOKEN_UNITS"),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "tests" / "compat" / "tests" / "milestone_10_integration.rs",
|
||||||
|
(
|
||||||
|
"native_extensions_consume_core_models_and_preserve_service_state",
|
||||||
|
"SimpleRenderer",
|
||||||
|
"MeshFoundry",
|
||||||
|
"generated_parser",
|
||||||
|
"RlvHarness",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "docs" / "extension-milestone-gate.md",
|
||||||
|
(
|
||||||
|
"Choosing an extension",
|
||||||
|
"Rendering migration",
|
||||||
|
"RLV host integration and teardown",
|
||||||
|
"LSL tooling migration",
|
||||||
|
"194 types",
|
||||||
|
"1,287 members",
|
||||||
|
"tools/test_milestone_10.py",
|
||||||
|
"ubuntu-latest",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
require_markers(
|
||||||
|
ROOT / "api" / "SHIM-COVERAGE.md",
|
||||||
|
tuple(
|
||||||
|
f"`{name}` | {types} | {members} | native implementation"
|
||||||
|
for name, (types, members) in ASSEMBLIES.items()
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_generation_and_ci() -> None:
|
||||||
|
subprocess.run(
|
||||||
|
["python3", "tools/generate_rust_mapping.py", "--check"], cwd=ROOT, check=True
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["python3", "tools/generate_api_shims.py", "--check"], cwd=ROOT, check=True
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["python3", "tools/generate_lsl_tables.py", "--check"], cwd=ROOT, check=True
|
||||||
|
)
|
||||||
|
workflow = ROOT / ".gitea" / "workflows" / "rust-workspace.yml"
|
||||||
|
require_markers(
|
||||||
|
workflow,
|
||||||
|
(
|
||||||
|
"python3 tools/check_milestone_10.py",
|
||||||
|
"python3 tools/test_milestone_10.py",
|
||||||
|
"runs-on: ubuntu-latest",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if re.search(r"runs-on:\s*(?:macos|windows)", workflow.read_text(), re.IGNORECASE):
|
||||||
|
raise SystemExit("milestone 10 workflow is not ubuntu-only")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
check_catalog_ownership()
|
||||||
|
check_sources_and_manifests()
|
||||||
|
check_parity()
|
||||||
|
check_contract_evidence()
|
||||||
|
check_generation_and_ci()
|
||||||
|
print(
|
||||||
|
"milestone 10 audit: 194 types and 1,287 members are native; no owned "
|
||||||
|
"stubs remain; bounds, callback teardown, 691 reviewed parity cases, "
|
||||||
|
"integration, migration docs, deterministic generation, and ubuntu-only CI are present"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -132,7 +132,7 @@ def main() -> None:
|
|||||||
raise SystemExit(f"issue 81 expected 27 focused fixtures, found {test_count}")
|
raise SystemExit(f"issue 81 expected 27 focused fixtures, found {test_count}")
|
||||||
require_markers(DOC, (
|
require_markers(DOC, (
|
||||||
"UTF-16 code-unit offsets", "maximum munch", "structured `Diagnostic`",
|
"UTF-16 code-unit offsets", "maximum munch", "structured `Diagnostic`",
|
||||||
"64 Mi UTF-16", "16 Mi units", "Lexer::iter", "27 focused",
|
"64 Mi UTF-16", "16 Mi units", "Lexer::iter", "46 focused",
|
||||||
"No C#, .NET runtime", "ubuntu-latest",
|
"No C#, .NET runtime", "ubuntu-latest",
|
||||||
))
|
))
|
||||||
require_markers(WORKFLOW, ("python3 tools/check_milestone_10_issue_81.py",))
|
require_markers(WORKFLOW, ("python3 tools/check_milestone_10_issue_81.py",))
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ def main() -> None:
|
|||||||
require_markers(EXTENSION_TESTS, ("assert!(YyParser::new().is_ok())",))
|
require_markers(EXTENSION_TESTS, ("assert!(YyParser::new().is_ok())",))
|
||||||
require_markers(DOC, (
|
require_markers(DOC, (
|
||||||
"canonical LR(0)", "deterministic LALR(1)", "Shift/reduce conflicts",
|
"canonical LR(0)", "deterministic LALR(1)", "Shift/reduce conflicts",
|
||||||
"nonassociative", "1,048,576", "16,777,216", "37 focused",
|
"nonassociative", "1,048,576", "16,777,216", "46 focused",
|
||||||
"issue 83", "ubuntu-latest",
|
"issue 83", "ubuntu-latest",
|
||||||
))
|
))
|
||||||
require_markers(WORKFLOW, ("python3 tools/check_milestone_10_issue_82.py",))
|
require_markers(WORKFLOW, ("python3 tools/check_milestone_10_issue_82.py",))
|
||||||
|
|||||||
@@ -601,6 +601,26 @@ NATIVE_DECLARATIONS = {
|
|||||||
"T:LibreMetaverse.Rendering.MeshFoundry": "crate::mesh_foundry::MeshFoundry",
|
"T:LibreMetaverse.Rendering.MeshFoundry": "crate::mesh_foundry::MeshFoundry",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Catalog declarations which are themselves complete native Rust. Unlike
|
||||||
|
# NATIVE_TYPES, these types intentionally remain in generated.rs: the RLV
|
||||||
|
# enums are closed value tables and the callback interfaces are Rust traits
|
||||||
|
# whose required methods are implemented by the host and default adapters.
|
||||||
|
# Keeping this set explicit lets coverage distinguish concrete generated code
|
||||||
|
# from a callable failure-only compatibility shell.
|
||||||
|
NATIVE_GENERATED_TYPES = {
|
||||||
|
"T:LibreMetaverse.RLV.IRlvActionCallbacks",
|
||||||
|
"T:LibreMetaverse.RLV.IRlvQueryCallbacks",
|
||||||
|
"T:LibreMetaverse.RLV.RlvAttachmentPoint",
|
||||||
|
"T:LibreMetaverse.RLV.RlvGestureState",
|
||||||
|
"T:LibreMetaverse.RLV.RlvGetDebugType",
|
||||||
|
"T:LibreMetaverse.RLV.RlvGetEnvType",
|
||||||
|
"T:LibreMetaverse.RLV.RlvPermissionsService.HoverTextLocation",
|
||||||
|
"T:LibreMetaverse.RLV.RlvPermissionsService.ObjectLocation",
|
||||||
|
"T:LibreMetaverse.RLV.RlvPermissionsService.TouchLocation",
|
||||||
|
"T:LibreMetaverse.RLV.RlvRestrictionType",
|
||||||
|
"T:LibreMetaverse.RLV.RlvWearableType",
|
||||||
|
}
|
||||||
|
|
||||||
NATIVE_MEMBER_BODIES = {
|
NATIVE_MEMBER_BODIES = {
|
||||||
"M:LibreMetaverse.RLV.RlvCommon.TryGetAttachmentPointFromItemName(System.String,System.Nullable{LibreMetaverse.RLV.RlvAttachmentPoint}@)":
|
"M:LibreMetaverse.RLV.RlvCommon.TryGetAttachmentPointFromItemName(System.String,System.Nullable{LibreMetaverse.RLV.RlvAttachmentPoint}@)":
|
||||||
"Self::native_try_get_attachment_point_from_item_name(item_name, attachment_point)",
|
"Self::native_try_get_attachment_point_from_item_name(item_name, attachment_point)",
|
||||||
@@ -3523,9 +3543,18 @@ def native_member_body(member_id: str) -> str | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def render_body(signature: str, member_id: str, error_model: str, asyncness: str, trait: bool) -> str:
|
def render_body(
|
||||||
|
signature: str,
|
||||||
|
member_id: str,
|
||||||
|
error_model: str,
|
||||||
|
asyncness: str,
|
||||||
|
trait: bool,
|
||||||
|
required_trait_method: bool = False,
|
||||||
|
) -> str:
|
||||||
if trait:
|
if trait:
|
||||||
signature = signature.removeprefix("pub ")
|
signature = signature.removeprefix("pub ")
|
||||||
|
if required_trait_method:
|
||||||
|
return f" {signature};"
|
||||||
if body := native_member_body(member_id):
|
if body := native_member_body(member_id):
|
||||||
if any(f"LibreMetaverse.{owner}." in member_id for owner in CLIENT_CORE_NATIVE_OWNERS):
|
if any(f"LibreMetaverse.{owner}." in member_id for owner in CLIENT_CORE_NATIVE_OWNERS):
|
||||||
marker = " /* native client-core implementation */"
|
marker = " /* native client-core implementation */"
|
||||||
@@ -3647,6 +3676,7 @@ def render_type(item: dict, type_row: dict, member_rows: dict[str, dict[str, str
|
|||||||
row["error_model"],
|
row["error_model"],
|
||||||
row["asyncness"],
|
row["asyncness"],
|
||||||
trait,
|
trait,
|
||||||
|
trait and item["doc_id"] in NATIVE_GENERATED_TYPES,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
lines.append("}")
|
lines.append("}")
|
||||||
@@ -3844,7 +3874,9 @@ def coverage_report(catalog: dict, coverage: dict[str, tuple[int, int, bool]]) -
|
|||||||
native_type_ids = {
|
native_type_ids = {
|
||||||
item["doc_id"]
|
item["doc_id"]
|
||||||
for item in assembly["types"]
|
for item in assembly["types"]
|
||||||
if item["doc_id"] in NATIVE_TYPES or item["doc_id"] in NATIVE_DECLARATIONS
|
if item["doc_id"] in NATIVE_TYPES
|
||||||
|
or item["doc_id"] in NATIVE_DECLARATIONS
|
||||||
|
or item["doc_id"] in NATIVE_GENERATED_TYPES
|
||||||
or (name == "LibreMetaverse.Types" and item["kind"] == "enum")
|
or (name == "LibreMetaverse.Types" and item["kind"] == "enum")
|
||||||
}
|
}
|
||||||
native_member_ids = {
|
native_member_ids = {
|
||||||
@@ -3852,6 +3884,7 @@ def coverage_report(catalog: dict, coverage: dict[str, tuple[int, int, bool]]) -
|
|||||||
for item in assembly["types"]
|
for item in assembly["types"]
|
||||||
for member in item["members"]
|
for member in item["members"]
|
||||||
if item["doc_id"] in NATIVE_TYPES
|
if item["doc_id"] in NATIVE_TYPES
|
||||||
|
or item["doc_id"] in NATIVE_GENERATED_TYPES
|
||||||
or (name == "LibreMetaverse.Types" and item["kind"] == "enum")
|
or (name == "LibreMetaverse.Types" and item["kind"] == "enum")
|
||||||
or (
|
or (
|
||||||
item["doc_id"] in NATIVE_DECLARATIONS
|
item["doc_id"] in NATIVE_DECLARATIONS
|
||||||
|
|||||||
@@ -960,7 +960,10 @@ def function_bodies(text: str) -> list[str]:
|
|||||||
|
|
||||||
|
|
||||||
def validate_generated_shims() -> None:
|
def validate_generated_shims() -> None:
|
||||||
for path in sorted((ROOT / "crates").glob("*/src/generated*.rs")):
|
# Only generated.rs files are callable compatibility shim targets.
|
||||||
|
# Deterministic native artifacts such as LSL generated_tables.rs contain
|
||||||
|
# ordinary successful functions and are validated by their own generator.
|
||||||
|
for path in sorted((ROOT / "crates").glob("*/src/generated.rs")):
|
||||||
text = path.read_text()
|
text = path.read_text()
|
||||||
default_types = set(
|
default_types = set(
|
||||||
re.findall(
|
re.findall(
|
||||||
|
|||||||
77
tools/test_milestone_10.py
Normal file
77
tools/test_milestone_10.py
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run only tests owned by the rendering, RLV, and LSL milestone."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
ENV = os.environ.copy()
|
||||||
|
ENV.setdefault("CARGO_BUILD_JOBS", "1")
|
||||||
|
ENV.setdefault("CARGO_INCREMENTAL", "0")
|
||||||
|
ENV.setdefault("CARGO_PROFILE_DEV_DEBUG", "0")
|
||||||
|
ENV.setdefault("CARGO_PROFILE_TEST_DEBUG", "0")
|
||||||
|
ENV.pop("RUN_LIVE_TESTS", None)
|
||||||
|
|
||||||
|
|
||||||
|
def run(command: list[str]) -> None:
|
||||||
|
print("+", " ".join(command), flush=True)
|
||||||
|
subprocess.run(command, cwd=ROOT, env=ENV, check=True)
|
||||||
|
|
||||||
|
|
||||||
|
run(
|
||||||
|
[
|
||||||
|
"cargo",
|
||||||
|
"test",
|
||||||
|
"-p",
|
||||||
|
"libremetaverse-rendering-simple",
|
||||||
|
"-p",
|
||||||
|
"libremetaverse-rendering-mesh-foundry",
|
||||||
|
"-p",
|
||||||
|
"libremetaverse-rlv",
|
||||||
|
"-p",
|
||||||
|
"libremetaverse-lsl-tools",
|
||||||
|
"--locked",
|
||||||
|
"-j",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
catalog = json.loads((ROOT / "tests" / "upstream-tests.json").read_text())
|
||||||
|
rlv_targets = sorted(
|
||||||
|
{
|
||||||
|
Path(test["rust_file"]).stem
|
||||||
|
for test in catalog["tests"]
|
||||||
|
if test["source"].startswith("LibreMetaverse.Tests/RLV/")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if len(rlv_targets) != 24:
|
||||||
|
raise SystemExit(f"milestone 10 expected 24 RLV test targets, found {rlv_targets}")
|
||||||
|
|
||||||
|
compat = ["cargo", "test", "-p", "libremetaverse-compat-tests"]
|
||||||
|
for target in (
|
||||||
|
"imaging_meshing_semantics",
|
||||||
|
"rendering_shims",
|
||||||
|
"extension_shims",
|
||||||
|
"milestone_10_integration",
|
||||||
|
*rlv_targets,
|
||||||
|
):
|
||||||
|
compat.extend(("--test", target))
|
||||||
|
compat.extend(("--locked", "-j", "1"))
|
||||||
|
run(compat)
|
||||||
|
|
||||||
|
run(
|
||||||
|
[
|
||||||
|
"cargo",
|
||||||
|
"check",
|
||||||
|
"--manifest-path",
|
||||||
|
"tests/api-compile/Cargo.toml",
|
||||||
|
"--locked",
|
||||||
|
"-j",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user