Generate docs - document tags

This commit is contained in:
AdamRamberg 2019-10-15 02:08:41 +02:00
parent 9ef5f06f9e
commit 3a46454ddb
31 changed files with 1258 additions and 376 deletions

View File

@ -12,6 +12,8 @@
- Add public method `Reset` to Variables.
- Improved documentation.
- Improved examples.
- Changed name on Atomic Tags to UA Tags.
- Automatic generation of API docs in markdown format from C# XML comments.
# 1.0.0 (Mars 17, 2019)

View File

@ -37,9 +37,7 @@
{
"name": "NPM",
"url": "https://registry.npmjs.org",
"scopes": [
"com.mambojambostudios.marvelous"
]
"scopes": ["com.mambojambostudios.marvelous"]
}
],
"lock": {

View File

@ -7,6 +7,9 @@ namespace UnityAtoms
/// </summary>
public static class Runtime
{
/// <summary>
/// Runtime constants
/// </summary>
public static class Constants
{
/// <summary>

View File

@ -0,0 +1,87 @@
using System.Collections.Generic;
using UnityEngine;
using UnityAtoms;
namespace UnityAtoms.Tags
{
/// <summary>
/// `GameObject` extensions related to tags in Unity Atoms.
/// </summary>
public static class GameObjectExtensions
{
/// <summary>
/// Retrieves all tags for a given `GameObject`. A faster alternative to `gameObject.GetComponen&lt;UATags&gt;().Tags`.
/// </summary>
/// <param name="go">This `GameObject`</param>
/// <returns>
/// A `ReadOnlyList&lt;T&gt;` of tags stored as `StringContant`s. Returns `null` if the `GameObject` does not have any tags or if the `GameObject` is disabled.
/// </returns>
public static ReadOnlyList<StringConstant> GetTags(this GameObject go)
{
return UATags.GetTags(go);
}
/// <summary>
/// Check if the tag provided is associated with this `GameObject`.
/// </summary>
/// <param name="go">This `GameObject`</param>
/// <param name="tag">The tag to search for.</param>
/// <returns>`true` if the tag exists, otherwise `false`.</returns>
public static bool HasTag(this GameObject go, string tag)
{
var tags = UATags.GetTagsForGameObject(go);
if (tags == null) return false;
return tags.HasTag(tag);
}
/// <summary>
/// Check if the tag provided is associated with this `GameObject`.
/// </summary>
/// <param name="go">This `GameObject`</param>
/// <param name="tag">The tag to search for.</param>
/// <returns>`true` if the tag exists, otherwise `false`.</returns>
public static bool HasTag(this GameObject go, StringConstant tag)
{
return go.HasTag(tag.Value);
}
/// <summary>
/// Check if any of the tags provided are associated with this `GameObject`.
/// </summary>
/// <param name="go">This `GameObject`</param>
/// <param name="tags">The tags to search for.</param>
/// <returns>`true` if any of the tags exist, otherwise `false`.</returns>
public static bool HasAnyTag(this GameObject go, List<string> tags)
{
var goTags = UATags.GetTagsForGameObject(go);
if (goTags == null) return false;
for (var i = 0; i < tags.Count; i++)
{
if (goTags.HasTag(tags[i])) return true;
}
return false;
}
/// <summary>
/// Check if any of the tags provided are associated with this `GameObject`.
/// </summary>
/// <param name="go">This `GameObject`</param>
/// <param name="tags">The tags to search for.</param>
/// <returns>`true` if any of the tags exist, otherwise `false`.</returns>
public static bool HasAnyTag(this GameObject go, List<StringConstant> stringConstants)
{
// basically same method as above, the code is mostly copy and pasted because its not preferable to convert
// stringconstants to strings and calling the other method, because of memory allocation
var tags = UATags.GetTagsForGameObject(go);
if (tags == null) return false;
for (var i = 0; i < stringConstants.Count; i++)
{
if (tags.HasTag(stringConstants[i].Value)) return true;
}
return false;
}
}
}

View File

@ -1,7 +1,8 @@
{
"name": "MamboJamboStudios.UnityAtomsTags.Runtime",
"references": [
"MamboJamboStudios.UnityAtomsCore.Runtime"
"MamboJamboStudios.UnityAtomsCore.Runtime",
"MamboJamboStudios.UnityAtomsCore.Editor"
],
"optionalUnityReferences": [],
"includePlatforms": [],

View File

@ -4,19 +4,52 @@ using System.Collections.Generic;
namespace UnityAtoms.Tags
{
/// <summary>
/// This is basically an IList without everything that could mutate the list
/// This is an `IList` without everything that could mutate the it.
/// </summary>
/// <typeparam name="T">The type of the list items.</typeparam>
public class ReadOnlyList<T> : IEnumerable<T>
{
/// <summary>
/// Get the number of elements contained in the `ReadOnlyList&lt;T&gt;`.
/// </summary>
/// <value>The number of elements contained in the `ReadOnlyList&lt;T&gt;`.</value>
/// <example>
/// <code>
/// var readOnlyList = new ReadOnlyList&lt;int&gt;(new List&lt;int&gt;() { 1, 2, 3 });
/// Debug.Log(readOnlyList.Count); // Outputs: 3
/// </code>
/// </example>
public int Count { get => _referenceList.Count; }
/// <summary>
/// Determines if the `ReadOnlyList&lt;T&gt;` is read only or not.
/// </summary>
/// <value>Will always be `true`.</value>
public bool IsReadOnly { get => true; }
/// <summary>
/// Get the element at the specified index.
/// </summary>
/// <param name="index">The zero-based index of the element to get.</param>
/// <value>The element at the specified index.</value>
public T this[int index] { get => _referenceList[index]; }
private readonly IList<T> _referenceList = null;
public ReadOnlyList(IList<T> referenceList)
/// <summary>
/// Creates a new class of the `ReadOnlyList&lt;T&gt;` class.
/// </summary>
/// <param name="list">The `IList&lt;T&gt;` to initialize the `ReadOnlyList&lt;T&gt;` with.</param>
public ReadOnlyList(IList<T> list)
{
_referenceList = referenceList;
_referenceList = list;
}
#region IEnumerable<T>
/// <summary>
/// Implements `GetEnumerator()` of `IEnumerable&lt;T&gt;`
/// </summary>
/// <returns>The list's `IEnumerator&lt;T&gt;`.</returns>
public IEnumerator<T> GetEnumerator()
{
return _referenceList.GetEnumerator();
@ -29,34 +62,34 @@ namespace UnityAtoms.Tags
#endregion
/// <summary>
/// Determines whether an element is in the `ReadOnlyList&lt;T&gt;`.
/// </summary>
/// <param name="item">The item to check if it exists in the `ReadOnlyList&lt;T&gt;`.</param>
/// <returns>`true` if item is found in the `ReadOnlyList&lt;T&gt;`; otherwise, `false`.</returns>
public bool Contains(T item)
{
return _referenceList.Contains(item);
}
/// <summary>
/// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array.
/// </summary>
/// <param name="item">The one-dimensional array to search.</param>
/// <returns>The index of the first occurrence of value in array, if found; otherwise, the lower bound of the array minus 1.</returns>
public int IndexOf(T item)
{
return _referenceList.IndexOf(item);
}
/// <summary>
/// Copies all the elements of the current one-dimensional array to the specified one-dimensional array starting at the specified destination array index. The index is specified as a 32-bit integer.
/// </summary>
/// <param name="array">The one-dimensional array that is the destination of the elements copied from the current array.</param>
/// <param name="arrayIndex">A 32-bit integer that represents the index in array at which copying begins.</param>
public void CopyTo(T[] array, int arrayIndex)
{
_referenceList.CopyTo(array, arrayIndex);
}
public int Count
{
get { return _referenceList.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public T this[int index]
{
get { return _referenceList[index]; }
}
}
}

View File

@ -0,0 +1,217 @@
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityAtoms.Tags
{
/// <summary>
/// A MonoBehaviour that adds tags the Unity Atoms way to a GameObject.
/// </summary>
[EditorIcon("atom-icon-delicate")]
[AddComponentMenu("Unity Atoms/Tags")]
public sealed class UATags : MonoBehaviour, ISerializationCallbackReceiver
{
/// <summary>
/// Get the tags associated with this GameObject as `StringConstants` in a `ReadOnlyList&lt;T&gt;`.
/// </summary>
/// <value>The tags associated with this GameObject as `StringConstants` in a `ReadOnlyList&lt;T&gt;`.</value>
public ReadOnlyList<StringConstant> Tags { get; private set; }
[SerializeField]
private List<StringConstant> _tags = new List<StringConstant>();
private SortedList<string, StringConstant> _sortedTags = new SortedList<string, StringConstant>();
private static readonly Dictionary<string, List<GameObject>> TaggedGameObjects
= new Dictionary<string, List<GameObject>>();
private static readonly Dictionary<GameObject, UATags> TagInstances
= new Dictionary<GameObject, UATags>();
#region Serialization
public void OnBeforeSerialize()
{
#if UNITY_EDITOR
if (!EditorApplication.isPlaying
&& !EditorApplication.isUpdating
&& !EditorApplication.isCompiling) return;
#endif
_tags.Clear();
foreach (var kvp in _sortedTags)
{
_tags.Add(kvp.Value);
}
}
public void OnAfterDeserialize()
{
_sortedTags = new SortedList<string, StringConstant>();
for (int i = 0; i != _tags.Count; i++)
{
if (_tags[i] == null || _tags[i].Value == null) continue;
if (_sortedTags.ContainsKey(_tags[i].Value)) continue;
_sortedTags.Add(_tags[i].Value, _tags[i]);
}
}
#endregion
#if UNITY_EDITOR
private void OnValidate()
{
OnAfterDeserialize(); // removes double values and nulls
_tags = _sortedTags.Values.ToList();
// this null value is just for easier editing and could also be archived with an custom inspector
if (!EditorApplication.isPlaying) { _tags.Add(null); }
}
#endif
#region Lifecycles
private void Awake()
{
Tags = new ReadOnlyList<StringConstant>(_sortedTags.Values);
}
private void OnEnable()
{
if (!TagInstances.ContainsKey(gameObject)) TagInstances.Add(gameObject, this);
for (var i = 0; i < Tags.Count; i++)
{
var stringConstant = Tags[i];
if (stringConstant == null) continue;
var tag = stringConstant.Value;
if (!TaggedGameObjects.ContainsKey(tag)) TaggedGameObjects.Add(tag, new List<GameObject>());
TaggedGameObjects[tag].Add(gameObject);
}
}
private void OnDisable()
{
if (TagInstances.ContainsKey(gameObject)) TagInstances.Remove(gameObject);
for (var i = 0; i < Tags.Count; i++)
{
var stringConstant = Tags[i];
if (stringConstant == null) continue;
var tag = stringConstant.Value;
if (TaggedGameObjects.ContainsKey(tag)) TaggedGameObjects[tag].Remove(gameObject);
}
}
#endregion
/// <summary>
/// Check if the tag provided is associated with this `GameObject`.
/// </summary>
/// <param name="tag"></param>
/// <returns>`true` if the tag exists, otherwise `false`.</returns>
public bool HasTag(string tag)
{
if (tag == null) return false;
return _sortedTags.ContainsKey(tag);
}
/// <summary>
/// Add a tag to this `GameObject`.
/// </summary>
/// <param name="tag">The tag to add as a `StringContant`.</param>
public void AddTag(StringConstant tag)
{
if (tag == null || tag.Value == null) return;
if (_sortedTags.ContainsKey(tag.Value)) return;
_sortedTags.Add(tag.Value, tag);
Tags = new ReadOnlyList<StringConstant>(_sortedTags.Values);
// Update static accessors:
if (!TaggedGameObjects.ContainsKey(tag.Value)) TaggedGameObjects.Add(tag.Value, new List<GameObject>());
TaggedGameObjects[tag.Value].Add(this.gameObject);
}
/// <summary>
/// Remove a tag from this `GameObject`.
/// </summary>
/// <param name="tag">The tag to remove as a `string`</param>
public void RemoveTag(string tag)
{
if (tag == null) return;
if (_sortedTags.ContainsKey(tag)) return;
_sortedTags.Remove(tag);
Tags = new ReadOnlyList<StringConstant>(_sortedTags.Values);
// Update static accessors:
if (!TaggedGameObjects.ContainsKey(tag)) return; // this should never happen
TaggedGameObjects[tag].Remove(this.gameObject);
}
/// <summary>
/// Find first `GameObject` that has the tag provided.
/// </summary>
/// <param name="tag">The tag that the `GameObject` that you search for will have.</param>
/// <returns>The first `GameObject` with the provided tag found. If no `GameObject`is found, it returns `null`.</returns>
public static GameObject FindByTag(string tag)
{
if (!TaggedGameObjects.ContainsKey(tag)) return null;
return TaggedGameObjects[tag][0];
}
/// <summary>
/// Find all `GameObject`s that have the tag provided.
/// </summary>
/// <param name="tag">The tag that the `GameObject`s that you search for will have.</param>
/// <returns>An array of `GameObject`s with the provided tag. If not found it returns `null`.</returns>
public static GameObject[] FindAllByTag(string tag)
{
if (!TaggedGameObjects.ContainsKey(tag)) return null;
return TaggedGameObjects[tag].ToArray();
}
/// <summary>
/// Find all `GameObject`s that have the tag provided. Mutates the output `List&lt;GameObject&gt;` and adds the `GameObject`s found to it.
/// </summary>
/// <param name="tag">The tag that the `GameObject`s that you search for will have.</param>
/// <param name="output">A `List&lt;GameObject&gt;` that this method will clear and add the `GameObject`s found to.</param>
public static void FindAllByTagNoAlloc(string tag, List<GameObject> output)
{
output.Clear();
if (!TaggedGameObjects.ContainsKey(tag)) return;
for (var i = 0; i < TaggedGameObjects[tag].Count; ++i)
{
output.Add(TaggedGameObjects[tag][i]);
}
}
/// <summary>
/// A faster alternative to `gameObject.GetComponen&lt;UATags&gt;()`.
/// </summary>
/// <returns>
/// Returns the `UATags` component. Returns `null` if the `GameObject` does not have a `UATags` component or if the `GameObject` is disabled.
/// </returns>
public static UATags GetTagsForGameObject(GameObject go)
{
if (!TagInstances.ContainsKey(go)) return null;
return TagInstances[go];
}
/// <summary>
/// Retrieves all tags for a given `GameObject`. A faster alternative to `gameObject.GetComponen&lt;UATags&gt;().Tags`.
/// </summary>
/// <param name="go">The `GameObject` to check for tags.</param>
/// <returns>
/// A `ReadOnlyList&lt;T&gt;` of tags stored as `StringContant`s. Returns `null` if the `GameObject` does not have any tags or if the `GameObject` is disabled.
/// </returns>
public static ReadOnlyList<StringConstant> GetTags(GameObject go)
{
if (!TagInstances.ContainsKey(go)) return null;
var tags = TagInstances[go];
return tags.Tags;
}
}
}

View File

@ -5,7 +5,7 @@ MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
icon: {fileID: 2800000, guid: c3c99b8d76418472cb0261944ff3deb8, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,181 +0,0 @@
using System.Collections.Generic;
using System.Linq;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityAtoms.Tags
{
[AddComponentMenu("Unity Atoms/Tags/Atomic Tags")]
public sealed class UnityAtomsTags : MonoBehaviour, ISerializationCallbackReceiver
{
public ReadOnlyList<StringConstant> Tags { get; private set; }
private SortedList<string, StringConstant> _sortedTags = new SortedList<string, StringConstant>();
private static readonly Dictionary<string, List<GameObject>> TaggedGameObjects
= new Dictionary<string, List<GameObject>>();
private static readonly Dictionary<GameObject, UnityAtomsTags> AtomicTagInstances
= new Dictionary<GameObject, UnityAtomsTags>();
public List<StringConstant> _tags = new List<StringConstant>();
#region Serialization
public void OnBeforeSerialize()
{
#if UNITY_EDITOR
if (!EditorApplication.isPlaying
&& !EditorApplication.isUpdating
&& !EditorApplication.isCompiling) return;
#endif
_tags.Clear();
foreach (var kvp in _sortedTags)
{
_tags.Add(kvp.Value);
}
}
public void OnAfterDeserialize()
{
_sortedTags = new SortedList<string, StringConstant>();
for (int i = 0; i != _tags.Count; i++)
{
if (_tags[i] == null || _tags[i].Value == null) continue;
if (_sortedTags.ContainsKey(_tags[i].Value)) continue;
_sortedTags.Add(_tags[i].Value, _tags[i]);
}
}
#endregion
#if UNITY_EDITOR
private void OnValidate()
{
OnAfterDeserialize(); // removes double values and nulls
_tags = _sortedTags.Values.ToList();
// this null value is just for easier editing and could also be archived with an custom inspector
if (!EditorApplication.isPlaying) { _tags.Add(null); }
}
#endif
#region Lifecycle
private void Awake()
{
Tags = new ReadOnlyList<StringConstant>(_sortedTags.Values);
}
private void OnEnable()
{
if (!AtomicTagInstances.ContainsKey(gameObject)) AtomicTagInstances.Add(gameObject, this);
for (var i = 0; i < Tags.Count; i++)
{
var stringConstant = Tags[i];
if (stringConstant == null) continue;
var atomicTag = stringConstant.Value;
if (!TaggedGameObjects.ContainsKey(atomicTag)) TaggedGameObjects.Add(atomicTag, new List<GameObject>());
TaggedGameObjects[atomicTag].Add(gameObject);
}
}
private void OnDisable()
{
if (AtomicTagInstances.ContainsKey(gameObject)) AtomicTagInstances.Remove(gameObject);
for (var i = 0; i < Tags.Count; i++)
{
var stringConstant = Tags[i];
if (stringConstant == null) continue;
var atomicTag = stringConstant.Value;
if (TaggedGameObjects.ContainsKey(atomicTag)) TaggedGameObjects[atomicTag].Remove(gameObject);
}
}
#endregion
public bool HasTag(string atomicTag)
{
if (atomicTag == null) return false;
return _sortedTags.ContainsKey(atomicTag);
}
public void AddTag(StringConstant atomicTag)
{
if (atomicTag == null || atomicTag.Value == null) return;
if (_sortedTags.ContainsKey(atomicTag.Value)) return;
_sortedTags.Add(atomicTag.Value, atomicTag);
Tags = new ReadOnlyList<StringConstant>(_sortedTags.Values);
// Update static accessors:
if (!TaggedGameObjects.ContainsKey(atomicTag.Value)) TaggedGameObjects.Add(atomicTag.Value, new List<GameObject>());
TaggedGameObjects[atomicTag.Value].Add(this.gameObject);
}
public void RemoveTag(string atomicTag)
{
if (atomicTag == null) return;
if (_sortedTags.ContainsKey(atomicTag)) return;
_sortedTags.Remove(atomicTag);
Tags = new ReadOnlyList<StringConstant>(_sortedTags.Values);
// Update static accessors:
if (!TaggedGameObjects.ContainsKey(atomicTag)) return; // this should never happen
TaggedGameObjects[atomicTag].Remove(this.gameObject);
}
public static GameObject FindByTag(string tag)
{
if (!TaggedGameObjects.ContainsKey(tag)) return null;
return TaggedGameObjects[tag][0];
}
public static GameObject[] FindAllByTag(string tag)
{
if (!TaggedGameObjects.ContainsKey(tag)) return null;
return TaggedGameObjects[tag].ToArray();
}
public static void FindAllByTagNoAlloc(string tag, List<GameObject> output)
{
output.Clear();
if (!TaggedGameObjects.ContainsKey(tag)) return;
for (var i = 0; i < TaggedGameObjects[tag].Count; ++i)
{
output.Add(TaggedGameObjects[tag][i]);
}
}
/// <summary>
/// Faster alternative to go.GetComponent&lt;AtomicTags&gt;() since they are already cached in a dictionary
/// </summary>
/// <returns>
/// - null if the GameObject does not have AtomicTags or they (or the GO) are disabled
/// - the AtomicTag component
/// </returns>
public static UnityAtomsTags GetForGameObject(GameObject go)
{
if (!AtomicTagInstances.ContainsKey(go)) return null;
return AtomicTagInstances[go];
}
/// <summary>
/// Retrieves all AtomicTags for a given GameObject
/// </summary>
/// <returns>
/// - null if the GameObject does not have AtomicTags or they (or the GO) are disabled
/// - an readonly list of strings containing the tags
/// - should be faster than go.GetComponent&lt;AtomicTags&gt;().tags
/// </returns>
public static ReadOnlyList<StringConstant> GetAtomicTags(GameObject go)
{
if (!AtomicTagInstances.ContainsKey(go)) return null;
var atomicTags = AtomicTagInstances[go];
return atomicTags.Tags;
}
}
}

View File

@ -1,67 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
using UnityAtoms;
namespace UnityAtoms.Tags
{
public static class UnityAtomsTagsExtensions
{
/// <summary>
/// Retrieves all AtomicTags for a given GameObject
/// </summary>
/// <returns>
/// - null if the GameObject does not have Atomic Tags or they (or the GO) are disabled)
/// - an readonly list of strings containing the tags
/// </returns>
public static ReadOnlyList<StringConstant> GetAtomicTags(this GameObject go)
{
return UnityAtomsTags.GetAtomicTags(go);
}
/// <returns>
/// - False if the GameObject does not have the AtomicTag, else True
/// </returns>
public static bool HasTag(this GameObject go, string tag)
{
var atomicTags = UnityAtomsTags.GetForGameObject(go);
if (atomicTags == null) return false;
return atomicTags.HasTag(tag);
}
/// <returns>
/// - False if the GameObject does not have the AtomicTag, else True
/// </returns>
public static bool HasTag(this GameObject go, StringConstant stringConstant)
{
return go.HasTag(stringConstant.Value);
}
public static bool HasAnyTag(this GameObject go, List<string> strings)
{
var atomicTags = UnityAtomsTags.GetForGameObject(go);
if (atomicTags == null) return false;
for (var i = 0; i < strings.Count; i++)
{
if (atomicTags.HasTag(strings[i])) return true;
}
return false;
}
public static bool HasAnyTag(this GameObject go, List<StringConstant> stringConstants)
{
// basically same method as above, the code is mostly copy and pasted because its not preferable to convert
// stringconstants to strings and calling the other method, because of memory allocation
var atomicTags = UnityAtomsTags.GetForGameObject(go);
if (atomicTags == null) return false;
for (var i = 0; i < stringConstants.Count; i++)
{
if (atomicTags.HasTag(stringConstants[i].Value)) return true;
}
return false;
}
}
}

View File

@ -22,7 +22,7 @@ namespace UnityAtoms.Tags.Tests
public IEnumerator TestingAndProfiling()
{
var go = new GameObject();
var atomicTags = go.AddComponent<UnityAtomsTags>();
var atomicTags = go.AddComponent<UATags>();
List<string> random_tags_raw = new List<string>() { "a", "c", "e", "g", "i", "k", "m" };
random_tags_raw.OrderBy((s => Random.value)).ToList();
@ -52,10 +52,10 @@ namespace UnityAtoms.Tags.Tests
Assert.That(() => { var t1 = atomicTags.Tags[2].Value; }, Is.Not.AllocatingGCMemory());
Assert.That(() => { atomicTags.HasTag(null); }, Is.Not.AllocatingGCMemory());
Assert.AreSame(go, UnityAtomsTags.FindByTag("e"));
Assert.AreSame(go, UATags.FindByTag("e"));
using (new ProfilerMarker("MySystem.FindByTag").Auto())
{
UnityAtomsTags.FindByTag("e");
UATags.FindByTag("e");
}
// THIS:
// Assert.That(() => { var t1 = AtomicTags.FindByTag("e"); }, Is.AllocatingGCMemory());
@ -71,7 +71,7 @@ namespace UnityAtoms.Tags.Tests
using (new ProfilerMarker("MySystem.GetGlobal").Auto())
{
UnityAtomsTags.GetForGameObject(go);
UATags.GetTagsForGameObject(go);
}
Assert.AreEqual(random_tags_raw.Count, atomicTags.Tags.Count);

View File

@ -7,15 +7,9 @@
- [Usage with UniRX](./introduction/unirx.md)
- [Level up using the Generator](./introduction/generator.md)
- API
- [Actions](./api/actions.md)
- [Constants](./api/constants.md)
- [Events](./api/events.md)
- [Functions](./api/functions.md)
- [Listeners](./api/listeners.md)
- [Lists](./api/lists.md)
- [References](./api/references.md)
- [Unity Events](./api/unity-events.md)
- [Variables](./api/variables.md)
- [UnityAtoms](./api/unityatoms.md)
- [UnityAtoms.Editor](./api/unityatoms.editor.md)
- [UnityAtoms.Tags](./api/unityatoms.tags.md)
- Subpackages
- [Mobile](./subpackages/mobile.md)
- [SceneMgmt](./subpackages/scene-mgmt.md)

View File

@ -1,10 +0,0 @@
---
id: actions
title: Actions
hide_title: true
sidebar_label: Actions
---
# Actions
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: constants
title: Constants
hide_title: true
sidebar_label: Constants
---
# Constants
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: events
title: Events
hide_title: true
sidebar_label: Events
---
# Events
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: functions
title: Functions
hide_title: true
sidebar_label: Functions
---
# Functions
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: listeners
title: Listeners
hide_title: true
sidebar_label: Listeners
---
# Listeners
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: lists
title: Lists
hide_title: true
sidebar_label: Lists
---
# Lists
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: references
title: References
hide_title: true
sidebar_label: References
---
# References
[**TODO**]

View File

@ -1,10 +0,0 @@
---
id: unity-events
title: Unity Events
hide_title: true
sidebar_label: Unity Events
---
# Unity Events
[**TODO**]

View File

@ -0,0 +1,14 @@
---
id: unityatoms.editor
title: UnityAtoms.Editor
hide_title: true
sidebar_label: UnityAtoms.Editor
---
# Namespace - `UnityAtoms.Editor`
## `EditorIconPostProcessor`
Postprocessor that processes all scripts using the EditorIcon attr and assigns the matching icon guid (matching the icon query name) to the script's meta.
---

72
docs/api/unityatoms.md Normal file
View File

@ -0,0 +1,72 @@
---
id: unityatoms
title: UnityAtoms
hide_title: true
sidebar_label: UnityAtoms
---
# Namespace - `UnityAtoms`
## `IAtomActionIcon`
Use in order to determine if this is a AtomAction when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---
## `EditorIcon`
Specify a texture name from your assets which you want to be assigned as an icon to the MonoScript.
---
## `BaseAtom`
Base class for all atoms
---
## `IAtomConstantIcon`
Use in order to determine if this is a Constant when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---
## `IAtomEventIcon`
Use in order to determine if this is a Event when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---
## `IAtomFunctionIcon`
Use in order to determine if this is a Function when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---
## `IAtomListenerIcon`
Use in order to determine if this is a Listener when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---
## `IAtomListIcon`
Use in order to determine if this is a List when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---
## `Runtime`
Internal constant and static readonly members for runtime usage.
---
## `Runtime.Constants`
Runtime constants
### Variables
#### `LOG_PREFIX`
Prefix that should be pre-pended to all Debug.Logs made from UnityAtoms to help immediately inform a user that those logs are made from this library.
---
## `IAtomVariableIcon`
Use in order to determine if this is a Variable when assigning icons to Atoms. This is hack is necessary because IsAssignableFrom and IsSubclassOf doesn't work without a type constraint 💩
---

272
docs/api/unityatoms.tags.md Normal file
View File

@ -0,0 +1,272 @@
---
id: unityatoms.tags
title: UnityAtoms.Tags
hide_title: true
sidebar_label: UnityAtoms.Tags
---
# Namespace - `UnityAtoms.Tags`
## `GameObjectExtensions`
`GameObject` extensions related to tags in Unity Atoms.
### Methods
#### `GetTags(UnityEngine.GameObject)`
Retrieves all tags for a given `GameObject`. A faster alternative to `gameObject.GetComponen<UATags>().Tags`.
##### Parameters
- `go` - This `GameObject`
##### Returns
A `ReadOnlyList<T>` of tags stored as `StringContant`s. Returns `null` if the `GameObject` does not have any tags or if the `GameObject` is disabled.
---
#### `HasTag(UnityEngine.GameObject,System.String)`
Check if the tag provided is associated with this `GameObject`.
##### Parameters
- `go` - This `GameObject`
- `tag` - The tag to search for.
##### Returns
`true` if the tag exists, otherwise `false`.
---
#### `HasTag(UnityEngine.GameObject,UnityAtoms.StringConstant)`
Check if the tag provided is associated with this `GameObject`.
##### Parameters
- `go` - This `GameObject`
- `tag` - The tag to search for.
##### Returns
`true` if the tag exists, otherwise `false`.
---
#### `HasAnyTag(UnityEngine.GameObject,System.Collections.Generic.List{System.String})`
Check if any of the tags provided are associated with this `GameObject`.
##### Parameters
- `go` - This `GameObject`
- `tags` - The tags to search for.
##### Returns
`true` if any of the tags exist, otherwise `false`.
---
#### `HasAnyTag(UnityEngine.GameObject,System.Collections.Generic.List{UnityAtoms.StringConstant})`
Check if any of the tags provided are associated with this `GameObject`.
##### Parameters
- `go` - This `GameObject`
- `tags` - The tags to search for.
##### Returns
`true` if any of the tags exist, otherwise `false`.
---
## `ReadOnlyList<T>`
#### Type Parameters
- `T` - The type of the list items.
This is an `IList` without everything that could mutate the it.
### Properties
#### `Count`
Get the number of elements contained in the `ReadOnlyList<T>`.
##### Examples
```cs
var readOnlyList = new ReadOnlyList<int>(new List<int>() { 1, 2, 3 });
Debug.Log(readOnlyList.Count); // Outputs: 3
```
---
#### `IsReadOnly`
Determines if the `ReadOnlyList<T>` is read only or not.
---
#### `Item(System.Int32)`
Get the element at the specified index.
### Methods
#### `#ctor(list)`
Creates a new class of the `ReadOnlyList<T>` class.
##### Parameters
- `list` - The `IList<T>` to initialize the `ReadOnlyList<T>` with.
---
#### `GetEnumerator`
Implements `GetEnumerator()` of `IEnumerable<T>`
##### Returns
The list's `IEnumerator<T>`.
---
#### `Contains(item)`
Determines whether an element is in the `ReadOnlyList<T>`.
##### Parameters
- `item` - The item to check if it exists in the `ReadOnlyList<T>`.
##### Returns
`true` if item is found in the `ReadOnlyList<T>`; otherwise, `false`.
---
#### `IndexOf(item)`
Searches for the specified object and returns the index of its first occurrence in a one-dimensional array.
##### Parameters
- `item` - The one-dimensional array to search.
##### Returns
The index of the first occurrence of value in array, if found; otherwise, the lower bound of the array minus 1.
---
#### `CopyTo(array,arrayIndex)`
Copies all the elements of the current one-dimensional array to the specified one-dimensional array starting at the specified destination array index. The index is specified as a 32-bit integer.
##### Parameters
- `array` - The one-dimensional array that is the destination of the elements copied from the current array.
- `arrayIndex` - A 32-bit integer that represents the index in array at which copying begins.
---
## `UATags`
A MonoBehaviour that adds tags the Unity Atoms way to a GameObject.
### Properties
#### `Tags`
Get the tags associated with this GameObject as `StringConstants` in a `ReadOnlyList<T>`.
### Methods
#### `HasTag(System.String)`
Check if the tag provided is associated with this `GameObject`.
##### Parameters
- `tag` - undefined
##### Returns
`true` if the tag exists, otherwise `false`.
---
#### `AddTag(UnityAtoms.StringConstant)`
Add a tag to this `GameObject`.
##### Parameters
- `tag` - The tag to add as a `StringContant`.
---
#### `RemoveTag(System.String)`
Remove a tag from this `GameObject`.
##### Parameters
- `tag` - The tag to remove as a `string`
---
#### `FindByTag(System.String)`
Find first `GameObject` that has the tag provided.
##### Parameters
- `tag` - The tag that the `GameObject` that you search for will have.
##### Returns
The first `GameObject` with the provided tag found. If no `GameObject`is found, it returns `null`.
---
#### `FindAllByTag(System.String)`
Find all `GameObject`s that have the tag provided.
##### Parameters
- `tag` - The tag that the `GameObject`s that you search for will have.
##### Returns
An array of `GameObject`s with the provided tag. If not found it returns `null`.
---
#### `FindAllByTagNoAlloc(System.String,System.Collections.Generic.List{UnityEngine.GameObject})`
Find all `GameObject`s that have the tag provided. Mutates the output `List<GameObject>` and adds the `GameObject`s found to it.
##### Parameters
- `tag` - The tag that the `GameObject`s that you search for will have.
- `output` - A `List<GameObject>` that this method will clear and add the `GameObject`s found to.
---
#### `GetTagsForGameObject(UnityEngine.GameObject)`
A faster alternative to `gameObject.GetComponen<UATags>()`.
##### Returns
Returns the `UATags` component. Returns `null` if the `GameObject` does not have a `UATags` component or if the `GameObject` is disabled.
---
#### `GetTags(UnityEngine.GameObject)`
Retrieves all tags for a given `GameObject`. A faster alternative to `gameObject.GetComponen<UATags>().Tags`.
##### Parameters
- `go` - The `GameObject` to check for tags.
##### Returns
A `ReadOnlyList<T>` of tags stored as `StringContant`s. Returns `null` if the `GameObject` does not have any tags or if the `GameObject` is disabled.
---

269
package-lock.json generated Normal file
View File

@ -0,0 +1,269 @@
{
"name": "com.mambojambostudios.unity-atoms",
"version": "2.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"dev": true,
"requires": {
"object-keys": "^1.0.12"
}
},
"es-abstract": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.15.0.tgz",
"integrity": "sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.0",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.0",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-inspect": "^1.6.0",
"object-keys": "^1.1.1",
"string.prototype.trimleft": "^2.1.0",
"string.prototype.trimright": "^2.1.0"
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
"dev": true
},
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"dev": true
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"dev": true,
"requires": {
"has": "^1.0.1"
}
},
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"dev": true,
"requires": {
"has-symbols": "^1.0.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"object-inspect": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
"integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==",
"dev": true
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"rimraf": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
"integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
},
"string.prototype.trimleft": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
"integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"string.prototype.trimright": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
"integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"function-bind": "^1.1.1"
}
},
"util.promisify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
"integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"object.getownpropertydescriptors": "^2.0.3"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"xml2js": {
"version": "0.4.22",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz",
"integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==",
"dev": true,
"requires": {
"sax": ">=0.6.0",
"util.promisify": "~1.0.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dev": true
}
}
}

View File

@ -33,5 +33,9 @@
"/package.json.meta",
"/Packages",
"/Packages.meta"
]
],
"devDependencies": {
"rimraf": "^3.0.0",
"xml2js": "^0.4.22"
}
}

238
scripts/generateDocs.js Normal file
View File

@ -0,0 +1,238 @@
const child_process = require('child_process');
const fs = require('fs');
const xml2js = require('xml2js');
const rimraf = require('rimraf');
const path = require('path');
const run = async () => {
// Extract dlls
let dlls = [];
const parser = new xml2js.Parser();
const assemblyFile = fs.readFileSync(path.join(process.cwd(), 'Examples', 'Assembly-CSharp.csproj'));
const assemblyXml = await parser.parseStringPromise(assemblyFile);
assemblyXml.Project.ItemGroup.forEach((itemGroup) => {
if (itemGroup.Reference) {
itemGroup.Reference.forEach((ref) => {
dlls = dlls.concat(ref.HintPath);
})
}
});
const packages = ['Tags'];
// Compile code
const apiXmlName = `api.xml`;
const assemblyName = `Packages.dll`;
const cmd = `csc -recurse:${path.join(process.cwd(), 'Packages', '/*.cs')} /doc:${path.join(process.cwd(), apiXmlName)} -t:library -out:${path.join(process.cwd(), assemblyName)} -r:${dlls.join(',')}`;
child_process.execSync(cmd);
// Remove generated assembly
rimraf.sync(path.join(process.cwd(), assemblyName));
// Parse docs xml
const docsXmlFile = fs.readFileSync(path.join(process.cwd(), apiXmlName));
const docsXml = await parser.parseStringPromise(docsXmlFile);
const NAMESPACES = [
'UnityAtoms.',
'UnityAtoms.Editor.',
'UnityAtoms.Tags.',
'UnityAtoms.Tags.Editor.',
'UnityAtoms.Mobile.',
'UnityAtoms.Mobile.Editor.',
'UnityAtoms.UI.',
'UnityAtoms.UI.Editor.',
'UnityAtoms.SceneMgmt.',
'UnityAtoms.SceneMgmt.Editor.'
];
const getNamespace = (name) => {
const matches = NAMESPACES.filter((ns) => name.includes(ns));
const namespace = matches.sort((a, b) => (b.match(/./g) || []).length - (a.match(/./g) || []).length)[0];
return namespace.substring(0, namespace.length - 1);
}
const extractFromName = (name) => {
const [type, ...restOfName] = name.split(':');
const namespace = getNamespace(name);
const toReturn = { type, namespace };
if (type === 'T') {
toReturn.className = restOfName[0].substring(namespace.length + 1);
} else if (type === 'M' || type === 'P' || type === 'F') {
const rest = restOfName[0].substring(namespace.length + 1);
const indexOfFirstParenthesis = rest.indexOf('(');
let className, restName;
if (indexOfFirstParenthesis !== -1) {
const indexOfMethodNameStart = rest.substring(0, indexOfFirstParenthesis).lastIndexOf('.') + 1;
className = rest.substring(0, indexOfMethodNameStart - 1);
restName = rest.substring(indexOfMethodNameStart, rest.length);
} else {
const splitName = restOfName[0].substring(namespace.length + 1).split('.');
restName = splitName.pop();
className = splitName.join('.');
}
toReturn.className = className;
toReturn.name = restName;
}
return toReturn;
}
// EXAMPLE FORMAT:
// const prettifiedAndGroupedJsonExample = [
// {
// namespace: 'UnityAtoms',
// classes: [{
// id: 'AtomListener',
// name: 'AtomListener'
// summary: '12312312',
// methods: [{}]
// properties: [{}]
// variables: [{}]]
// }],
// }
// ];
const prettifiedAndGroupedJson = [];
// Prettify
const prettifiedXml = docsXml.doc.members[0].member.map((cur) => {
const summary = cur.summary && cur.summary[0];
const params = cur.param && cur.param.length > 0 && cur.param.map((p) => ({ name: p['$'].name, description: p['_'] }));
const returns = cur.returns && cur.returns.length > 0 && cur.returns[0];
const value = cur.value && cur.value.length > 0 && cur.value[0];
const examples = cur.example && cur.example.length > 0 && cur.example.map((ex) => ex.code[0]);
const typeparams = cur.typeparam && cur.typeparam.length > 0 && cur.typeparam.map((tp) => ({ name: tp['$'].name, description: tp['_'] }));
const extractedFromName = extractFromName(cur['$'].name);
// Add namespace and classes
let namespaceGroup = prettifiedAndGroupedJson.find((n) => n.namespace === extractedFromName.namespace);
if (!namespaceGroup) {
namespaceGroup = { namespace: extractedFromName.namespace, classes: [] };
prettifiedAndGroupedJson.push(namespaceGroup);
}
if (extractedFromName.type === 'T') {
namespaceGroup.classes.push({
id: extractedFromName.className,
name: extractedFromName.className.includes('`') && typeparams ? extractedFromName.className.replace(/`\d/, `<${typeparams.map((tp) => tp.name).join(',')}>`) : extractedFromName.className,
typeparams,
summary,
methods: [],
properties: [],
variables: [],
});
}
return { summary, params, returns, value, examples, typeparams, ...extractedFromName };
}, []);
// Add all methods, properties and variables
prettifiedXml.filter((cur) => ['M', 'F', 'P'].includes(cur.type)).forEach((cur) => {
const classGroup = prettifiedAndGroupedJson.find((n) => n.namespace === cur.namespace).classes.find((n) => n.id === cur.className);
if (classGroup) {
if (cur.type === 'M') {
if (cur.name.includes('Do(')) {
}
let name = cur.name;
if (name.includes('``') && cur.typeparams) {
name = name.replace(/``\d/, `<${cur.typeparams.map((tp) => tp.name).join(',')}>`);
}
if (name.includes('`') && cur.params) {
name = name.replace(/\(([^\)]+)\)/, `(${cur.params.map((p) => p.name).join(',')})`);
}
classGroup.methods.push({
...cur,
name,
});
} else if (cur.type === 'F') {
classGroup.variables.push(cur);
} else if (cur.type === 'P') {
classGroup.properties.push(cur);
}
}
});
const printExamples = (examples) => {
if (!examples) return '';
return `##### Examples\n\n${examples.map((example) => {
const exampleSplitOnNewline = example.split('\n');
const numSpacesFirstRow = exampleSplitOnNewline[1].search(/\S/);
const trimmedExample = exampleSplitOnNewline.map((line) => line.substring(numSpacesFirstRow)).join('\n');
return `\`\`\`cs${trimmedExample}\`\`\``;
}).join('\n\n')}\n\n`;
}
const printValues = (values = '') => {
const trimmedValues = values.replace(/\s+/g, ' ').trim();
if (!trimmedValues) return '';
return `##### Values\n\n${trimmedValues}\n\n`;
}
const printReturns = (returns = '') => {
const trimmedReturns = returns.replace(/\s+/g, ' ').trim();
if (!trimmedReturns) return '';
return `##### Returns\n\n${trimmedReturns}\n\n`;
}
const printSummary = (summary = '') => {
const trimmedSummary = summary.replace(/\s+/g, ' ').trim();
if (!trimmedSummary) return '';
return(`${trimmedSummary}\n\n`);
}
const printTypeParams = (typeparams) => {
if (!typeparams || typeparams.length <= 0) return '';
return(`#### Type Parameters\n\n${typeparams.map((tp) => `- \`${tp.name}\` - ${tp.description}`).join('\n')}\n\n`);
}
const printParameters = (params) => {
if (!params || params.length <= 0) return '';
return (`##### Parameters\n\n${params.map((param) => `- \`${param.name}\` - ${param.description}`).join('\n')}\n\n`);
}
const printVariablesSection = (variables) => {
if (!variables || variables.length <= 0) return '';
return `### Variables\n\n${variables.map((v) => {
return `\n\n#### \`${v.name}\`\n\n${printSummary(v.summary)}`;
}).join('---\n')}`;
}
const printPropertiesSection = (properties) => {
if (!properties || properties.length <= 0) return '';
return `### Properties\n\n${properties.map((prop) => {
return `#### \`${prop.name}\`\n\n${printSummary(prop.summary)}${printValues(prop.values)}${printExamples(prop.examples)}`
}).join('---\n')}`;
}
const printMethodsSection = (methods) => {
if (!methods || methods.length <= 0) return '';
return `### Methods\n\n${methods.map((method) => {
return `#### \`${method.name}\`\n\n${printSummary(method.summary)}${printTypeParams(method.typeparams)}${printParameters(method.params)}${printReturns(method.returns)}${printExamples(method.examples)}`
}).join('---\n')}`;
}
const printClasses = (classes) => {
if (!classes || classes.length <= 0) return '';
return classes.map((c) => {
return `## \`${c.name}\`\n\n${printTypeParams(c.typeparams)}${printSummary(c.summary)}${printVariablesSection(c.variables)}${printPropertiesSection(c.properties)}${printMethodsSection(c.methods)}---\n`
}).join('');
}
const printNamespace = (namespace) => `# Namespace - \`${namespace.namespace}\`\n\n${printClasses(namespace.classes)}`;
const printPageMeta = (namespace) => `---\nid: ${namespace.toLowerCase()}\ntitle: ${namespace}\nhide_title: true\nsidebar_label: ${namespace}\n---\n\n`;
// Create one MD file per namespace
prettifiedAndGroupedJson.forEach((namespace) => {
const mdPath = path.join(process.cwd(), 'docs', 'api', `${namespace.namespace.toLowerCase()}.md`);
fs.writeFileSync(mdPath, `${printPageMeta(namespace.namespace)}${printNamespace(namespace)}`);
});
// Remove generated xml
rimraf.sync(path.join(process.cwd(), apiXmlName));
}
run();

View File

@ -37,6 +37,18 @@
"title": "Unity Events",
"sidebar_label": "Unity Events"
},
"api/unityatoms.editor": {
"title": "UnityAtoms.Editor",
"sidebar_label": "UnityAtoms.Editor"
},
"api/unityatoms": {
"title": "UnityAtoms",
"sidebar_label": "UnityAtoms"
},
"api/unityatoms.tags": {
"title": "UnityAtoms.Tags",
"sidebar_label": "UnityAtoms.Tags"
},
"api/variables": {
"title": "Variables",
"sidebar_label": "Variables"

View File

@ -8,15 +8,9 @@
"introduction/unirx"
],
"API Reference": [
"api/actions",
"api/constants",
"api/events",
"api/functions",
"api/listeners",
"api/lists",
"api/references",
"api/unity-events",
"api/variables"
"api/unityatoms",
"api/unityatoms.editor",
"api/unityatoms.tags"
],
"Subpackages": [
"subpackages/mobile",

View File

@ -25,7 +25,7 @@ const siteConfig = {
// For no header links in the top nav bar -> headerLinks: [],
headerLinks: [
{ doc: 'introduction/quick-start', label: 'Quick Start' },
{ doc: 'api/actions', label: 'API' },
{ doc: 'api/unityatoms', label: 'API' },
{ href: 'https://www.github.com/AdamRamberg/unity-atoms', label: 'Github' },
],