···34343535 // test with test clock not elapsing
3636 double lastValue = interpolating.CurrentTime;
3737+3738 for (int i = 0; i < 100; i++)
3839 {
3940 interpolating.ProcessFrame();
···48494950 // test with test clock elapsing
5051 lastValue = interpolating.CurrentTime;
5252+5153 for (int i = 0; i < 100; i++)
5254 {
5355 source.CurrentTime += 50;
+1
osu.Framework.Tests/IO/TestDesktopStorage.cs
···1414 public void TestRelativePaths()
1515 {
1616 var guid = new Guid().ToString();
1717+1718 using (var storage = new TemporaryNativeStorage(guid))
1819 {
1920 var basePath = storage.GetFullPath(string.Empty);
+4
osu.Framework.Tests/IO/TestWebRequest.cs
···9696 List<long> startTimes = new List<long>();
97979898 List<Task> running = new List<Task>();
9999+99100 for (int i = 0; i < request_count; i++)
100101 {
101102 var request = new DelayedWebRequest
···354355 Assert.DoesNotThrow(request.Perform);
355356356357 var events = request.GetType().GetEvents(BindingFlags.Instance | BindingFlags.Public);
358358+357359 foreach (var e in events)
358360 {
359361 var field = request.GetType().GetField(e.Name, BindingFlags.Instance | BindingFlags.Public);
···368370 public void TestUnbindOnDispose([Values(true, false)] bool async)
369371 {
370372 WebRequest request;
373373+371374 using (request = new JsonWebRequest<HttpBinGetResponse>($"{default_protocol}://{host}/get")
372375 {
373376 Method = HttpMethod.Get,
···383386 }
384387385388 var events = request.GetType().GetEvents(BindingFlags.Instance | BindingFlags.Public);
389389+386390 foreach (var e in events)
387391 {
388392 var field = request.GetType().GetField(e.Name, BindingFlags.Instance | BindingFlags.Public);
+1
osu.Framework.Tests/Lists/TestArrayExtensions.cs
···123123 public void TestNonSquareJaggedWithNullRowsToRectangular()
124124 {
125125 var jagged = new int[10][];
126126+126127 for (int i = 1; i < 10; i += 2)
127128 {
128129 if (i % 2 == 1)
+3
osu.Framework.Tests/Lists/TestWeakList.cs
···4848 var list = new WeakList<object> { obj, obj2, obj3 };
49495050 int count = 0;
5151+5152 foreach (var item in list)
5253 {
5354 if (count == 1)
···6869 var list = new WeakList<object> { obj, obj2, obj3 };
69707071 int count = 0;
7272+7173 foreach (var item in list)
7274 {
7375 if (count == 0)
···9092 GC.WaitForPendingFinalizers();
91939294 int index = 0;
9595+9396 foreach (var obj in list)
9497 {
9598 if (alive[index] != obj)
···5151 case LoadState.Loading when thread != TestThread.Load:
5252 container.LoadingEvent.Set();
5353 break;
5454+5455 // Special case for the load thread: possibly active during the ready state, but the ready event is handled in the switch below
5556 case LoadState.Ready when thread == TestThread.Load:
5657 container.LoadingEvent.Set();
5758 stateToWaitFor = LoadState.Loading; // We'll never reach the ready state before the switch below
5859 break;
6060+5961 case LoadState.Ready:
6062 container.LoadingEvent.Set();
6163 container.ReadyEvent.Set();
6264 break;
6565+6366 case LoadState.Loaded:
6467 container.LoadingEvent.Set();
6568 container.ReadyEvent.Set();
···9699 AddStep("bind event", () => container.OnLoading += tryThrow);
97100 AddStep("set loading", () => container.LoadingEvent.Set());
98101 break;
102102+99103 case LoadState.Ready:
100104 AddStep("bind event", () => container.OnReady += tryThrow);
101105 AddStep("set loading", () => container.ReadyEvent.Set());
···444444 AddStep("Setup screens", () =>
445445 {
446446 screens = new List<TestScreen>();
447447+447448 for (int i = 0; i < 5; i++)
448449 {
449450 var screen = new TestScreen();
···108108 case PropertyInfo pi:
109109 action(((IBindable)pi.GetValue(targetShadowModel), (IBindable)pi.GetValue(target)));
110110 break;
111111+111112 case FieldInfo fi:
112113 action(((IBindable)fi.GetValue(targetShadowModel), (IBindable)fi.GetValue(target)));
113114 break;
+1
osu.Framework/Allocation/ObjectHandle.cs
···6767 try
6868 {
6969 var value = handle.Target;
7070+7071 if (value is T)
7172 {
7273 target = (T)value;
+2
osu.Framework/Allocation/ResolvedAttribute.cs
···7373 var activators = new List<Action<object, IReadOnlyDependencyContainer>>();
74747575 var properties = type.GetProperties(activator_flags).Where(f => f.GetCustomAttribute<ResolvedAttribute>() != null);
7676+7677 foreach (var property in properties)
7778 {
7879 if (!property.CanWrite)
···8586 var attribute = property.GetCustomAttribute<ResolvedAttribute>();
86878788 var cacheInfo = new CacheInfo(attribute.Name);
8989+8890 if (attribute.Parent != null)
8991 {
9092 // When a parent type exists, infer the property name if one is not provided
···207207 newDevice = audioDevices.Find(df => df.IsDefault).Name;
208208209209 bool oldDeviceValid = Bass.CurrentDevice >= 0;
210210+210211 if (oldDeviceValid)
211212 {
212213 DeviceInfo oldDeviceInfo = Bass.GetDeviceInfo(Bass.CurrentDevice);
···318319 {
319320 // use default device
320321 var device = Bass.GetDeviceInfo(Bass.CurrentDevice);
322322+321323 if (!device.IsDefault && !setAudioDevice())
322324 {
323325 if (!device.IsEnabled || !setAudioDevice(device.Name))
···337339 {
338340 // use whatever is the preferred device
339341 var device = Bass.GetDeviceInfo(Bass.CurrentDevice);
342342+340343 if (device.Name == AudioDevice.Value)
341344 {
342345 if (!device.IsEnabled && !setAudioDevice())
···354357 else
355358 {
356359 var preferredDevice = getAllDevices().SingleOrDefault(d => d.Name == AudioDevice.Value);
360360+357361 if (preferredDevice.Name == AudioDevice.Value && preferredDevice.IsEnabled)
358362 setAudioDevice(preferredDevice.Name);
359363 else if (!device.IsEnabled && !setAudioDevice())
+1
osu.Framework/Audio/Sample/SampleStore.cs
···3333 lock (sampleCache)
3434 {
3535 SampleChannel channel = null;
3636+3637 if (!sampleCache.TryGetValue(name, out Sample sample))
3738 {
3839 byte[] data = store.Get(name);
+3
osu.Framework/Audio/Track/Waveform.cs
···113113 // Channels are interleaved in the sample data (data[0] -> channel0, data[1] -> channel1, data[2] -> channel0, etc)
114114 // samplesPerPoint assumes this interleaving behaviour
115115 var point = new WaveformPoint(info.Channels);
116116+116117 for (int j = i; j < i + samplesPerPoint; j += info.Channels)
117118 {
118119 // Find the maximum amplitude for each channel in the point
···135136 float[] bins = new float[fft_bins];
136137 int currentPoint = 0;
137138 long currentByte = 0;
139139+138140 while (length > 0)
139141 {
140142 length = Bass.ChannelGetData(decodeStream, bins, (int)fft_samples);
···217219218220 var point = new WaveformPoint(channels);
219221 float totalWeight = 0;
222222+220223 for (int j = startIndex; j < endIndex; j++)
221224 {
222225 if (j < 0 || j >= points.Count) continue;
+1
osu.Framework/Bindables/AggregateBindable.cs
···5656 lock (sourceMapping)
5757 {
5858 var weak = findExistingWeak(bindable);
5959+5960 if (weak != null)
6061 {
6162 sourceMapping[weak].UnbindAll();
+2
osu.Framework/Bindables/Bindable.cs
···209209 case T t:
210210 Value = t;
211211 break;
212212+212213 case string s:
213214 var underlyingType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
214215···217218 else
218219 Value = (T)Convert.ChangeType(s, underlyingType, CultureInfo.InvariantCulture);
219220 break;
221221+220222 default:
221223 throw new ArgumentException($@"Could not parse provided {input.GetType()} ({input}) to {typeof(T)}.");
222224 }
+2
osu.Framework/Bindables/BindableList.cs
···350350 case null:
351351 Clear();
352352 break;
353353+353354 case IEnumerable<T> enumerable:
354355 Clear();
355356 AddRange(enumerable);
356357 break;
358358+357359 default:
358360 throw new ArgumentException($@"Could not parse provided {input.GetType()} ({input}) to {typeof(T)}.");
359361 }
···228228 case TypeCode.UInt64:
229229 case TypeCode.Int64:
230230 return true;
231231+231232 default:
232233 return false;
233234 }
···245246246247 byteBindable.Value = Convert.ToByte(val);
247248 break;
249249+248250 case TypeCode.SByte:
249251 var sbyteBindable = this as BindableNumber<sbyte>;
250252 if (sbyteBindable == null) throw new ArgumentNullException(nameof(sbyteBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
251253252254 sbyteBindable.Value = Convert.ToSByte(val);
253255 break;
256256+254257 case TypeCode.UInt16:
255258 var ushortBindable = this as BindableNumber<ushort>;
256259 if (ushortBindable == null) throw new ArgumentNullException(nameof(ushortBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
257260258261 ushortBindable.Value = Convert.ToUInt16(val);
259262 break;
263263+260264 case TypeCode.Int16:
261265 var shortBindable = this as BindableNumber<short>;
262266 if (shortBindable == null) throw new ArgumentNullException(nameof(shortBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
263267264268 shortBindable.Value = Convert.ToInt16(val);
265269 break;
270270+266271 case TypeCode.UInt32:
267272 var uintBindable = this as BindableNumber<uint>;
268273 if (uintBindable == null) throw new ArgumentNullException(nameof(uintBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
269274270275 uintBindable.Value = Convert.ToUInt32(val);
271276 break;
277277+272278 case TypeCode.Int32:
273279 var intBindable = this as BindableNumber<int>;
274280 if (intBindable == null) throw new ArgumentNullException(nameof(intBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
275281276282 intBindable.Value = Convert.ToInt32(val);
277283 break;
284284+278285 case TypeCode.UInt64:
279286 var ulongBindable = this as BindableNumber<ulong>;
280287 if (ulongBindable == null) throw new ArgumentNullException(nameof(ulongBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
281288282289 ulongBindable.Value = Convert.ToUInt64(val);
283290 break;
291291+284292 case TypeCode.Int64:
285293 var longBindable = this as BindableNumber<long>;
286294 if (longBindable == null) throw new ArgumentNullException(nameof(longBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
287295288296 longBindable.Value = Convert.ToInt64(val);
289297 break;
298298+290299 case TypeCode.Single:
291300 var floatBindable = this as BindableNumber<float>;
292301 if (floatBindable == null) throw new ArgumentNullException(nameof(floatBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
293302294303 floatBindable.Value = Convert.ToSingle(val);
295304 break;
305305+296306 case TypeCode.Double:
297307 var doubleBindable = this as BindableNumber<double>;
298308 if (doubleBindable == null) throw new ArgumentNullException(nameof(doubleBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
···313323314324 byteBindable.Value += Convert.ToByte(val);
315325 break;
326326+316327 case TypeCode.SByte:
317328 var sbyteBindable = this as BindableNumber<sbyte>;
318329 if (sbyteBindable == null) throw new ArgumentNullException(nameof(sbyteBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
319330320331 sbyteBindable.Value += Convert.ToSByte(val);
321332 break;
333333+322334 case TypeCode.UInt16:
323335 var ushortBindable = this as BindableNumber<ushort>;
324336 if (ushortBindable == null) throw new ArgumentNullException(nameof(ushortBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
325337326338 ushortBindable.Value += Convert.ToUInt16(val);
327339 break;
340340+328341 case TypeCode.Int16:
329342 var shortBindable = this as BindableNumber<short>;
330343 if (shortBindable == null) throw new ArgumentNullException(nameof(shortBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
331344332345 shortBindable.Value += Convert.ToInt16(val);
333346 break;
347347+334348 case TypeCode.UInt32:
335349 var uintBindable = this as BindableNumber<uint>;
336350 if (uintBindable == null) throw new ArgumentNullException(nameof(uintBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
337351338352 uintBindable.Value += Convert.ToUInt32(val);
339353 break;
354354+340355 case TypeCode.Int32:
341356 var intBindable = this as BindableNumber<int>;
342357 if (intBindable == null) throw new ArgumentNullException(nameof(intBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
343358344359 intBindable.Value += Convert.ToInt32(val);
345360 break;
361361+346362 case TypeCode.UInt64:
347363 var ulongBindable = this as BindableNumber<ulong>;
348364 if (ulongBindable == null) throw new ArgumentNullException(nameof(ulongBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
349365350366 ulongBindable.Value += Convert.ToUInt64(val);
351367 break;
368368+352369 case TypeCode.Int64:
353370 var longBindable = this as BindableNumber<long>;
354371 if (longBindable == null) throw new ArgumentNullException(nameof(longBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
355372356373 longBindable.Value += Convert.ToInt64(val);
357374 break;
375375+358376 case TypeCode.Single:
359377 var floatBindable = this as BindableNumber<float>;
360378 if (floatBindable == null) throw new ArgumentNullException(nameof(floatBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
361379362380 floatBindable.Value += Convert.ToSingle(val);
363381 break;
382382+364383 case TypeCode.Double:
365384 var doubleBindable = this as BindableNumber<double>;
366385 if (doubleBindable == null) throw new ArgumentNullException(nameof(doubleBindable), $"Generic type {typeof(T)} does not match actual bindable type {GetType()}.");
+1
osu.Framework/Bindables/BindableSize.cs
···60606161 Value = new Size(int.Parse(split[0]), int.Parse(split[1]));
6262 break;
6363+6364 default:
6465 base.Parse(input);
6566 break;
+2
osu.Framework/Extensions/ExtensionMethods.cs
···103103 return null;
104104105105 var jagged = new T[rectangular.GetLength(0)][];
106106+106107 for (int r = 0; r < rectangular.GetLength(0); r++)
107108 {
108109 jagged[r] = new T[rectangular.GetLength(1)];
···130131 var cols = rows == 0 ? 0 : jagged.Max(c => c?.Length ?? 0);
131132132133 var rectangular = new T[rows, cols];
134134+133135 for (int r = 0; r < rows; r++)
134136 for (int c = 0; c < cols; c++)
135137 {
+2
osu.Framework/Graphics/Animations/Animation.cs
···129129 if (IsPlaying && frameData.Count > 0)
130130 {
131131 currentFrameTime += Time.Elapsed;
132132+132133 while (currentFrameTime > frameData[currentFrameIndex].Duration)
133134 {
134135 currentFrameTime -= frameData[currentFrameIndex].Duration;
135136 ++currentFrameIndex;
137137+136138 if (currentFrameIndex >= frameData.Count)
137139 {
138140 if (Repeat)
···418418 return false;
419419420420 internalChildren.RemoveAt(index);
421421+421422 if (drawable.IsAlive)
422423 {
423424 aliveInternalChildren.Remove(drawable);
···563564 {
564565 case LoadState.NotLoaded:
565566 break;
567567+566568 case LoadState.Loading:
567569 if (Thread.CurrentThread != LoadThread)
568570 throw new InvalidThreadForChildMutationException(LoadState, "not on the load thread");
569571570572 break;
573573+571574 case LoadState.Ready:
572575 // Allow mutating from the load thread since parenting containers may still be in the loading state
573576 if (Thread.CurrentThread != LoadThread && !ThreadSafety.IsUpdateThread)
574577 throw new InvalidThreadForChildMutationException(LoadState, "not on the load or update threads");
575578576579 break;
580580+577581 case LoadState.Loaded:
578582 if (!ThreadSafety.IsUpdateThread)
579583 throw new InvalidThreadForChildMutationException(LoadState, "not on the update thread");
···985989 private static void addFromComposite(ulong frame, int treeIndex, bool forceNewDrawNode, ref int j, CompositeDrawable parentComposite, List<DrawNode> target)
986990 {
987991 SortedList<Drawable> children = parentComposite.aliveInternalChildren;
992992+988993 for (int i = 0; i < children.Count; ++i)
989994 {
990995 Drawable drawable = children[i];
···9951000 continue;
99610019971002 CompositeDrawable composite = drawable as CompositeDrawable;
10031003+9981004 if (composite?.CanBeFlattened == true)
9991005 {
10001006 if (!composite.IsMaskedAway)
···9797 protected override IEnumerable<Vector2> ComputeLayoutPositions()
9898 {
9999 var max = MaximumSize;
100100+100101 if (max == Vector2.Zero)
101102 {
102103 var s = ChildSize;
···128129129130 // First pass, computing initial flow positions
130131 Vector2 size = Vector2.Zero;
132132+131133 for (int i = 0; i < children.Length; ++i)
132134 {
133135 Drawable c = children[i];
···138140 {
139141 case FillDirection.Full:
140142 return Axes.Both;
143143+141144 case FillDirection.Horizontal:
142145 return Axes.X;
146146+143147 case FillDirection.Vertical:
144148 return Axes.Y;
149149+145150 default:
146151 throw new ArgumentException($"{direction.ToString()} is not defined");
147152 }
···192197 rowIndices[i] = rowOffsetsToMiddle.Count - 1;
193198194199 Vector2 stride = Vector2.Zero;
200200+195201 if (i < children.Length - 1)
196202 {
197203 // Compute stride. Note, that the stride depends on the origins of the drawables
···230236 + $"Consider using multiple instances of {nameof(FillFlowContainer)} if this is intentional.");
231237232238 break;
239239+233240 case FillDirection.Horizontal:
234241 if (c.RelativeAnchorPosition.X != ourRelativeAnchor.X)
235242 throw new InvalidOperationException(
···237244 + $"Consider using multiple instances of {nameof(FillFlowContainer)} if this is intentional.");
238245239246 break;
247247+240248 default:
241249 if (c.RelativeAnchorPosition != ourRelativeAnchor)
242250 throw new InvalidOperationException(
···164164 var positions = ComputeLayoutPositions().ToArray();
165165166166 int i = 0;
167167+167168 foreach (var d in FlowingChildren)
168169 {
169170 if (i > positions.Length)
···5353 // We keep track of all drawables we found while traversing the parent chain upwards.
5454 newChildDrawables.Clear();
5555 newChildDrawables.Add(candidate);
5656+5657 // When we encounter a drawable we already encountered before, then there is no need
5758 // to keep going upward, since we already recorded it previously. At that point we know
5859 // the drawables we found are in fact children of ours.
+3
osu.Framework/Graphics/Cursor/TooltipContainer.cs
···140140 base.Update();
141141142142 IHasTooltip target = findTooltipTarget();
143143+143144 if (target != null && target != currentlyDisplayed)
144145 {
145146 currentlyDisplayed = target;
···178179 return hasValidTooltip(draggedTarget) ? draggedTarget : null;
179180180181 IHasTooltip targetCandidate = FindTargets().Find(t => t.TooltipText != null);
182182+181183 // check this first - if we find no target candidate we still want to clear the recorded positions and update the lastCandidate.
182184 if (targetCandidate != lastCandidate)
183185 {
···191193 double appearDelay = (targetCandidate as IHasAppearDelay)?.AppearDelay ?? AppearDelay;
192194 // Always keep 10 positions at equally-sized time intervals that add up to AppearDelay.
193195 double positionRecordInterval = appearDelay / 10;
196196+194197 if (Time.Current - lastRecordedPositionTime >= positionRecordInterval)
195198 {
196199 lastRecordedPositionTime = Time.Current;
+24
osu.Framework/Graphics/Drawable.cs
···592592 get
593593 {
594594 Vector2 offset = Vector2.Zero;
595595+595596 if (Parent != null && RelativePositionAxes != Axes.None)
596597 {
597598 offset = Parent.RelativeChildOffset;
···844845 private void updateBypassAutoSizeAxes()
845846 {
846847 var value = RelativePositionAxes | RelativeSizeAxes | bypassAutoSizeAdditionalAxes;
848848+847849 if (bypassAutoSizeAxes != value)
848850 {
849851 var changedAxes = bypassAutoSizeAxes ^ value;
···14061408 protected InputManager GetContainingInputManager()
14071409 {
14081410 Drawable search = Parent;
14111411+14091412 while (search != null)
14101413 {
14111414 if (search is InputManager test) return test;
···17171720 internal virtual DrawNode GenerateDrawNodeSubtree(ulong frame, int treeIndex, bool forceNewDrawNode)
17181721 {
17191722 DrawNode node = drawNodes[treeIndex];
17231723+17201724 if (node == null || forceNewDrawNode)
17211725 {
17221726 drawNodes[treeIndex] = node = CreateDrawNode();
···18361840 {
18371841 case MouseMoveEvent mouseMove:
18381842 return OnMouseMove(mouseMove);
18431843+18391844 case HoverEvent hover:
18401845 return OnHover(hover);
18461846+18411847 case HoverLostEvent hoverLost:
18421848 OnHoverLost(hoverLost);
18431849 return false;
18501850+18441851 case MouseDownEvent mouseDown:
18451852 return OnMouseDown(mouseDown);
18531853+18461854 case MouseUpEvent mouseUp:
18471855 return OnMouseUp(mouseUp);
18561856+18481857 case ClickEvent click:
18491858 return OnClick(click);
18591859+18501860 case DoubleClickEvent doubleClick:
18511861 return OnDoubleClick(doubleClick);
18621862+18521863 case DragStartEvent dragStart:
18531864 return OnDragStart(dragStart);
18651865+18541866 case DragEvent drag:
18551867 return OnDrag(drag);
18681868+18561869 case DragEndEvent dragEnd:
18571870 return OnDragEnd(dragEnd);
18711871+18581872 case ScrollEvent scroll:
18591873 return OnScroll(scroll);
18741874+18601875 case FocusEvent focus:
18611876 OnFocus(focus);
18621877 return false;
18781878+18631879 case FocusLostEvent focusLost:
18641880 OnFocusLost(focusLost);
18651881 return false;
18821882+18661883 case KeyDownEvent keyDown:
18671884 return OnKeyDown(keyDown);
18851885+18681886 case KeyUpEvent keyUp:
18691887 return OnKeyUp(keyUp);
18881888+18701889 case JoystickPressEvent joystickPress:
18711890 return OnJoystickPress(joystickPress);
18911891+18721892 case JoystickReleaseEvent joystickRelease:
18731893 return OnJoystickRelease(joystickRelease);
18941894+18741895 default:
18751896 return false;
18761897 }
···20072028 private static bool get(Drawable drawable, ConcurrentDictionary<Type, bool> cache, bool positional)
20082029 {
20092030 var type = drawable.GetType();
20312031+20102032 if (!cache.TryGetValue(type, out var value))
20112033 {
20122034 value = compute(type, positional);
···20192041 private static bool compute(Type type, bool positional)
20202042 {
20212043 var inputMethods = positional ? positional_input_methods : non_positional_input_methods;
20442044+20222045 foreach (var inputMethod in inputMethods)
20232046 {
20242047 // check for any input method overrides which are at a higher level than drawable.
···20312054 }
2032205520332056 var inputInterfaces = positional ? positional_input_interfaces : non_positional_input_interfaces;
20572057+20342058 foreach (var inputInterface in inputInterfaces)
20352059 {
20362060 // check if this type implements any interface which requires a drawable to handle input.
···3131 case FrameStatisticsMode.None:
3232 this.FadeOut(100);
3333 break;
3434+3435 case FrameStatisticsMode.Minimal:
3536 case FrameStatisticsMode.Full:
3637 this.FadeIn(100);
···3131 {
3232 case ShaderType.FragmentShader:
3333 return @".fs";
3434+3435 case ShaderType.VertexShader:
3536 return @".vs";
3637 }
+3
osu.Framework/Graphics/Shaders/ShaderPart.cs
···7676 }
77777878 Match includeMatch = includeRegex.Match(line);
7979+7980 if (includeMatch.Success)
8081 {
8182 string includeName = includeMatch.Groups[1].Value.Trim();
···9394 if (Type == ShaderType.VertexShader || Type == ShaderType.VertexShaderArb)
9495 {
9596 Match inputMatch = shaderInputRegex.Match(line);
9797+9698 if (inputMatch.Success)
9799 {
98100 ShaderInputs.Add(new ShaderInputInfo
···130132 string compileLog = GL.GetShaderInfoLog(this);
131133 Log.AppendLine(string.Format('\t' + BOUNDARY, Name));
132134 Log.AppendLine($"\tCompiled: {Compiled}");
135135+133136 if (!Compiled)
134137 {
135138 Log.AppendLine("\tLog:");
+1
osu.Framework/Graphics/Textures/TextureAtlas.cs
···8585 Vector2I res = new Vector2I(0, currentY);
86868787 int maxY = currentY;
8888+8889 foreach (RectangleI bounds in subTextureBounds)
8990 {
9091 // +1 is required to prevent aliasing issues with sub-pixel positions while drawing. Bordering edged of other textures can show without it.
+1
osu.Framework/Graphics/TransformableExtensions.cs
···318318 {
319319 case Direction.Horizontal:
320320 return drawable.MoveToX(destination, duration, easing);
321321+321322 case Direction.Vertical:
322323 return drawable.MoveToY(destination, duration, easing);
323324 }
···335335 throw new InvalidOperationException($"Can not perform {nameof(Loop)} on an endless {nameof(TransformSequence<T>)}.");
336336337337 var iterDuration = endTime - startTime + pause;
338338+338339 foreach (var t in transforms)
339340 {
340341 Action tmpOnAbort = t.OnAbort;
···347348 // inserted in the correct order such that none of them trigger abortions on
348349 // each other due to instant re-sorting upon adding.
349350 double currentTransformTime = t.TargetTransformable.Time.Current;
351351+350352 while (t.EndTime <= currentTransformTime)
351353 {
352354 t.StartTime += iterDuration;
···101101 // dir is used so negative angles result in negative angularOffset.
102102 float angularOffset = dir * Math.Min(i * step, dir * angle);
103103 float normalisedOffset = angularOffset / MathHelper.TwoPi;
104104+104105 if (dir < 0)
105106 {
106107 normalisedOffset += 1.0f;
···2424 {
2525 case RuntimeInfo.Platform.MacOsx:
2626 return new MacOSGameHost(gameName, bindIPC, toolkitOptions, portableInstallation);
2727+2728 case RuntimeInfo.Platform.Linux:
2829 return new LinuxGameHost(gameName, bindIPC, toolkitOptions, portableInstallation);
3030+2931 case RuntimeInfo.Platform.Windows:
3032 return new WindowsGameHost(gameName, bindIPC, toolkitOptions, portableInstallation);
3333+3134 default:
3235 throw new InvalidOperationException($"Could not find a suitable host for the selected operating system ({Enum.GetName(typeof(RuntimeInfo.Platform), RuntimeInfo.OS)}).");
3336 }
+4
osu.Framework/IO/AsyncBufferStream.cs
···7676 return;
77777878 int last = -1;
7979+7980 while (!isLoaded && !isClosed)
8081 {
8182 cancellationToken.Token.ThrowIfCancellationRequested();
82838384 int curr = nextBlockToLoad;
8585+8486 if (curr < 0)
8587 {
8688 Thread.Sleep(1);
···211213 case SeekOrigin.Begin:
212214 Position = offset;
213215 break;
216216+214217 case SeekOrigin.Current:
215218 Position += offset;
216219 break;
220220+217221 case SeekOrigin.End:
218222 Position = data.Length + offset;
219223 break;
···5252 {
5353 int num = 0;
5454 int num2 = 0;
5555+5556 for (int i = 0; i < count; i++)
5657 {
5758 char ch = (char)bytes[offset + i];
5959+5860 if (paramEncode && ch == ' ')
5961 {
6062 num++;
···72747375 byte[] buffer = new byte[count + num2 * 2];
7476 int num4 = 0;
7777+7578 for (int j = 0; j < count; j++)
7679 {
7780 byte num6 = bytes[offset + j];
7881 char ch2 = (char)num6;
8282+7983 if (IsSafe(ch2))
8084 {
8185 buffer[num4++] = num6;
+2
osu.Framework/IO/Network/WebRequest.cs
···230230 private async Task internalPerform()
231231 {
232232 var url = Url;
233233+233234 if (!AllowInsecureRequests && !url.StartsWith(@"https://"))
234235 {
235236 logger.Add($"Insecure request was automatically converted to https ({Url})");
···459460 {
460461 // in the case we fail a request, spitting out the response in the log is quite helpful.
461462 ResponseStream.Seek(0, SeekOrigin.Begin);
463463+462464 using (StreamReader r = new StreamReader(ResponseStream, new UTF8Encoding(false, true), true, 1024, true))
463465 {
464466 try
+2
osu.Framework/IO/Stores/FontStore.cs
···4343 case FontStore fs:
4444 nestedFontStores.Add(fs);
4545 return;
4646+4647 case GlyphStore gs:
4748 glyphStores.Add(gs);
4849 queueLoad(gs);
···8586 case FontStore fs:
8687 nestedFontStores.Remove(fs);
8788 return;
8989+8890 case GlyphStore gs:
8991 glyphStores.Remove(gs);
9092 break;
···2020 if (!handler.Initialize(Host)) return;
21212222 int index = inputHandlers.BinarySearch(handler, new InputHandlerComparer());
2323+2324 if (index < 0)
2425 {
2526 index = ~index;
···141141 {
142142 case MouseButton.Left:
143143 return new MouseLeftButtonEventManager(button);
144144+144145 default:
145146 return new MouseMinorButtonEventManager(button);
146147 }
···260261 if (!(keyboardRepeatKey is Key key)) return;
261262262263 keyboardRepeatTime -= Time.Elapsed;
264264+263265 while (keyboardRepeatTime < 0)
264266 {
265267 handleKeyDown(state, key, true);
···358360 }
359361360362 d.IsHovered = true;
363363+361364 if (d.TriggerEvent(new HoverEvent(state)))
362365 {
363366 hoverHandledDrawable = d;
···430433 case MousePositionChangeEvent mousePositionChange:
431434 HandleMousePositionChange(mousePositionChange);
432435 return;
436436+433437 case MouseScrollChangeEvent mouseScrollChange:
434438 HandleMouseScrollChange(mouseScrollChange);
435439 return;
440440+436441 case ButtonStateChangeEvent<MouseButton> mouseButtonStateChange:
437442 HandleMouseButtonStateChange(mouseButtonStateChange);
438443 return;
444444+439445 case ButtonStateChangeEvent<Key> keyboardKeyStateChange:
440446 HandleKeyboardKeyStateChange(keyboardKeyStateChange);
441447 return;
448448+442449 case ButtonStateChangeEvent<JoystickButton> joystickButtonStateChange:
443450 HandleJoystickButtonStateChange(joystickButtonStateChange);
444451 return;
···518525 {
519526 //ensure we are visible
520527 CompositeDrawable d = FocusedDrawable.Parent;
528528+521529 while (d != null)
522530 {
523531 if (!d.IsPresent || !d.IsAlive)
+1
osu.Framework/Input/MouseButtonEventManager.cs
···171171172172 // only drawables up to the one that handled mouse down should handle mouse up
173173 MouseDownInputQueue = positionalInputQueue;
174174+174175 if (handledBy != null)
175176 {
176177 var count = MouseDownInputQueue.IndexOf(handledBy) + 1;
+1
osu.Framework/Input/StateChanges/ButtonInput.cs
···6565 public void Apply(InputState state, IInputStateChangeHandler handler)
6666 {
6767 var buttonStates = GetButtonStates(state);
6868+6869 foreach (var entry in Entries)
6970 {
7071 if (buttonStates.SetPressed(entry.Button, entry.IsPressed))
···2626 public void Apply(InputState state, IInputStateChangeHandler handler)
2727 {
2828 var mouse = state.Mouse;
2929+2930 if (Delta != Vector2.Zero)
3031 {
3132 var lastScroll = mouse.Scroll;
+1
osu.Framework/Logging/Logger.cs
···204204 lock (static_sync_lock)
205205 {
206206 var nameLower = name.ToLower();
207207+207208 if (!static_loggers.TryGetValue(nameLower, out Logger l))
208209 {
209210 static_loggers[nameLower] = l = Enum.TryParse(name, true, out LoggingTarget target) ? new Logger(target) : new Logger(name);
+23
osu.Framework/MathUtils/Interpolation.cs
···7373 {
7474 int n = points.Length;
7575 double[] w = new double[n];
7676+7677 for (int i = 0; i < n; i++)
7778 {
7879 w[i] = 1;
···257258 case Easing.In:
258259 case Easing.InQuad:
259260 return time * time;
261261+260262 case Easing.Out:
261263 case Easing.OutQuad:
262264 return time * (2 - time);
265265+263266 case Easing.InOutQuad:
264267 if (time < .5) return time * time * 2;
265268···267270268271 case Easing.InCubic:
269272 return time * time * time;
273273+270274 case Easing.OutCubic:
271275 return --time * time * time + 1;
276276+272277 case Easing.InOutCubic:
273278 if (time < .5) return time * time * time * 4;
274279···276281277282 case Easing.InQuart:
278283 return time * time * time * time;
284284+279285 case Easing.OutQuart:
280286 return 1 - --time * time * time * time;
287287+281288 case Easing.InOutQuart:
282289 if (time < .5) return time * time * time * time * 8;
283290···285292286293 case Easing.InQuint:
287294 return time * time * time * time * time;
295295+288296 case Easing.OutQuint:
289297 return --time * time * time * time * time + 1;
298298+290299 case Easing.InOutQuint:
291300 if (time < .5) return time * time * time * time * time * 16;
292301···294303295304 case Easing.InSine:
296305 return 1 - Math.Cos(time * Math.PI * .5);
306306+297307 case Easing.OutSine:
298308 return Math.Sin(time * Math.PI * .5);
309309+299310 case Easing.InOutSine:
300311 return .5 - .5 * Math.Cos(Math.PI * time);
301312302313 case Easing.InExpo:
303314 return Math.Pow(2, 10 * (time - 1));
315315+304316 case Easing.OutExpo:
305317 return -Math.Pow(2, -10 * time) + 1;
318318+306319 case Easing.InOutExpo:
307320 if (time < .5) return .5 * Math.Pow(2, 20 * time - 10);
308321···310323311324 case Easing.InCirc:
312325 return 1 - Math.Sqrt(1 - time * time);
326326+313327 case Easing.OutCirc:
314328 return Math.Sqrt(1 - --time * time);
329329+315330 case Easing.InOutCirc:
316331 if ((time *= 2) < 1) return .5 - .5 * Math.Sqrt(1 - time * time);
317332···319334320335 case Easing.InElastic:
321336 return -Math.Pow(2, -10 + 10 * time) * Math.Sin((1 - elastic_const2 - time) * elastic_const);
337337+322338 case Easing.OutElastic:
323339 return Math.Pow(2, -10 * time) * Math.Sin((time - elastic_const2) * elastic_const) + 1;
340340+324341 case Easing.OutElasticHalf:
325342 return Math.Pow(2, -10 * time) * Math.Sin((.5 * time - elastic_const2) * elastic_const) + 1;
343343+326344 case Easing.OutElasticQuarter:
327345 return Math.Pow(2, -10 * time) * Math.Sin((.25 * time - elastic_const2) * elastic_const) + 1;
346346+328347 case Easing.InOutElastic:
329348 if ((time *= 2) < 1)
330349 return -.5 * Math.Pow(2, -10 + 10 * time) * Math.Sin((1 - elastic_const2 * 1.5 - time) * elastic_const / 1.5);
···333352334353 case Easing.InBack:
335354 return time * time * ((back_const + 1) * time - back_const);
355355+336356 case Easing.OutBack:
337357 return --time * time * ((back_const + 1) * time + back_const) + 1;
358358+338359 case Easing.InOutBack:
339360 if ((time *= 2) < 1) return .5 * time * time * ((back_const2 + 1) * time - back_const2);
340361···350371 return 1 - (7.5625 * (time -= 2.25 * bounce_const) * time + .9375);
351372352373 return 1 - (7.5625 * (time -= 2.625 * bounce_const) * time + .984375);
374374+353375 case Easing.OutBounce:
354376 if (time < bounce_const)
355377 return 7.5625 * time * time;
···359381 return 7.5625 * (time -= 2.25 * bounce_const) * time + .9375;
360382361383 return 7.5625 * (time -= 2.625 * bounce_const) * time + .984375;
384384+362385 case Easing.InOutBounce:
363386 if (time < .5) return .5 - .5 * ApplyEasing(Easing.OutBounce, 1 - time * 2);
364387
+4
osu.Framework/MathUtils/PathApproximator.cs
···5252 while (toFlatten.Count > 0)
5353 {
5454 Vector2[] parent = toFlatten.Pop();
5555+5556 if (bezierIsFlatEnough(parent))
5657 {
5758 // If the control points we currently operate on are sufficiently "flat", we use
···155156 // AC B lies.
156157 Vector2 orthoAtoC = c - a;
157158 orthoAtoC = new Vector2(orthoAtoC.Y, -orthoAtoC.X);
159159+158160 if (Vector2.Dot(orthoAtoC, b - a) < 0)
159161 {
160162 dir = -dir;
···211213212214 float minX = controlPoints[0].X;
213215 float maxX = controlPoints[0].X;
216216+214217 for (int i = 1; i < controlPoints.Length; i++)
215218 {
216219 minX = Math.Min(minX, controlPoints[i].X);
···293296 l[count + i] = r[i + 1];
294297295298 output.Add(controlPoints[0]);
299299+296300 for (int i = 1; i < count - 1; ++i)
297301 {
298302 int index = 2 * i;
+3
osu.Framework/Physics/RigidBodyContainer.cs
···127127 float usableLength = Math.Max(length - 2 * cornerRadius, 0);
128128129129 Vector2 normal = (b - a).PerpendicularRight.Normalized();
130130+130131 for (int j = 0; j < amount_side_steps; ++j)
131132 {
132133 Vertices.Add(a + dir * (cornerRadius + j * usableLength / (amount_side_steps - 1)));
···135136 }
136137137138 const int amount_corner_steps = 10;
139139+138140 if (cornerRadius > 0)
139141 {
140142 // Rounded corners
···207209 return false;
208210209211 bool didCollide = false;
212212+210213 for (int i = 0; i < Vertices.Count; ++i)
211214 {
212215 if (other.BodyContains(Vector2Extensions.Transform(Vertices[i], SimulationToScreenSpace)))
+4
osu.Framework/Platform/DesktopGameWindow.cs
···176176 case Input.ConfineMouseMode.Fullscreen:
177177 confine = WindowMode.Value != Configuration.WindowMode.Windowed;
178178 break;
179179+179180 case Input.ConfineMouseMode.Always:
180181 confine = true;
181182 break;
···202203 try
203204 {
204205 inWindowModeTransition = true;
206206+205207 switch (newMode)
206208 {
207209 case Configuration.WindowMode.Fullscreen:
···210212211213 WindowState = WindowState.Fullscreen;
212214 break;
215215+213216 case Configuration.WindowMode.Borderless:
214217 if (lastFullscreenDisplay != null)
215218 RestoreResolution(lastFullscreenDisplay);
···222225 ClientSize = new Size(currentDisplay.Bounds.Width + 1, currentDisplay.Bounds.Height + 1);
223226 Location = currentDisplay.Bounds.Location;
224227 break;
228228+225229 case Configuration.WindowMode.Windowed:
226230 if (lastFullscreenDisplay != null)
227231 RestoreResolution(lastFullscreenDisplay);
···249249 case Configuration.WindowMode.Windowed:
250250 currentValue = Configuration.WindowMode.Borderless;
251251 break;
252252+252253 case Configuration.WindowMode.Borderless:
253254 currentValue = Configuration.WindowMode.Fullscreen;
254255 break;
256256+255257 case Configuration.WindowMode.Fullscreen:
256258 currentValue = Configuration.WindowMode.Windowed;
257259 break;
+1
osu.Framework/Platform/Linux/Native/Library.cs
···2222 public static void Load(string library, LoadFlags flags)
2323 {
2424 var paths = (string)AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES");
2525+2526 foreach (var path in paths.Split(':'))
2627 {
2728 if (dlopen(Path.Combine(path, library), flags) != IntPtr.Zero)
+1
osu.Framework/Platform/MacOS/MacOSGameWindow.cs
···130130 {
131131 // update the window mode if we have an update queued
132132 WindowMode? mode = pendingWindowMode;
133133+133134 if (mode.HasValue)
134135 {
135136 pendingWindowMode = null;
···8383 {
8484 int requested = Math.Min(width, height);
8585 int closest = -1;
8686+8687 for (int i = 0; i < iconDir.Count; i++)
8788 {
8889 var entry = iconDir.Entries[i];
···4646 throw new InvalidCastException($"The test runner must be a {nameof(Game)}.");
47474848 runTask = Task.Factory.StartNew(() => host.Run(game), TaskCreationOptions.LongRunning);
4949+4950 while (!game.IsLoaded)
5051 {
5152 checkForErrors();