Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
131 changes: 113 additions & 18 deletions Assets/FishNet/Runtime/Managing/Scened/SceneLookupData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using GameKit.Dependencies.Utilities;
using FishNet.Utility;
using GameKit.Dependencies.Utilities;
using System;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
Expand All @@ -24,7 +25,6 @@ public static string[] GetNames(this SceneLookupData[] datas)
return names;
}


/// <summary>
/// Returns Names from SceneLookupData.
/// </summary>
Expand All @@ -46,13 +46,33 @@ public static string[] GetNamesOnly(this SceneLookupData[] datas)
public class SceneLookupData : IEquatable<SceneLookupData>
{
/// <summary>
/// Handle of the scene. If value is 0, then handle is not used.
/// Raw handle of the scene. If value is 0, then handle is not used.
/// </summary>
public int Handle;
private ulong _rawHandle;

/// <summary>
/// Legacy 32-bit handle view.
/// </summary>
public int Handle
{
get => unchecked((int)_rawHandle);
set => _rawHandle = unchecked((uint)value);
}

/// <summary>
/// Raw scene handle value.
/// </summary>
public ulong RawHandle
{
get => _rawHandle;
set => _rawHandle = value;
}

/// <summary>
/// Name of the scene.
/// </summary>
public string Name = string.Empty;

/// <summary>
/// Returns the scene name without a directory path should one exist.
/// </summary>
Expand All @@ -62,16 +82,17 @@ public string NameOnly
{
if (string.IsNullOrEmpty(Name))
return string.Empty;

string name = System.IO.Path.GetFileName(Name);
return RemoveUnityExtension(name);
}
}

/// <summary>
/// Returns if this data is valid for use.
/// Being valid does not mean that the scene exist, rather that there is enough data to try and lookup a scene.
/// </summary>
public bool IsValid => Name != string.Empty || Handle != 0;
public bool IsValid => Name != string.Empty || RawHandle != 0;

#region Const
/// <summary>
Expand All @@ -89,7 +110,7 @@ public SceneLookupData() { }
/// <param name = "scene">Scene to generate from.</param>
public SceneLookupData(Scene scene)
{
Handle = scene.handle;
RawHandle = UnityCompatibility.GetSceneHandleRaw(scene);
Name = scene.name;
}

Expand All @@ -109,6 +130,14 @@ public SceneLookupData(int handle)
Handle = handle;
}

/// <summary>
/// </summary>
/// <param name = "handle">Raw scene handle to generate from.</param>
public SceneLookupData(ulong handle)
{
RawHandle = handle;
}

/// <summary>
/// </summary>
/// <param name = "handle">Scene handle to generate from.</param>
Expand All @@ -119,6 +148,16 @@ public SceneLookupData(int handle, string name)
Name = name;
}

/// <summary>
/// </summary>
/// <param name = "handle">Raw scene handle to generate from.</param>
/// <param name = "name">Name to generate from if handle is 0.</param>
public SceneLookupData(ulong handle, string name)
{
RawHandle = handle;
Name = name;
}

#region Comparers.
public static bool operator ==(SceneLookupData sldA, SceneLookupData sldB)
{
Expand Down Expand Up @@ -159,10 +198,10 @@ public bool Equals(SceneLookupData sld)
return false;

// True if both handles are empty.
bool bothHandlesEmpty = Handle == 0 && sld.Handle == 0;
bool bothHandlesEmpty = RawHandle == 0 && sld.RawHandle == 0;

// If both have handles and they match.
if (!bothHandlesEmpty && sld.Handle == Handle)
if (!bothHandlesEmpty && sld.RawHandle == RawHandle)
return true;
// If neither have handles and name matches.
else if (bothHandlesEmpty && sld.Name == Name)
Expand All @@ -175,7 +214,7 @@ public bool Equals(SceneLookupData sld)
public override int GetHashCode()
{
int hashCode = 2053068273;
hashCode = hashCode * -1521134295 + Handle.GetHashCode();
hashCode = hashCode * -1521134295 + RawHandle.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name);
return hashCode;
}
Expand All @@ -187,7 +226,7 @@ public override bool Equals(object obj)

public override string ToString()
{
return $"Name {Name}, Handle {Handle}";
return $"Name {Name}, Handle {RawHandle}";
// return base.ToString();
}
#endregion
Expand All @@ -214,6 +253,13 @@ public override string ToString()
/// <returns></returns>
public static SceneLookupData CreateData(int handle) => new(handle);

/// <summary>
/// Returns a new SceneLookupData.
/// </summary>
/// <param name = "scene">Raw scene handle to create from.</param>
/// <returns></returns>
public static SceneLookupData CreateData(ulong handle) => new(handle);

/// <summary>
/// Returns a SceneLookupData collection.
/// </summary>
Expand All @@ -235,6 +281,13 @@ public override string ToString()
/// <returns></returns>
public static SceneLookupData[] CreateData(List<int> handles) => CreateData(handles.ToArray());

/// <summary>
/// Returns a SceneLookupData collection.
/// </summary>
/// <param name = "handles">Raw scene handles to create from.</param>
/// <returns></returns>
public static SceneLookupData[] CreateData(List<ulong> handles) => CreateData(handles.ToArray());

/// <summary>
/// Returns a SceneLookupData collection.
/// </summary>
Expand Down Expand Up @@ -297,12 +350,12 @@ public static SceneLookupData[] ValidateData(SceneLookupData[] datas)
for (int i = 0; i < result.Count; i++)
{
bool nameMatches = result[i].Name == item.Name;
bool handleMatches = result[i].Handle == item.Handle;
bool handleMatches = result[i].RawHandle == item.RawHandle;
// Handle is the same (could be 0 handle).
if (handleMatches)
{
// If handle matches and not default then the same scene was added multiple times.
if (item.Handle != 0)
if (item.RawHandle != 0)
failingIndex = i;
}
// Name is the same.
Expand Down Expand Up @@ -365,6 +418,32 @@ public static SceneLookupData[] CreateData(int[] handles)

return result.ToArray();
}

/// <summary>
/// Returns a SceneLookupData collection.
/// </summary>
/// <param name = "handles">Raw scene handles to create from.</param>
/// <returns></returns>
public static SceneLookupData[] CreateData(ulong[] handles)
{
bool invalidFound = false;
List<SceneLookupData> result = new();
foreach (ulong item in handles)
{
if (item == 0)
{
invalidFound = true;
continue;
}

result.Add(CreateData(item));
}

if (invalidFound)
NetworkManagerExtensions.LogWarning(INVALID_SCENE);

return result.ToArray();
}
#endregion

/// <summary>
Expand All @@ -390,19 +469,19 @@ public Scene GetScene(out bool foundByHandle, bool warnIfDuplicates = true)
{
foundByHandle = false;

if (Handle == 0 && string.IsNullOrEmpty(NameOnly))
if (RawHandle == 0 && string.IsNullOrEmpty(NameOnly))
{
NetworkManagerExtensions.LogWarning("Scene handle and name is unset; scene cannot be returned.");
return default;
}

Scene result = default;

// Lookup my handle.
if (Handle != 0)
// Lookup by handle first.
if (RawHandle != 0)
{
result = SceneManager.GetScene(Handle);
if (result.handle != 0)
result = GetSceneByRawHandle(RawHandle);
if (UnityCompatibility.HasValidSceneHandle(result))
foundByHandle = true;
}

Expand All @@ -412,5 +491,21 @@ public Scene GetScene(out bool foundByHandle, bool warnIfDuplicates = true)

return result;
}

/// <summary>
/// Returns a currently loaded scene by raw scene handle.
/// </summary>
private static Scene GetSceneByRawHandle(ulong rawHandle)
{
int count = UnityEngine.SceneManagement.SceneManager.sceneCount;
for (int i = 0; i < count; i++)
{
Scene scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(i);
if (scene.IsValid() && UnityCompatibility.GetSceneHandleRaw(scene) == rawHandle)
return scene;
}

return default;
}
}
}
Loading