Skip to content

Commit

Permalink
Merge documentation and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Perksey committed Nov 20, 2023
1 parent b09ff59 commit f67d445
Show file tree
Hide file tree
Showing 51 changed files with 7,717 additions and 10 deletions.
6 changes: 2 additions & 4 deletions Silk.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{9DB0EA3E-7
docs\CODE_OF_CONDUCT.md = docs\CODE_OF_CONDUCT.md
docs\CODEOWNERS = docs\CODEOWNERS
docs\CONTRIBUTING.md = docs\CONTRIBUTING.md
docs\ISSUE_TEMPLATE.md = docs\ISSUE_TEMPLATE.md
docs\PULL_REQUEST_TEMPLATE.md = docs\PULL_REQUEST_TEMPLATE.md
docs\README.md = docs\README.md
EndProjectSection
EndProject
Expand All @@ -52,9 +50,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{A5578D12
tests\Directory.Build.targets = tests\Directory.Build.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch", "sources\SilkTouch\Silk.NET.SilkTouch.csproj", "{76F747A6-D971-4162-BF35-A226177FCA08}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.SilkTouch", "sources\Silk.NET.SilkTouch\Silk.NET.SilkTouch.csproj", "{76F747A6-D971-4162-BF35-A226177FCA08}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.SilkTouch.UnitTests", "tests\SilkTouch\Silk.NET.SilkTouch.UnitTests.csproj", "{600D712C-4ABF-44C4-96C3-B1DEE1F38298}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.SilkTouch.UnitTests", "tests\SilkTouchX\Silk.NET.SilkTouch.UnitTests.csproj", "{600D712C-4ABF-44C4-96C3-B1DEE1F38298}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.GLFW", "sources\GLFW\Silk.NET.GLFW.csproj", "{7B58E4E1-0DE6-453C-95A2-25D8EE0621C1}"
EndProject
Expand Down
12 changes: 6 additions & 6 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- Begin exclude from NuGet readme. -->
<h1 align="center">
<a href="#"><img align="center" src="documentation/readme/silkdotnet_v3_horizontal_96.svg"></a>
<a href="#"><img align="center" src="readme/silkdotnet_v3_horizontal_96.svg"></a>
<br />
</h1>
<div align="center">
Expand All @@ -12,10 +12,10 @@

</div>

<div>
<div>
<!-- End exclude from NuGet readme. -->
<!-- Begin include in NuGet readme.
![Silk.NET Logo](https://raw.githubusercontent.com/dotnet/Silk.NET/main/documentation/readme/silkdotnet_v3_horizontal_96.svg)
![Silk.NET Logo](https://raw.githubusercontent.com/dotnet/Silk.NET/develop/3.0/docs/readme/silkdotnet_v3_horizontal_96.svg)
End include in NuGet readme. -->

Silk.NET is your one-stop-shop for high-speed .NET multimedia, graphics, and compute; providing bindings to popular low-level APIs such as OpenGL, OpenCL, OpenAL, OpenXR, GLFW, SDL, Vulkan, Assimp, WebGPU, and DirectX.
Expand All @@ -31,7 +31,7 @@ Silk.NET works on any .NET Standard 2.0 compliant platform, including .NET 6.0,
<a href="https://dotnetfoundation.org" align="right"><img src="https://github.com/dotnet-foundation/swag/blob/main/logo/dotnetfoundation_v4.svg" alt=".NET Foundation" class="logo-footer" width="72" align="left">
<!-- End exclude from NuGet readme. -->
<!-- Begin include in NuGet readme.
![.NET Foundation](https://raw.githubusercontent.com/dotnet/Silk.NET/main/documentation/readme/dotnetfoundation_v4_horizontal_64.svg)
![.NET Foundation](https://raw.githubusercontent.com/dotnet/Silk.NET/develop/3.0/docs/readme/dotnetfoundation_v4_horizontal_64.svg)
End include in NuGet readme. -->
</a>
<br />
Expand Down Expand Up @@ -125,9 +125,9 @@ Silk.NET is a [.NET Foundation](https://www.dotnetfoundation.org/projects) proje
---

<div>
<a href="https://www.jetbrains.com/?from=Silk.NET" align="right"><img src="https://raw.githubusercontent.com/dotnet/Silk.NET/main/documentation/readme/jetbrains.svg" alt="JetBrains" class="logo-footer" width="72" align="left">
<a href="https://www.jetbrains.com/?from=Silk.NET" align="right"><img src="https://raw.githubusercontent.com/dotnet/Silk.NET/develop/3.0/docs/readme/jetbrains.svg" alt="JetBrains" class="logo-footer" width="72" align="left">
<a><br/>

Special thanks to [JetBrains](https://www.jetbrains.com/?from=Silk.NET) for supporting us with open-source licenses for their IDEs. </a>
</div>

Expand Down
23 changes: 23 additions & 0 deletions docs/deprecation-notices/SilkManager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# SilkManager
## Information
- Introduced in Preview 2
- Active in 1.1.1
- Deprecated in 1.2
- Removed in 2.0

## Summary
SilkManager was our solution to accessing classes and interfaces that needed to be shared across packages without introducing a
direct (often circular) dependency.

## Why are we removing it?
In Silk.NET 2.0, we intend to couple all of the default windowing implementations into one package to eliminate the storage
overhead of having a bridge DLL with just one class in it (Silk.NET.Windowing and Silk.NET.Input). This is because .NET 5
makes cross-platform a lot easier. The new package structure will look like this:

- Silk.NET.Windowing
- Silk.NET.Windowing.Desktop merged into this package
- depends on Silk.NET.Windowing.Common
- Silk.NET.Input
- Silk.NET.Input.Desktop merged into this package
- depends on Silk.NET.Input.Common
- depends on Silk.NET.Windowing.Common (subject to change)
32 changes: 32 additions & 0 deletions docs/deprecation-notices/VulkanViews.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Vulkan-Specific Views and Windows (i.e. IVulkanView, IVulkanWindow)
## Information
- Introduced in Preview 3
- Active in 1.1.1
- Deprecated in 1.2
- Removed in 2.0

## Why are we removing it?
Currently, Vulkan-specific functions are accessed by first checking if a IView or IWindow supports Vulkan, and then
casting the IView or IWindow to a IVulkanView or IVulkanWindow respectively. This can get quite messy. As such, we
decided to instead move all API or platform specific functions into interfaces accessed via a nullable property in
IView and IWindow, as follows:

### Old
```cs
if (window.IsVulkanSupported && window is IVulkanWindow vkWindow)
{
vkWindow.CreateSurface(...);
}
```

### New

```cs
if (window.VkSurface != null)
{
window.VkSurface.CreateSurface(...);
}
```

All OpenGL functions will get the same treatment, but both the Vulkan-specific and OpenGL-specific functions will
continue to be accessible through the main IView and IWindow interfaces through extension methods.
13 changes: 13 additions & 0 deletions docs/for-contributors/generators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SilkTouch

SilkTouch is the Silk.NET project's C# native interoperability code generation stack. It contains useful generators which together generate the majority of the library's codebase.

It does this by centering all parts around a [common symbol layer](./symbol-layer/README.md), which allows other parts to be used in any configuration deemed useful, parts don't have a way other then the symbol layer to exchange data, enforcing interoperability.

Learn more about each individual cornerstone of the SilkTouch Stack:

- [Symbol Layer](./symbol-layer/README.md)
- [Emitter](emitter.md)
- [Scraper](scraper.md)

TODO: Add a link to the original proposal once the proposals folder has been reorganised according to the Software Development Plan.
7 changes: 7 additions & 0 deletions docs/for-contributors/generators/emitter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Emitter

The emitter is responsible for creating Roslyn C# Code Symbols from our symbol layer.

See [here](./about%20formatting.md) for how formatting works, and [here](./visitor.md) for details on the visitor implementation.

In general the emitter tries it's best to be very basic doing only the job of 1:1 translating shared symbol layer into C# roslyn symbols.
38 changes: 38 additions & 0 deletions docs/for-contributors/generators/emitter/about formatting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# About Formatting

This document is just a sink for all things related formatting.
If your code is acting up and spitting out unreadable garbage, or you want to improve code style - READ THIS FRIST!

## Indentation

The emitter implements a very basic system based on 4 members: `Indent()`, `Outdent()`, `NewLine`, `Indentation`

- `Indent()`: After this call indentation will be more
- `Outdent()`: After this call indentation will be less
- `NewLine`: Put this when you want to go to the next line. It automatically handles putting the right amount of spaces after.
- `Indentation`: only use this if absolutely necessary. It's only there as a safety net

The common pattern is something like this:

```cs
Indent()
var members = memberSymbols.Select(s => {
VisitSomething(s);
if (_syntax is not SomeSyntax memberSyntax)
throw Something;
ClearState();
memberSyntax = memberSyntax.WithLeadingTrivia(NewLine);
return memberSyntax;
}).ToArray();
Outdent();

// use members somehow
```

Note the `.ToArray()` this forces execution to happen during the indent/outdent scope.

## On Trivia

Prefer using leading trivia over trailing trivia. This is because leading trivia is impossible to leak outside of the symbol you are working on, while trailing trivia easily does this. While sometimes inconvinient because the parent symbol you have no control over leaks it's trivia into your symbol, it's still preferable - had the parent symbol followed this advice it couldn't leak into your symbol right now. Do us all a favor.

Similar things apply at the micro level too - use leading trivia on braces over trailing trivia on identifiers. This improves the editing experience when adding extra things later and massively improves the reviewers understanding, as there are simply fewer changes.
39 changes: 39 additions & 0 deletions docs/for-contributors/generators/emitter/visitor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Visitor

See [here](../symbol-layer/symbol-visitor.md) for details on how the base symbol visitor works.

To Transform our internal symbol layer to C# code a visitor (`CSharpEmitter.Visitor`) is used.

## State

To communicate produced syntax nodes with the levels above the current one the state variables are used.
Therefore its important to enshure that this state is clear at all times. (Using `AssertClearState` & `ClearState`)

## Depth First

In general we try to push symbols down as far as possible to avoid code duplication and increase testable surface area.
The best example of this that instead of creating identifier tokens / identifier name syntax nodes inline (which would be very easy) we visit the identifier, letting the `VisitIdentifier` function create those, and then take what we need, using a pattern like

```cs
VisitIdentifier(structSymbol.Identifier);
if (_syntaxToken is not { } identifierToken)
throw new InvalidOperationException("Some Identifier was not visited correctly");
ClearState();
```

when a token is required, or

```cs
VisitIdentifier(fieldSymbol.Type.Identifier);
if (_syntax is not IdentifierNameSyntax typeIdentifierSyntax)
throw new InvalidOperationException("Some Identifier was not visited correctly");
ClearState();
```

when a syntax node is required.

## Trivia

The visitor is intended to produce "valid" code, that means it can be formatted using .ToFullString and the resulting code is valid and can be parsed back by roslyn.
In addition we try to avoid elastic trivia wherever possible. For performance reasons we don't want to normalize our trivia / syntax internally, but elastic trivia would be thrown away when doing so, therefore we try to avoid generating elastic trivia in the first place.
Integration tests should test for elastic trivia, although their primary purpose is to check the resulting formatted string.
16 changes: 16 additions & 0 deletions docs/for-contributors/generators/scraper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Scraper

The Scraper will call into ClangSharp to generate XML from the given C headers (`GenerateXML`), and then convert the output produced by ClangSharp into symbols defined by the [Symbol Layer](./symbol-layer/README.md) (`ScrapeXML`).

The Scraper should stay quite small and easy to use, as it is also the window to all the complexity that comes from C++, Clang, header, etc. It should only bridge the XML output into the symbol layer.

## Scraping XML

To scrape XML there is a visitor that visits each XML node and outputs several symbols per node.
This is what happens in `XmlVisitor.cs`, called from `ScrapeXML`.

## Generating XML using ClangSharp

This is what happens in `ClangScraper.cs`, which is configured using `ClangScraperConfiguration.cs`.
The XML is generated by the `ClangSharp.PInvokeGenerator` see [dotnet/ClangSharp](https://github.com/dotnet/ClangSharp) and the [PInvokeGenerator file](https://github.com/dotnet/ClangSharp/blob/main/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs).
Check XML docs for details on what methods do.
11 changes: 11 additions & 0 deletions docs/for-contributors/generators/symbol-layer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Symbol Layer

The symbol layer is a set of types in the Silk.NET.SilkTouch.Symbols, all inheriting from the central Silk.NET.SilkTouch.Symbols.Symbol type.

The symbol layer is intended as a way to represent data passed between components of SilkTouch and is entirely immutable, with the only exception being the [Type Store](./type-store.md).

The way to update & iterate symbols is using a [Symbol Visitor](./symbol-visitor.md).

See [symbols](./symbols/README.md) for a list of all symbols, their visitor method, test details, etc.

See [type references](./type-references.md) for an explanation of type references.
19 changes: 19 additions & 0 deletions docs/for-contributors/generators/symbol-layer/symbol-visitor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Symbol Visitor

A symbol visitor visits each symbol and then calls the appropriate methods to recursively visit all parts.
Each symbol visitor has access to a [type store](./type-store.md). It has to be provided in the constructor of every symbol visitor.
It's generally adviced to simply bubble up this constructor parameter to users of your type.

## Updating Symbols

Each method returns the same type it gets as parameter, so prefer to override the most specific method possible.
For example, if you wish to rename all `TypeSymbol`s, override `VisitTypeSymbol`. But if you want to add a field to every struct, override `VisitStructSymbol`. If you want to rewrite the type of a symbol, for example generate a class for every struct, again, override the most specific method that is compatible with both (in this case `VisitTypeSymbol`) and do type checks as necessary.

### Type IDs

See [type store](./type-store.md) for details on what type Ids are.
**Do not change type IDs when visiting symbols. This breaks all references to that type.**

## Managing State

While the base `SymbolVisitor` is stateless, derived types are free to introduce (mutable) state. This allow propagating state other then the new symbol up the tree.
55 changes: 55 additions & 0 deletions docs/for-contributors/generators/symbol-layer/symbols/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Symbols

This document / folder is for tracking all the available symbols, and documenting what creation of one entails.

## Relation to SymbolVisitor

In general each symbol listed below should have a corresponding method `VisitMySymbol` the only exception being `UnresolvedTypeReference` as only few visitors should ever interact with it.

## List

(Order alphabetically please!)

Parent Symbols (Unlisted, abstract):
| Name | See Also |
| ---- | -------- |
| MemberSymbol | |
| Symbol | |
| TypeReference | [here](../type-references.md) |
| TypeSymbol | |
| MethodSymbol |

| Name | Symbol Layer File | Symbol Layer Tests | Emitter Tests |
| ---------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| ClassSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/ClassSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ClassSymbolTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/ClassSymbolTests.cs) |
| ExternalTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/ExternalTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/ExternalTypeReferenceTests.cs) |
| FunctionPointerTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/FunctionPointerTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FunctionPointerTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/FunctionPointerTypeReferenceTests.cs) |
| FieldSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/FieldSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterFieldTests.cs) |
| IdentifierSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/IdentifierSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierSymbolTests.cs) |
| InternalTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/InternalTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/InternalTypeReferenceTests.cs) |
| NamespaceSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/NamespaceSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceTests.cs) |
| PointerTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/PointerTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/PointerTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/PointerTypeReferenceTests.cs) |
| StaticExternalMethodSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/StaticExternalMethodSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StaticExternalMethodSymbolTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/StaticExternalMethodSymbolTests.cs) |
| StructSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs) |
| UnresolvedTypeReference | [here](src/generators/Silk.NET.SilkTouch.Symbols/UnresolvedTypeReference.cs) | [here](tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs) | - |

## How to create a symbol

Checklist:

- [ ] Write a short description of what this symbol does in the above list.
- [ ] Add the symbol to Silk.NET.SilkTouch.Symbols
- [ ] Add a partial of SymbolVisitor to below the definition, and add visiting method in there.
- [ ] Call the new visiting method either from
- The root Visit(Symbol) method, this should rarely be needed
- The parent's visit method
- [ ] Add Tests to Silk.NET.SilkTouch.Symbols.Tests for
- [ ] The type being visited with it's own visiting method
- [ ] The type being visited with it's parent (not needed if this is a new root type, with no parent)
- [ ] Each part being visited correctly. Only shallowly check this, don't check parts of parts.
- [ ] Handle symbol in Silk.NET.SilkTouch.Emitter
- [ ] Add Tests to Silk.NET.SilkTouch.Emitter.Tests
- [ ] Transforming a sample Symbol matching a specific string
- [ ] Other tests, this is highly dependend on how complex the C# output looks like
- [ ] More is better!
- [ ] You're done. Feel free to use the symbol wherever needed. Prefer to add usages in a separate PR.
Loading

0 comments on commit f67d445

Please sign in to comment.