using System;
using UnityEngine;
using UnityEngine.Perception.Randomization.Samplers;
namespace UnityEngine.Perception.Randomization.Parameters
{
///
/// Parameters, in conjunction with a parameter configuration, are used to create convenient interfaces for
/// randomizing simulations.
///
[Serializable]
public abstract class Parameter
{
///
/// Returns the display name of a parameter type
///
/// A subclass of Parameter
/// The parameter type's display name
public static string GetDisplayName(Type type)
{
return type.Name.Replace("Parameter", "");
}
[HideInInspector, SerializeField] internal bool collapsed;
///
/// The name of the parameter
///
[HideInInspector] public string name = "Parameter";
///
/// The target this parameter apply a sample to
///
[HideInInspector, SerializeField] public ParameterTarget target = new ParameterTarget();
///
/// Indicates whether this parameter has a target GameObject
///
public bool hasTarget => target.gameObject != null;
///
/// The sample type generated by this parameter
///
public abstract Type sampleType { get; }
///
/// An array containing a reference to each sampler field in this parameter
///
public abstract ISampler[] samplers { get; }
///
/// Constructs a new parameter
///
protected Parameter()
{
InitializeSamplers();
}
///
/// Deterministically ensures that no sampler shares the same seed when a parameter is initialized
///
void InitializeSamplers()
{
var i = 0;
foreach (var sampler in samplers)
{
sampler.Rebase(SamplerUtility.IterateSeed((uint)i++, SamplerUtility.largePrime));
sampler.ResetState();
}
}
internal void RandomizeSamplers()
{
foreach (var sampler in samplers)
{
sampler.Rebase(SamplerUtility.GenerateRandomSeed());
sampler.ResetState();
}
}
///
/// Resets sampler states and then offsets those states using the current scenario iteration
///
/// The current scenario iteration
public void ResetState(int scenarioIteration)
{
foreach (var sampler in samplers)
sampler.ResetState(scenarioIteration);
}
///
/// Applies one sampled value to this parameters assigned target gameobject
///
internal abstract void ApplyToTarget(int seedOffset);
///
/// Validates parameter settings
///
internal virtual void Validate()
{
if (hasTarget)
{
if (target.component == null)
throw new ParameterValidationException($"Null component target on parameter \"{name}\"");
if (string.IsNullOrEmpty(target.propertyName))
throw new ParameterValidationException($"Invalid property target on parameter \"{name}\"");
}
}
}
}