-
Notifications
You must be signed in to change notification settings - Fork 31
Tomb Engine: Electrical Field and Fusebox #1132
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
Draft
Stranger1992
wants to merge
4
commits into
develop
Choose a base branch
from
Stranger1992-Electrical-Field-Fusebox
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| ## General Project Information | ||
|
|
||
| - Language: **C# targeting .NET 8** (desktop application). | ||
| - This is a level editor suite for a family of 3D game engines used in the classic Tomb Raider series. | ||
| - Level formats are grid-based, room-based, and portal-based. | ||
| - A room is a spatial container for level geometry and game entities. | ||
| - Rooms are connected by vertical or horizontal portals, strictly aligned with grid sectors. | ||
| - Portals may be visual (`RoomConnectionInfo.VisualType`) or traversable (`RoomConnectionInfo.TraversableType`). | ||
| - One grid sector consists of 1024 units, which roughly equals 2 meters in real-world coordinates. | ||
|
|
||
| ## General Guidelines | ||
|
|
||
| - Files must use Windows line endings. Only standard ASCII symbols are allowed; do not use Unicode symbols. | ||
| - `using` directives are grouped and sorted as follows: `DarkUI` namespaces first, then `System` namespaces, followed by third-party and local namespaces. | ||
| - Namespace declarations and type definitions should place the opening brace on a new line. | ||
| - Prefer grouping all feature-related functionality within a self-contained module or modules. Avoid creating large code blocks over 10–15 lines in existing modules; instead, offload code to helper functions. | ||
| - Avoid duplicating and copypasting code. Implement helper methods instead, whenever similar code is used within a given module, class or feature scope. | ||
|
|
||
| ## Formatting | ||
|
|
||
| - **Indentation** is four spaces; tabs are not used. | ||
|
|
||
| - **Braces**: | ||
| - Always use braces for multi-statement blocks. | ||
| - Do not use braces for single-statement blocks, unless they are within multiple `else if` conditions where surrounding statements are multi-line. | ||
|
|
||
| - Opening curly brace `{` for structures, classes and methods should be on the next line, not on the same line: | ||
|
|
||
| ```csharp | ||
| public class Foo | ||
| { | ||
| public void Bar() | ||
| { | ||
| if (condition) | ||
| { | ||
| ... | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| - Anonymous delegates and lambdas should keep the brace on the same line: | ||
| `delegate () { ... }` or `() => { ... }`. | ||
|
|
||
| - **Line breaks and spacing**: | ||
| - A blank line separates logically distinct groups of members (fields, constructors, public methods, private helpers, etc.). | ||
| - Spaces around binary operators (`=`, `+`, `==`, etc.) and after commas. | ||
| - A single space follows keyword `if`/`for`/`while` before the opening parenthesis. | ||
| - Expressions may be broken into multiple lines and aligned with the previous line's indentation level to improve readability. | ||
| - However, chained LINQ method calls, lambdas or function/method arguments should not be broken into multiple lines, unless they reach more than 150 symbols in length. | ||
|
|
||
| - Do not collapse early exits or single-statement conditions into a single line: | ||
|
|
||
| Bad example: | ||
| ```csharp | ||
| if (condition) return; | ||
| ``` | ||
| Do this instead: | ||
| ```csharp | ||
| if (condition) | ||
| return; | ||
| ``` | ||
|
|
||
| ## Naming | ||
|
|
||
| - **PascalCase** for public types, methods, constants, properties and events. | ||
| - **camelCase** for private fields and local variables. Private fields should start with an underscore (`_editor`, `_primaryControlFocused`). Local variables should not start with an underscore. | ||
| - Constants and `static readonly` fields use PascalCase rather than ALL_CAPS. | ||
| - Enum members use PascalCase. | ||
| - Interfaces are prefixed with `I` and use PascalCase (`IScaleable`). | ||
| - Methods and variables should use clear, descriptive names and generally avoid Hungarian notation. Avoid using short non-descriptive names, such as `s2`, `rwh`, `fmp`, unless underlying meaning is brief (e.g. X coordinate is `x`, counter is `i`). | ||
| - Class method and field names should not repeat words from a class name itself (e.g. `ObjectBrushHelper.BeginObjectBrushStroke` is a bad name, but `ObjectBrushHelper.BeginStroke` is a good name). | ||
|
|
||
| ## Members and Access | ||
|
|
||
| - Fields are generally declared as `public` or `private readonly` depending on usage; expose state via properties where appropriate. | ||
| - `var` type should be preferred where possible, when the right-hand type is evident from the initializer. | ||
| - Explicit typing should be only used when it is required by logic or compiler, or when type name is shorter than 6 symbols (e.g. `int`, `bool`, `float`). | ||
| - For floating-point numbers, always use `f` postfix and decimal, even if value is not fractional (e.g. `2.0f`). | ||
|
|
||
| ## Control Flow and Syntax | ||
|
|
||
| - Avoid excessive condition nesting and use early exits / breaks where possible. | ||
| - LINQ and lambda expressions are used for collections (`FirstOrDefault`, `Where`, `Any`, etc.). | ||
| - Exception and error handling is done with `try`/`catch`, and caught exceptions are logged with [NLog](https://nlog-project.org/) where appropriate. | ||
| - Warnings must also be logged by NLog, if cause for the incorrect behaviour is user action. | ||
|
|
||
| ## Comments | ||
|
|
||
| - When comments appear they are single-line `//`. Block comments (`/* ... */`) are rare. | ||
| - Comments are sparse. Code relies on meaningful names rather than inline documentation. | ||
| - Do not use `<summary>` if surrounding code and/or module isn't already using it. Only add `<summary>` for non-private methods with high complexity. | ||
| - If module or function implements complex functionality, a brief description (2-3 lines) may be added in front of it, separated by a blank line from the function body. | ||
| - All descriptive comments should end with a full stop (`.`). | ||
|
|
||
| ## Code Grouping | ||
|
|
||
| - Large methods should group related actions together, separated by blank lines. | ||
| - Constants and static helpers that are used several times should appear at the top of a class. | ||
| - Constants that are used only within a scope of a method, should be declared within this method. | ||
| - One-liner lambdas may be grouped together, if they share similar meaning or functionality. | ||
|
|
||
| ## User Interface Implementation | ||
|
|
||
| - For WinForms-based workflows, maintain the existing Visual Studio module pair for each control or unit: `.cs` and `.Designer.cs`. | ||
| - For existing WinForms-based `DarkUI` controls and containers, prefer to use existing WinForms-based `DarkUI` controls. | ||
| - For new controls and containers with complex logic, or where WinForms may not perform fast enough, prefer `DarkUI.WPF` framework. Use `GeometryIOSettingsWindow` as a reference. | ||
| - Use `CommunityToolkit` functionality where possible. | ||
|
|
||
| ## Performance | ||
|
|
||
| - For 3D rendering controls, prefer more performant approaches and locally cache frequently used data within the function scope whenever possible. | ||
| - Avoid scenarios where bulk data updates may cause event floods, as the project relies heavily on event subscriptions across multiple controls and sub-controls. | ||
| - Use `Parallel` for bulk operations to maximize performance. Avoid using it in thread-unsafe contexts or when operating on serial data sets. | ||
15 changes: 15 additions & 0 deletions
15
DarkUI/DarkUI.WPF/Converters/InverseBoolToVisibilityConverter.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using System; | ||
| using System.Globalization; | ||
| using System.Windows; | ||
| using System.Windows.Data; | ||
|
|
||
| namespace DarkUI.WPF.Converters; | ||
|
|
||
| public class InverseBoolToVisibilityConverter : IValueConverter | ||
| { | ||
| public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | ||
| => value is bool b && b ? Visibility.Collapsed : Visibility.Visible; | ||
|
|
||
| public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | ||
| => throw new NotSupportedException(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| using System; | ||
| using System.Windows; | ||
| using System.Windows.Controls; | ||
|
|
||
| namespace DarkUI.WPF.CustomControls; | ||
|
|
||
| /// <summary> | ||
| /// A Grid that supports RowSpacing and ColumnSpacing between rows and columns | ||
| /// without injecting dummy rows or columns. | ||
| /// </summary> | ||
| public class SpacedGrid : Grid | ||
| { | ||
| public static readonly DependencyProperty RowSpacingProperty = | ||
| DependencyProperty.Register( | ||
| nameof(RowSpacing), | ||
| typeof(double), | ||
| typeof(SpacedGrid), | ||
| new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange)); | ||
|
|
||
| public static readonly DependencyProperty ColumnSpacingProperty = | ||
| DependencyProperty.Register( | ||
| nameof(ColumnSpacing), | ||
| typeof(double), | ||
| typeof(SpacedGrid), | ||
| new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange)); | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the vertical spacing between rows. | ||
| /// </summary> | ||
| public double RowSpacing | ||
| { | ||
| get => (double)GetValue(RowSpacingProperty); | ||
| set => SetValue(RowSpacingProperty, value); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Gets or sets the horizontal spacing between columns. | ||
| /// </summary> | ||
| public double ColumnSpacing | ||
| { | ||
| get => (double)GetValue(ColumnSpacingProperty); | ||
| set => SetValue(ColumnSpacingProperty, value); | ||
| } | ||
|
|
||
| protected override Size MeasureOverride(Size constraint) | ||
| { | ||
| double totalRowSpacing = GetTotalRowSpacing(); | ||
| double totalColSpacing = GetTotalColumnSpacing(); | ||
|
|
||
| var reducedConstraint = new Size( | ||
| double.IsInfinity(constraint.Width) ? constraint.Width : Math.Max(0, constraint.Width - totalColSpacing), | ||
| double.IsInfinity(constraint.Height) ? constraint.Height : Math.Max(0, constraint.Height - totalRowSpacing)); | ||
|
|
||
| var baseSize = base.MeasureOverride(reducedConstraint); | ||
|
|
||
| return new Size(baseSize.Width + totalColSpacing, baseSize.Height + totalRowSpacing); | ||
| } | ||
|
|
||
| protected override Size ArrangeOverride(Size arrangeSize) | ||
| { | ||
| double rowSpacing = RowSpacing; | ||
| double colSpacing = ColumnSpacing; | ||
| double totalRowSpacing = GetTotalRowSpacing(); | ||
| double totalColSpacing = GetTotalColumnSpacing(); | ||
|
|
||
| // Let the base Grid arrange children within a reduced area. | ||
| var reducedSize = new Size( | ||
| Math.Max(0, arrangeSize.Width - totalColSpacing), | ||
| Math.Max(0, arrangeSize.Height - totalRowSpacing)); | ||
|
|
||
| base.ArrangeOverride(reducedSize); | ||
|
|
||
| int rowCount = Math.Max(1, RowDefinitions.Count); | ||
| int colCount = Math.Max(1, ColumnDefinitions.Count); | ||
|
|
||
| // Build cumulative row offsets from ActualHeight after base layout. | ||
| double[] rowStarts = new double[rowCount + 1]; | ||
|
|
||
| for (int i = 0; i < rowCount; i++) | ||
| { | ||
| double height = RowDefinitions.Count > 0 ? RowDefinitions[i].ActualHeight : reducedSize.Height; | ||
| rowStarts[i + 1] = rowStarts[i] + height; | ||
| } | ||
|
|
||
| // Build cumulative column offsets from ActualWidth after base layout. | ||
| double[] colStarts = new double[colCount + 1]; | ||
|
|
||
| for (int i = 0; i < colCount; i++) | ||
| { | ||
| double width = ColumnDefinitions.Count > 0 ? ColumnDefinitions[i].ActualWidth : reducedSize.Width; | ||
| colStarts[i + 1] = colStarts[i] + width; | ||
| } | ||
|
|
||
| // Re-arrange each child, injecting spacing offsets. | ||
| foreach (UIElement child in InternalChildren) | ||
| { | ||
| if (child == null || child.Visibility == Visibility.Collapsed) | ||
| continue; | ||
|
|
||
| int row = Math.Min(GetRow(child), rowCount - 1); | ||
| int col = Math.Min(GetColumn(child), colCount - 1); | ||
| int rowSpan = Math.Min(GetRowSpan(child), rowCount - row); | ||
| int colSpan = Math.Min(GetColumnSpan(child), colCount - col); | ||
|
|
||
| // Position = base offset + cumulative spacing for preceding rows/columns. | ||
| double x = colStarts[col] + col * colSpacing; | ||
| double y = rowStarts[row] + row * rowSpacing; | ||
|
|
||
| // Size = base span size + spacing gaps within the span. | ||
| double width = colStarts[col + colSpan] - colStarts[col] + (colSpan - 1) * colSpacing; | ||
| double height = rowStarts[row + rowSpan] - rowStarts[row] + (rowSpan - 1) * rowSpacing; | ||
|
|
||
| child.Arrange(new Rect(x, y, Math.Max(0, width), Math.Max(0, height))); | ||
| } | ||
|
|
||
| return arrangeSize; | ||
| } | ||
|
|
||
| private double GetTotalRowSpacing() | ||
| { | ||
| int gaps = Math.Max(0, (RowDefinitions.Count > 0 ? RowDefinitions.Count : 1) - 1); | ||
| return gaps * RowSpacing; | ||
| } | ||
|
|
||
| private double GetTotalColumnSpacing() | ||
| { | ||
| int gaps = Math.Max(0, (ColumnDefinitions.Count > 0 ? ColumnDefinitions.Count : 1) - 1); | ||
| return gaps * ColumnSpacing; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| <ResourceDictionary | ||
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
| xmlns:local="clr-namespace:DarkUI.WPF"> | ||
|
|
||
| <Style x:Key="SliderRepeatButtonStyle" TargetType="{x:Type RepeatButton}"> | ||
| <Setter Property="OverridesDefaultStyle" Value="True" /> | ||
| <Setter Property="IsTabStop" Value="False" /> | ||
| <Setter Property="Focusable" Value="False" /> | ||
|
|
||
| <Setter Property="Template"> | ||
| <Setter.Value> | ||
| <ControlTemplate TargetType="{x:Type RepeatButton}"> | ||
| <Border Background="Transparent" /> | ||
| </ControlTemplate> | ||
| </Setter.Value> | ||
| </Setter> | ||
| </Style> | ||
|
|
||
| <Style x:Key="SliderThumbStyle" TargetType="{x:Type Thumb}"> | ||
| <Setter Property="OverridesDefaultStyle" Value="True" /> | ||
| <Setter Property="Template"> | ||
| <Setter.Value> | ||
| <ControlTemplate TargetType="{x:Type Thumb}"> | ||
| <Border | ||
| Width="10" | ||
| Height="16" | ||
| Background="{DynamicResource Brush_Background_High}" | ||
| BorderBrush="{DynamicResource Brush_Border}" | ||
| BorderThickness="1" | ||
| CornerRadius="2" /> | ||
| </ControlTemplate> | ||
| </Setter.Value> | ||
| </Setter> | ||
| </Style> | ||
|
|
||
| <Style TargetType="{x:Type Slider}"> | ||
| <Setter Property="OverridesDefaultStyle" Value="True" /> | ||
| <Setter Property="SnapsToDevicePixels" Value="{x:Static local:Defaults.SnapsToDevicePixels}" /> | ||
| <Setter Property="UseLayoutRounding" Value="{x:Static local:Defaults.UseLayoutRounding}" /> | ||
|
|
||
| <Setter Property="Template"> | ||
| <Setter.Value> | ||
| <ControlTemplate TargetType="{x:Type Slider}"> | ||
| <Grid VerticalAlignment="Center"> | ||
| <Border | ||
| Height="4" | ||
| Margin="5,0" | ||
| Background="{DynamicResource Brush_Background_Low}" | ||
| BorderBrush="{DynamicResource Brush_Border}" | ||
| BorderThickness="1" | ||
| CornerRadius="2" /> | ||
|
|
||
| <Track x:Name="PART_Track"> | ||
| <Track.DecreaseRepeatButton> | ||
| <RepeatButton Command="Slider.DecreaseLarge" Style="{StaticResource SliderRepeatButtonStyle}" /> | ||
| </Track.DecreaseRepeatButton> | ||
| <Track.Thumb> | ||
| <Thumb Style="{StaticResource SliderThumbStyle}" /> | ||
| </Track.Thumb> | ||
| <Track.IncreaseRepeatButton> | ||
| <RepeatButton Command="Slider.IncreaseLarge" Style="{StaticResource SliderRepeatButtonStyle}" /> | ||
| </Track.IncreaseRepeatButton> | ||
| </Track> | ||
| </Grid> | ||
| </ControlTemplate> | ||
| </Setter.Value> | ||
| </Setter> | ||
| </Style> | ||
| </ResourceDictionary> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This states the project targets .NET 8, but multiple
.csprojfiles in this PR targetnet6.0-windows. Update AGENTS.md to match the repository’s actual target framework(s) to avoid misleading contributors/tooling.