Skip to content

Commit

Permalink
scene handle value type no longer GC allocs & interfcae comment fixed…
Browse files Browse the repository at this point in the history
… & value type renamed
  • Loading branch information
Saeed Barari committed Jul 22, 2023
1 parent 833617a commit 9f3e92d
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 25 deletions.
2 changes: 1 addition & 1 deletion BContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public sealed class BContext : MonoBehaviour {
[SerializeReference] internal List<BoxedValueHolder> StructDependencies_Serialized = new( 8 );


[NonSerialized] readonly List<ValueHolder> _structDependencies = new( 8 );
[NonSerialized] readonly List<IValueHolder> _structDependencies = new( 8 );
[NonSerialized] readonly HashSet<Type> _dependencyTypes = new( 16 );
[NonSerialized] bool _initialized;

Expand Down
35 changes: 17 additions & 18 deletions BinjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static BContext FindContext<T>(Transform transform, ushort groupNumber =
}

// check topmost scene root context
if (_topMostScene != sceneHandle) {
if (_topMostScene.Equals( sceneHandle )) {
var root = _sceneContexts[_topMostScene][0];
if (isCorrectGroup( root, groupNumber ) && root.HasDependency<T>())
return root;
Expand Down Expand Up @@ -157,11 +157,12 @@ internal static void AddContext(BContext context) {
Debug.Log( $"adding {context.name}({context.gameObject.scene.name}). all: {CreateStringListOfAllContexts()}" );
#endif
// add to lists
var sceneHandle = new SceneHandle( context.gameObject.scene.handle );
if (!_groupedContexts.TryGetValue( context.Group, out var glist ))
_groupedContexts[context.Group] = glist = new List<BContext>( 4 );
glist.Add( context );
if (!_sceneContexts.TryGetValue( new( context.gameObject.scene ), out var slist ))
_sceneContexts[new( context.gameObject.scene )] = slist = new List<BContext>( 4 );
if (!_sceneContexts.TryGetValue( sceneHandle, out var slist ))
_sceneContexts[sceneHandle] = slist = new List<BContext>( 4 );
slist.Add( context );

UpdateAllRootContextsAndTopmostScene();
Expand All @@ -177,13 +178,12 @@ internal static void RemoveContext(BContext context) {
bool changed = false;

// remove from lists
var sceneHandle = new SceneHandle( context.gameObject.scene.handle );
if (_groupedContexts.TryGetValue( context.Group, out var glist )) {
changed = glist.Remove( context );
if (changed && glist.Count == 0)
_groupedContexts.Remove( context.Group );
}

var sceneHandle = new SceneHandle( context.gameObject.scene );
if (_sceneContexts.TryGetValue( sceneHandle, out var slist )) {
changed |= slist.Remove( context );
if (changed && slist.Count == 0)
Expand Down Expand Up @@ -235,14 +235,14 @@ static void UpdateAllRootContextsAndTopmostScene() {
Dictionary<Scene, int> sceneOrder = new( SceneManager.sceneCount );
bool foundTopmostScene = false;
for (int i = 0; i < SceneManager.sceneCount; i++) {
var scene = SceneManager.GetSceneAt( i );
var sceneHandle = new SceneHandle( scene );
sceneOrder[scene] = i;
sceneOrder[SceneManager.GetSceneAt( i )] = i;

// resolving topmost scene right here
var scene = SceneManager.GetSceneAt( i );
var sceneHandle = new SceneHandle( scene );
if (!foundTopmostScene && _sceneContexts.ContainsKey( sceneHandle )) {
#if B_DEBUG
if (_topMostScene != sceneHandle) Debug.Log( $"Topmost scene changed: {scene.name}" );
if (_topMostScene.Equals( sceneHandle )) Debug.Log( $"Topmost scene changed: {scene.name}" );
#endif
_topMostScene = sceneHandle;
foundTopmostScene = true;
Expand Down Expand Up @@ -389,16 +389,15 @@ public static void GetDependency<T1, T2, T3, T4>(this Component component, out T
}


internal readonly struct SceneHandle {
readonly int _value;
public SceneHandle(Scene scene) => _value = scene.handle;

public override bool Equals(object obj) => obj is SceneHandle other && Equals( other );
public override int GetHashCode() => _value;
public static bool operator ==(SceneHandle a, SceneHandle b) => a.Equals( b );
public static bool operator !=(SceneHandle a, SceneHandle b) => !a.Equals( b );
internal readonly struct SceneHandle : IEquatable<SceneHandle> {
public readonly int Value;
public SceneHandle(Scene scene) => Value = scene.handle;
public SceneHandle(int handle) => Value = handle;

[MethodImpl( MethodImplOptions.AggressiveInlining )]
public override int GetHashCode() => Value;

[MethodImpl( MethodImplOptions.AggressiveInlining )]
bool Equals(SceneHandle other) => _value == other._value;
public bool Equals(SceneHandle other) => Value == other.Value;
}
}
2 changes: 1 addition & 1 deletion Editor/BContextEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void SetupStructList() {
prop.isExpanded = EditorGUI.BeginFoldoutHeaderGroup(
position: rect,
foldout: prop.isExpanded,
content: ((ValueHolder)prop.managedReferenceValue).GetValueType().ToString(),
content: ((IValueHolder)prop.managedReferenceValue).GetValueType().ToString(),
menuAction: rect => {
var menu = new GenericMenu();
menu.AddItem( new GUIContent( "Remove" ), false, () => {
Expand Down
4 changes: 2 additions & 2 deletions Interfaces.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
namespace Binject {

/// <summary>
/// Marks the implementing class as one that has a custom editor to be drawn with. It's only useful alongside
/// <see cref="IBDependency"/>.
/// Marks the implementing class as one that has a custom editor to be drawn with. It'll only work with types that
/// are not inherited from <see cref="UnityEngine.Object"/>.
/// </summary>
public interface IBHasCustomDrawer { }

Expand Down
6 changes: 3 additions & 3 deletions RealValueHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using UnityEngine;

namespace Binject {
internal interface ValueHolder {
internal interface IValueHolder {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
public Type GetValueType();

Expand All @@ -15,7 +15,7 @@ internal interface ValueHolder {
}

[Serializable]
internal class BoxedValueHolder : ValueHolder {
internal class BoxedValueHolder : IValueHolder {
[SerializeReference] public object Value;

public BoxedValueHolder(object value) => Value = value;
Expand All @@ -28,7 +28,7 @@ internal interface ITest<T>{ }


[Serializable]
internal struct RealValueHolder<T> : ValueHolder {
internal struct RealValueHolder<T> : IValueHolder {
public T Value;
public RealValueHolder(T value) => Value = value;
public Type GetValueType() => typeof(T);
Expand Down

0 comments on commit 9f3e92d

Please sign in to comment.