Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Staging #336

Merged
merged 95 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
5df5f15
Merge pull request #333 from Luthetus/main
Luthetus Oct 17, 2024
0553b05
Merge pull request #334 from Luthetus/beta
Luthetus Oct 17, 2024
73f2e46
Merge pull request #41 from Luthetus/staging
huntercfreeman Oct 17, 2024
827c5b1
Draft PR
huntercfreeman Oct 17, 2024
0efb0ae
IParserModel.ExpressionStack
huntercfreeman Oct 18, 2024
f91af6b
Add: 'BadExpressionNode.cs'
huntercfreeman Oct 18, 2024
d6bc82b
Builds without errors
huntercfreeman Oct 18, 2024
589a053
Good progress checkpoint
huntercfreeman Oct 18, 2024
2702123
Finish: Numeric_BinaryExpressionNode()
huntercfreeman Oct 18, 2024
acb89d8
Finish: String_BinaryExpressionNode()
huntercfreeman Oct 18, 2024
79b9106
Finish: Char_BinaryExpressionNode()
huntercfreeman Oct 18, 2024
f68ca47
Various number related binary operators
huntercfreeman Oct 18, 2024
b40412e
Finish: Numeric_Add_BinaryExpressionNode_More()
huntercfreeman Oct 18, 2024
ded5c4a
Finish: Bool_BinaryExpressionNode()
huntercfreeman Oct 18, 2024
189972e
ExpressionSession
huntercfreeman Oct 19, 2024
de0d284
ParenthesizedExpressionNode idea
huntercfreeman Oct 19, 2024
c920af4
Recursive step: ParseExpression(...)
huntercfreeman Oct 19, 2024
29f54d4
ParenthesizedExpressionNode_Test()
Luthetus Oct 19, 2024
130e3ea
ExplicitCastNode_IdentifierToken()
Luthetus Oct 19, 2024
60c3f0d
ExplicitCastNode_KeywordToken()
Luthetus Oct 19, 2024
e104cf2
Break out code into separate files
Luthetus Oct 19, 2024
9288cca
Rename methods
Luthetus Oct 19, 2024
5a6be2c
FunctionInvocationNode_A()
huntercfreeman Oct 20, 2024
3a222f2
FunctionInvocationNode_B()
huntercfreeman Oct 20, 2024
e7e5cb8
Function generic parameters progress
huntercfreeman Oct 20, 2024
6fd0254
Might go on to create 'TypeExpressionNode'?
huntercfreeman Oct 20, 2024
39c13d4
Add: AmbiguousIdentifierExpressionNode.cs
huntercfreeman Oct 20, 2024
01f0984
Cleaner: Parser_TEST.cs file
huntercfreeman Oct 20, 2024
61f4638
More cleaning
huntercfreeman Oct 20, 2024
13e386f
Cleaning
huntercfreeman Oct 20, 2024
6bf9cf1
FunctionInvocationNode_D()
huntercfreeman Oct 20, 2024
2c2159e
Skeleton ConstructorInvocationNode tests
huntercfreeman Oct 20, 2024
6a14a9e
ConstructorInvocationNode_A()
huntercfreeman Oct 20, 2024
b8a762a
ConstructorInvocationNode_B()
huntercfreeman Oct 20, 2024
bd623f5
ConstructorInvocationNode_C()
huntercfreeman Oct 20, 2024
c33e313
ConstructorInvocationNode_D()
huntercfreeman Oct 20, 2024
8726457
ObjectInitializationNode skeleton
huntercfreeman Oct 21, 2024
3838c32
Skeleton for assertions
huntercfreeman Oct 21, 2024
6f7b385
Built no errors
huntercfreeman Oct 21, 2024
1edf52f
BadExpressionNode: syntaxPrimary.SyntaxKind: AmbiguousIdentifierExpre…
huntercfreeman Oct 21, 2024
3b387c0
Progress
huntercfreeman Oct 21, 2024
67c2d41
Built no errors
huntercfreeman Oct 21, 2024
2b0a2f9
This looks promising
huntercfreeman Oct 21, 2024
6299582
ObjectInitializationNode_A()
huntercfreeman Oct 21, 2024
beae7d0
ObjectInitializationNode_... all them passed
huntercfreeman Oct 21, 2024
079b0f3
Skeleton CollectionInitializationNode
huntercfreeman Oct 21, 2024
4021861
IsCollectionInitialization
huntercfreeman Oct 21, 2024
a808c4b
CollectionInitializationNode_A()
huntercfreeman Oct 21, 2024
5f8adb2
Update ParseExpressionTests.cs
huntercfreeman Oct 21, 2024
487d472
Name the tests
huntercfreeman Oct 22, 2024
1e2094b
Update Parser_TEST.cs
huntercfreeman Oct 22, 2024
fe8dce8
Progress
huntercfreeman Oct 22, 2024
8aa5522
CollectionInitializationNode_Parameters_WithTrailingComma()
huntercfreeman Oct 22, 2024
17e7392
CollectionInitializationNode
huntercfreeman Oct 22, 2024
18031c4
LambdaExpression skeleton
huntercfreeman Oct 22, 2024
60be351
Idea?
huntercfreeman Oct 22, 2024
5b7cd7f
Update ParseExpressionTests.cs
huntercfreeman Oct 22, 2024
2a679c7
LambdaFunction Fabricate
huntercfreeman Oct 23, 2024
494e4bf
fix build errors
huntercfreeman Oct 23, 2024
51754c8
_shortCircuitListStringifiedIsDirty
huntercfreeman Oct 23, 2024
c19694f
They all return 'LambdaExpressionNode' so progress I guess?
huntercfreeman Oct 23, 2024
bb5baa0
Merged code with CSharpBinder.cs Built without errors
huntercfreeman Oct 23, 2024
6928f4c
Fix: new expression parsing Null Reference Exception
Luthetus Oct 24, 2024
e3327bf
DOES NOT WORK: changing GetChildList
huntercfreeman Oct 24, 2024
530f306
ChildList -> GetChildList() lazy
huntercfreeman Oct 24, 2024
6d3dfa7
Expression 'forceExit'
huntercfreeman Oct 25, 2024
261ecfa
Tests build without errors
huntercfreeman Oct 25, 2024
01201d3
Bool_BinaryExpressionNode()
huntercfreeman Oct 25, 2024
fa085cc
ParenthesizedExpressionNode_Test()
huntercfreeman Oct 25, 2024
cb99677
ExplicitCastNode_IdentifierToken()
huntercfreeman Oct 25, 2024
d66c0bd
FunctionInvocationNode_Parameters()
huntercfreeman Oct 25, 2024
cbcc86f
ConstructorInvocationNode_Basic()
huntercfreeman Oct 25, 2024
08a392c
triggeredDelimiterTuple
huntercfreeman Oct 25, 2024
6308a91
ConstructorInvocationNode_Generic_Parameters()
huntercfreeman Oct 25, 2024
fd45865
VariableReferenceNode in expression
huntercfreeman Oct 26, 2024
a020b63
Thoughts (2024-10-25)
huntercfreeman Oct 26, 2024
48c3ae2
ConstructorInvocation uses shared GenericParameter logic
huntercfreeman Oct 26, 2024
5c85558
FunctionInvocationNode uses shared generic code
huntercfreeman Oct 26, 2024
e4e7051
Fix any code that broke from common generic parameter logic
huntercfreeman Oct 26, 2024
39f4320
Progress?
huntercfreeman Oct 26, 2024
1461dcf
Fix EmptyExpressionNode as a parameter
huntercfreeman Oct 26, 2024
5a5b2e0
DollarSignToken and AtToken
huntercfreeman Oct 26, 2024
48f6b20
Fix: variable reference node
huntercfreeman Oct 26, 2024
a4d8eb0
EmptyExpressionNode.Empty
huntercfreeman Oct 26, 2024
011937d
Remove: IScope.ResourceUri
huntercfreeman Oct 26, 2024
18dc013
Scopes use int key instead of Key<IScope>
huntercfreeman Oct 26, 2024
20b0ed2
ParseMemberAccessToken
huntercfreeman Oct 27, 2024
f6f3eb4
Fix: While loops
huntercfreeman Oct 27, 2024
c832dd4
Fix: while loops for real this time
huntercfreeman Oct 27, 2024
bfa7073
Fix: single statement code blocks
huntercfreeman Oct 27, 2024
88d0692
Parsed without any exceptions
huntercfreeman Oct 27, 2024
672c9ca
Progress: Debounce.cs
huntercfreeman Oct 28, 2024
748d7c8
Debounce works?
huntercfreeman Oct 28, 2024
a9d2fd7
Update IdeInfoDisplay.razor
huntercfreeman Oct 28, 2024
bed9b50
Merge pull request #335 from huntercfreeman/optimizations
Luthetus Oct 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions Source/Lib/Common/Reactives/Models/Debounce.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
namespace Luthetus.Common.RazorLib.Reactives.Models;

/// <summary>
/// The "starter code" for this was copy and pasted from <see cref="ThrottleOptimized"/>.
///
/// This type is meant to fire when the requests cease for some duration of time.
/// i.e.: if one continually fires a request, the <see cref="_workItem"/> will never run.
///
/// Additionally: a second requirement exists where the previously started workItem must be IsCompleted
/// before another workItem can be started.
/// i.e.: if the requests cease for some duration of time, then the previously workItem
/// is awaited. Only then will a new workItem start.
/// </summary>
public class Debounce<TArgs>
{

/*

jjjjjjj

j -> Task.Delay(DebounceTimeSpan)

j

CancellationToken share between
'j -> Task.Delay(DebounceTimeSpan)'
'taskStartWorkItem'

j ->
Task.Delay(DebounceTimeSpan, cancellationToken) ->
Task.Run();

no

j ->
Task.Run(Task.Delay(DebounceTimeSpan, cancellationToken)); ->
// if Task.Run is given the cancellationToken it will throw an exception upon cancellation
// the user probably doesn't want this information so I won't put it on the Task.Run itself.
// Otherwise every invocation would require me to start a task.
//
// Speaking of which, I need to re-use the "intent to start" task rather than stopping
// it and starting a new task.
//
// I presume this would be a massive improvement in all regards
// considering how often the debounce might fire.

j ->
Step Cancel:
CancellationTokenSource.Cancel();
if (intentToRun.IsCompleted)
{
// Begin a new intentToRun
var intentToRun = Task.Run(await () =>
{
Task.Delay(DebounceTimeSpan, cancellationToken)
});
}
else
{
}
Step Reuse:

No

TimerSpan?

Is there API to re-use the same 'CancellationTokenSource' after cancelling?

Every second, check the timespan of the most recent event.
If mostRecentEvent - CurrentTimeSpan > Delay => start work item

j ->
if (intentToRun.IsCompleted)
{
lock (eventLock)
{
_eventTimeSpan = DateTime.UtcNow;
}

// Begin a new intentToRun
IntentToRun = Task.Run(async () =>
{
// Constructor takes 'CancellationToken' so the outside and tell it to stop
while (!CancellationToken.IsCancellationRequested)
{
await Task.Delay(DebounceTimeSpan);

if (_eventTimeSpan - DateTime.UtcNow > DebounceTimeSpan)
break;
}

if (CancellationToken.IsCancellationRequested)
return;

// Await the previous workItem
await WorkItem;

WorkItem = workItemFunc.Invoke();
await WorkItem;
});
}
else
{
}
Step Reuse:

*/

private readonly object _lockWorkItemArgs = new();
private readonly Func<TArgs, CancellationToken, Task> _workItem;

/// <summary>
/// The workItem is invoked with the cancellationToken that is given to this constructor.
/// As well, the cancellationToken is used to stop the debounce checking that is done in a while loop.
/// </summary>
public Debounce(
TimeSpan debounceTimeSpan,
CancellationToken cancellationToken,
Func<TArgs, CancellationToken, Task> workItem)
{
DebounceTimeSpan = debounceTimeSpan;
CancellationToken = cancellationToken;
_workItem = workItem;
}

private TArgs _args;
private DateTime _runDateTime;

/// <summary>
/// If <see cref="TArgs"/> is a struct,
/// then a null reference for <see cref="_args"/>
/// would not suffice to know whether the <see cref="_workItemTask"/>
/// will be created or not.
///
/// A fix for this could be to move the '_workItemTask' inside the 'lock (_lockWorkItemArgs)'
/// but it is unknown as to whether this could cause concurrency issues.
///
/// Difference fix could be to mark <see cref="_args"/> as nullable with '?'.
///
/// But it is unknown as to whether this would cause issues relating to
/// using <see cref="TArgs"/> as a struct in order to optimize memory.
///
/// So, for now (until the previous points are understood fully), this bool is going
/// to be used to mark whether the '_workItemTask' will be started or not.
/// In order to permit invocations of <see cref="Run"/> to return early from the lock.
/// Yet, not have to 'Task.Run' from within the lock.
/// </summary>
private bool _intentToRun;

public Task _workItemTask = Task.CompletedTask;

public TimeSpan DebounceTimeSpan { get; }
public CancellationToken CancellationToken { get; }

public void Run(TArgs args)
{
lock (_lockWorkItemArgs)
{
_args = args;
_runDateTime = DateTime.UtcNow;
if (_intentToRun)
return;

_intentToRun = true;
}

var previousTask = _workItemTask;

_workItemTask = Task.Run(async () =>
{
// Await the previous work item task.
await previousTask.ConfigureAwait(false);

TArgs argsCapture = default;
DateTime runDateTimeCapture;

while (!CancellationToken.IsCancellationRequested)
{
await Task.Delay(DebounceTimeSpan);

lock (_lockWorkItemArgs)
{
argsCapture = _args;
runDateTimeCapture = _runDateTime;
_intentToRun = false;
}

if (DateTime.UtcNow - runDateTimeCapture > DebounceTimeSpan)
break;
}

if (CancellationToken.IsCancellationRequested)
return;

await _workItem.Invoke(argsCapture, CancellationToken)
.ConfigureAwait(false);
});
}
}
Loading