Skip to content
Merged
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
18 changes: 13 additions & 5 deletions Assets/Integration/TreeRhythmController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ public class TreeRhythmController : MonoBehaviour, IRhythmGameAdapter

[Header("Sample Tree")]
[Tooltip("Values pre-inserted into the tree before gameplay starts. Leave empty for a blank tree.")]
[SerializeField] private IntSampleTreeProvider _sampleTreeProvider;
[SerializeField] private SampleTreeProviderBase _sampleTreeProvider;

[Header("Generator")]
[Tooltip("ScriptableObject config that creates and configures the value generator. " +
"Assign IntValueGeneratorConfig or SmartIntValueGeneratorConfig.")]
[SerializeField] private IntGeneratorConfig _generatorConfig;

[Header("Layer")]
[Tooltip("Unity layer for all nodes and edges created by this controller. Set to P1Tree or P2Tree in 2P mode.")]
Expand Down Expand Up @@ -118,7 +123,7 @@ public class TreeRhythmController : MonoBehaviour, IRhythmGameAdapter
private TreeInputRhythmAdapter _rhythmInput;
private TreeRhythmReactionPolicy _reactionPolicy;
private RhythmManager _rhythmManager;
private IntValueGenerator _generator;
private IntValueGeneratorBase _generator;
private TreeLayoutManager<int> _layout;
private int _lastPulseSubdivision = -1;
private InputSystem_Actions _p2InputActions;
Expand Down Expand Up @@ -163,7 +168,9 @@ private void Awake()
var rules = new BSTInsertionRules<int>();
var hooks = new TreeAnimationHooks<int>(_animationConfig, _audioSource, () => _carrierView);
_navigator = new TreeNavigator<int>(rules, hooks);
_generator = new IntValueGenerator(_config.MinValue, _config.MaxValue);
_generator = _generatorConfig != null
? _generatorConfig.CreateGenerator()
: new IntValueGenerator();
int layer = LayerMask.NameToLayer(_treeLayerName);
_layout = new TreeLayoutManager<int>(_nodePrefab, _config, _edgeContainer, layer < 0 ? 0 : layer);

Expand Down Expand Up @@ -398,6 +405,7 @@ private void PopulateSampleTree()
TreeNode<int> node = _navigator.InsertDirect(value);
node.View = _layout.CreateNodeView(value.ToString());
node.View.SetState(NodeVisualState.Normal);
_generator.MarkUsed(value);
}

_layout.SnapToLayout(_navigator.Root);
Expand All @@ -411,8 +419,8 @@ private void PopulateSampleTree()

private void BeginNextInsertion()
{
_generator.Min = _config.MinValue;
_generator.Max = _config.MaxValue;
if (_generatorConfig != null) _generatorConfig.UpdateGenerator(_generator);
_generator.SetTreeContext(_navigator.Root);
int value = _generator.GenerateNext();
_currentInsertValue = value;
_nextInsertValue = _generator.PeekNext();
Expand Down
2,304 changes: 1,153 additions & 1,151 deletions Assets/Scenes/GameScene.unity

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions Assets/ScriptableObjects/Configs/RandomSampleTreeProvider.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 10ae8d5ed9c634489ae5a52ecb8cc4a9, type: 3}
m_Name: RandomSampleTreeProvider
m_EditorClassIdentifier:
_rootValue: 50
_targetDepth: 3
_minValue: 1
_maxValue: 99
_seed: -1

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d630d9c2233e94396ae69c7c3eef13bb, type: 3}
m_Name: SmartIntValueGeneratorConfig
m_EditorClassIdentifier:
MinValue: 1
MaxValue: 99
BiasStrength: 0.6
DepthBias: 1.5

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions Assets/Tree/Controller/TreeGameController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,20 @@ public class TreeGameController : MonoBehaviour

[Header("Sample Tree")]
[Tooltip("ScriptableObject providing values inserted silently before gameplay starts. Leave empty for a blank tree.")]
[SerializeField] private IntSampleTreeProvider _sampleTreeProvider;
[SerializeField] private SampleTreeProviderBase _sampleTreeProvider;

[Header("Generator")]
[Tooltip("ScriptableObject config that creates and configures the value generator. " +
"Assign IntValueGeneratorConfig or SmartIntValueGeneratorConfig.")]
[SerializeField] private IntGeneratorConfig _generatorConfig;

#endregion

#region Private Systems

private TreeNavigator<int> _navigator;
private UnityInputProvider _inputProvider;
private IntValueGenerator _generator;
private IntValueGeneratorBase _generator;
private TreeLayoutManager<int> _layout;

#endregion
Expand All @@ -59,7 +64,9 @@ private void Awake()
var hooks = new TreeAnimationHooks<int>(_animationConfig, _audioSource, () => _carrierView);

_navigator = new TreeNavigator<int>(rules, hooks);
_generator = new IntValueGenerator(_config.MinValue, _config.MaxValue);
_generator = _generatorConfig != null
? _generatorConfig.CreateGenerator()
: new IntValueGenerator();
_layout = new TreeLayoutManager<int>(_nodePrefab, _config, _edgeContainer);

_inputProvider = new UnityInputProvider();
Expand Down Expand Up @@ -117,6 +124,7 @@ private void PopulateSampleTree()
TreeNode<int> node = _navigator.InsertDirect(value);
node.View = _layout.CreateNodeView(value.ToString());
node.View.SetState(NodeVisualState.Normal);
_generator.MarkUsed(value);
}

_layout.SnapToLayout(_navigator.Root);
Expand All @@ -131,8 +139,8 @@ private void PopulateSampleTree()

private void BeginNextInsertion()
{
_generator.Min = _config.MinValue;
_generator.Max = _config.MaxValue;
if (_generatorConfig != null) _generatorConfig.UpdateGenerator(_generator);
_generator.SetTreeContext(_navigator.Root);
_currentInsertValue = _generator.GenerateNext();
_navigator.BeginInsertion(_currentInsertValue).Forget();
}
Expand Down
42 changes: 42 additions & 0 deletions Assets/Tree/Generation/IntGeneratorConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using UnityEngine;

/** <summary>
* Abstract ScriptableObject that acts as both a factory and a live-editable
* config for integer value generators. Assign a concrete subclass
* (<see cref="IntValueGeneratorConfig"/> or <see cref="SmartIntValueGeneratorConfig"/>)
* to the controller's <c>_generatorConfig</c> inspector slot to swap the
* active generator without touching code.
* </summary>
*/
public abstract class IntGeneratorConfig : ScriptableObject
{
#region Shared Parameters

[Header("Value Range")]
[Tooltip("Inclusive minimum value the generator will produce.")]
public int MinValue = 1;

[Tooltip("Inclusive maximum value the generator will produce.")]
public int MaxValue = 99;

#endregion

#region Factory

/** <summary>Creates and returns a new runtime generator instance.</summary> */
public abstract IntValueGeneratorBase CreateGenerator();

/** <summary>
* Pushes the current config values onto an existing generator so live
* inspector edits propagate without recreating the generator mid-session.
* Base implementation syncs <see cref="MinValue"/> and <see cref="MaxValue"/>.
* </summary>
*/
public virtual void UpdateGenerator(IntValueGeneratorBase gen)
{
gen.Min = MinValue;
gen.Max = MaxValue;
}

#endregion
}
2 changes: 2 additions & 0 deletions Assets/Tree/Generation/IntGeneratorConfig.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Assets/Tree/Generation/IntSampleTreeProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* </summary>
*/
[CreateAssetMenu(menuName = "Treeformance/IntSampleTreeProvider", fileName = "IntSampleTreeProvider")]
public class IntSampleTreeProvider : ScriptableObject, ISampleTreeProvider<int>
public class IntSampleTreeProvider : SampleTreeProviderBase
{
#region Inspector Fields

Expand All @@ -16,10 +16,10 @@ public class IntSampleTreeProvider : ScriptableObject, ISampleTreeProvider<int>

#endregion

#region ISampleTreeProvider<int>
#region SampleTreeProviderBase

/** <inheritdoc /> */
public IReadOnlyList<int> Values => _values;
public override IReadOnlyList<int> Values => _values;

#endregion
}
14 changes: 4 additions & 10 deletions Assets/Tree/Generation/IntValueGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,13 @@
* network-sourced) without changing the navigator or controller.
* </summary>
*/
public class IntValueGenerator : IValueGenerator<int>
public class IntValueGenerator : IntValueGeneratorBase
{
#region Fields

private readonly Random _random;
private int? _peeked;

/** <summary>Inclusive lower bound. Settable so live config changes propagate without recreating the generator.</summary> */
public int Min { get; set; }

/** <summary>Inclusive upper bound. Settable so live config changes propagate without recreating the generator.</summary> */
public int Max { get; set; }

#endregion

#region Constructor
Expand All @@ -39,10 +33,10 @@ public IntValueGenerator(int min = 1, int max = 99)

#endregion

#region IValueGenerator Implementation
#region IntValueGeneratorBase

/** <summary>Returns a random integer in [Min, Max].</summary> */
public int GenerateNext()
public override int GenerateNext()
{
if (_peeked.HasValue)
{
Expand All @@ -60,7 +54,7 @@ public int GenerateNext()
* Call only after Min/Max are set.
* </summary>
*/
public int PeekNext()
public override int PeekNext()
{
if (!_peeked.HasValue)
_peeked = _random.Next(Min, Max + 1);
Expand Down
44 changes: 44 additions & 0 deletions Assets/Tree/Generation/IntValueGeneratorBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/** <summary>
* Abstract base for all integer value generators.
* Provides <see cref="Min"/>, <see cref="Max"/>, and a concrete
* <see cref="PeekNext"/> contract alongside the <see cref="IValueGenerator{T}"/>
* interface, so controllers can hold a single typed field regardless of which
* generator implementation is active.
* </summary>
*/
public abstract class IntValueGeneratorBase : IValueGenerator<int>
{
/** <summary>Inclusive lower bound. Updated live by the controller each insertion.</summary> */
public int Min { get; set; }

/** <summary>Inclusive upper bound. Updated live by the controller each insertion.</summary> */
public int Max { get; set; }

/** <inheritdoc /> */
public abstract int GenerateNext();

/** <summary>
* Returns the value that the next <see cref="GenerateNext"/> call will return,
* generating and caching it if not already done. The sequence is preserved —
* the peeked value is consumed (not re-rolled) by <see cref="GenerateNext"/>.
* </summary>
*/
public abstract int PeekNext();

/** <summary>
* Provides the current tree root so implementations can analyse the BST structure.
* Called by the controller immediately before each <see cref="GenerateNext"/> /
* <see cref="PeekNext"/>. Default is a no-op for generators that do not need it.
* </summary>
*/
public virtual void SetTreeContext(TreeNode<int> root) { }

/** <summary>
* Notifies the generator that <paramref name="value"/> has already been placed
* in the tree (e.g. during pre-population), so it can exclude it from the
* "unused" pool and avoid treating it as an unseen value.
* Default is a no-op for generators without exhaustion tracking.
* </summary>
*/
public virtual void MarkUsed(int value) { }
}
2 changes: 2 additions & 0 deletions Assets/Tree/Generation/IntValueGeneratorBase.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions Assets/Tree/Generation/IntValueGeneratorConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using UnityEngine;

/** <summary>
* ScriptableObject config that creates a plain random <see cref="IntValueGenerator"/>.
* Assign via <b>Treeformance &gt; Generators &gt; IntValueGeneratorConfig</b>.
* </summary>
*/
[CreateAssetMenu(menuName = "Treeformance/Generators/IntValueGeneratorConfig",
fileName = "IntValueGeneratorConfig")]
public class IntValueGeneratorConfig : IntGeneratorConfig
{
/** <inheritdoc /> */
public override IntValueGeneratorBase CreateGenerator() =>
new IntValueGenerator(MinValue, MaxValue);
}
2 changes: 2 additions & 0 deletions Assets/Tree/Generation/IntValueGeneratorConfig.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading