Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
229beb5
Began looking into the prospect of supporting transitions with params
PaulNonatomic Aug 25, 2024
ee83d05
Transitions with params are functional. I want to explore explicit co…
PaulNonatomic Aug 25, 2024
8e51535
Working on transitions with params
PaulNonatomic Sep 9, 2024
5aec08e
Merge branch 'develop' into feat/transitions-with-params
PaulNonatomic Sep 10, 2024
36ac34b
Added support for switching models on SubStateMachineStates
PaulNonatomic Sep 10, 2024
5f94178
Merge remote-tracking branch 'refs/remotes/origin/develop' into develop
PaulNonatomic Sep 10, 2024
d7db6ec
Merge branch 'develop' into feat/transitions-with-params
PaulNonatomic Sep 10, 2024
6bf940f
I think i've landed on a good implementation. Implemented type safe t…
PaulNonatomic Sep 11, 2024
a8c2c1b
Merge pull request #110 from PaulNonatomic/main
PaulNonatomic Sep 11, 2024
ef3db60
Changed the HandleDeleteSelection method in StateGraphView to remove …
PaulNonatomic Sep 11, 2024
da4577e
Fix for deletion of selected items from context menu
PaulNonatomic Sep 17, 2024
ff89f12
Added selection deletion from context menu
PaulNonatomic Sep 17, 2024
5330d0d
Merge pull request #112 from PaulNonatomic/feat/delete-selected
PaulNonatomic Sep 17, 2024
48deb85
Added validation for typed ports
PaulNonatomic Sep 17, 2024
137978e
Abstracted validation
PaulNonatomic Sep 17, 2024
9b4eff1
brough the NodeGraphStateManager updates in
PaulNonatomic Sep 19, 2024
8a2f2a7
Scheduler
PaulNonatomic Sep 19, 2024
aa2f14e
Updated validation
PaulNonatomic Sep 19, 2024
ebf8cb2
Making progress. Issue with adding transitin data for netry node to T…
PaulNonatomic Sep 19, 2024
f0d9939
Fix for type comparison to creat transitions and fix for executing en…
PaulNonatomic Sep 20, 2024
55eda5c
Updated the package.json to include tests
PaulNonatomic Sep 20, 2024
aada53d
Updated change log and package manifest to include additional notes a…
PaulNonatomic Sep 20, 2024
dfe9772
Updated the readme
PaulNonatomic Sep 20, 2024
e0a8104
Updated the Readme
PaulNonatomic Sep 20, 2024
1ee0810
Update README.md
PaulNonatomic Sep 20, 2024
a40b07c
Added a counter with target state
PaulNonatomic Sep 20, 2024
d62946f
Merge branch 'release/0.9.0-beta' of github.com:PaulNonatomic/VisualS…
PaulNonatomic Sep 20, 2024
8930321
Updated chage log
PaulNonatomic Sep 20, 2024
f9da36a
Simplified the uss by importing shared styles
PaulNonatomic Sep 23, 2024
88895c2
uss is now simplified
PaulNonatomic Sep 23, 2024
171bf45
Merge pull request #113 from PaulNonatomic/feat/0.9.0/uss-simplified
PaulNonatomic Sep 23, 2024
9775a1d
Removed a preprocessor
PaulNonatomic Sep 23, 2024
6b4fb67
Updated the readme
PaulNonatomic Sep 23, 2024
a9977f1
Updated the Readme to include migration steps
PaulNonatomic Sep 23, 2024
83798d4
Changed the naming process of entry ports
PaulNonatomic Sep 23, 2024
845be4c
Further refactoring of method names
PaulNonatomic Sep 23, 2024
82a708a
Added additional icons
PaulNonatomic Nov 18, 2024
d105e04
Added support for LateUpdate in States
PaulNonatomic Dec 22, 2024
ab68cd0
Added a cache for event info obtained via reflection to reduce the us…
PaulNonatomic Dec 22, 2024
d27134e
Merge pull request #120 from PaulNonatomic/feat/0.9.0-beta/state-api-…
PaulNonatomic Dec 22, 2024
329fd13
Update README.md
PaulNonatomic Dec 22, 2024
d0c1f3b
Added a migration tool for upgrading to 0.9.0-beta
PaulNonatomic Dec 22, 2024
be02ec0
Merge pull request #121 from PaulNonatomic/feat/0.9.0-beta/state-api-…
PaulNonatomic Dec 22, 2024
880cb6a
Added back the obsolete methods to improve migration
PaulNonatomic Dec 22, 2024
bf68cf8
Added additional obsolete methods back in to support migration
PaulNonatomic Dec 22, 2024
824ed96
Updated the changelog
PaulNonatomic Dec 22, 2024
80c6d2e
updated package.json
PaulNonatomic Dec 22, 2024
c2ae5a0
Added a migration step to transition validation
PaulNonatomic Dec 22, 2024
d07a81a
.
PaulNonatomic Dec 22, 2024
ca2b992
Added a method to migrate node ports
PaulNonatomic Dec 22, 2024
cc4998d
Added support for migrating all state machine models
PaulNonatomic Dec 22, 2024
5bf9f16
.
PaulNonatomic Dec 22, 2024
38f2d59
.
PaulNonatomic Dec 23, 2024
e0014fe
.
PaulNonatomic Dec 23, 2024
dc625ee
added support for migrating generic states
PaulNonatomic Dec 23, 2024
d01f21f
Finalised migration tool
PaulNonatomic Dec 23, 2024
47a7801
Updated migration tools
PaulNonatomic Dec 23, 2024
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
8 changes: 8 additions & 0 deletions .idea/indexLayout.xml

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

13 changes: 13 additions & 0 deletions .idea/material_theme_project_new.xml

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

7 changes: 7 additions & 0 deletions .idea/projectSettingsUpdater.xml

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

6 changes: 6 additions & 0 deletions .idea/vcs.xml

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

81 changes: 81 additions & 0 deletions .idea/workspace.xml

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

29 changes: 28 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Change Log

# [0.9.4-beta] - Dec 22, 2024
- Added a method to migrate all state machine model assets

# [0.9.3-beta] - Dec 22, 2024
- Added a migration step to fix transitions to OnEnterState methods

# [0.9.2-beta] - Dec 22, 2024
- Added a migration step to add missing using statements

# [0.9.1-beta] - Dec 22, 2024
- Added a migration tool to upgrade to 0.9.1-beta
- Added obsolete methods back in and marked as obsolete to allow for a smoother migration to the new version
- Added support for LateUpdate in states
- Added a cache for event info obtained via reflection to reduce the runtime overhead of reflection

# [0.9.0-beta] - Sept 20, 2024
- BREAKING - State enter methods now require an [Enter] attribute.
- States now support typed transitions
- Example ```[Transition] public event Action<int> OnTransitionWithInt```
- Example ```[Enter] public void OnEnterWithInt(int value){}```
- Abstracted validation methods to a separate class
- Added a CounterWithTargetState.
- Simplified the uss files used to style the basic states

# [0.8.5-beta] - Sept 17, 2024
- Fix for deleting a selection via the context menu

## [0.8.4-beta] - Sept 11, 2024
- SharedData.ClearData is now Obsolete and will be removed in a future release. Use SharedData.ClearAllData instead.
- Added SharedData.ClearAllData method to clear all shared data.
Expand Down Expand Up @@ -67,7 +94,7 @@ Added support for switching SubStateMachine models at runtime

## [0.5.1-beta] - Jul 18, 2024
- Added a protected setter to the Model accessor of BaseSubStateMachineState
- This will allow for derived states to switch the model in the OnAwakeState
- This will allow for derived states to switch the model in the OnAwake

## [0.5.0-beta] - Jul 17, 2024
- Removal of the StateMachineController.Model setter.
Expand Down
3 changes: 3 additions & 0 deletions Editor/Migration.meta

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

70 changes: 70 additions & 0 deletions Editor/Migration/MethodAttributeInserter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Text.RegularExpressions;

namespace Nonatomic.VSM2.Editor.Migration
{
public static class MethodAttributeInserter
{
/*
* Explanation of this pattern (in Multiline mode):
*
* ^(?<indent>[^\S\r\n]*)
* - '^[^\S\r\n]*' means at the start of a line (^), capture any whitespace
* that is *not* a newline or carriage return. (i.e. spaces or tabs)
*
* (?<body>(\[[^\]]*\]\s*)*(public|protected|private|internal)?\s*
* (virtual|abstract|override|static|sealed|async|\s)*[^\s]+\s+
* (<METHOD_NAME_HERE>)\s*\([^)]*\)\s*\{)
* - Captures the rest of the line (any existing attributes, modifiers, method name, etc.)
* - <METHOD_NAME_HERE> is a placeholder that we'll replace with the actual method name.
*
* RegexOptions.Multiline => '^' and '$' match the start/end of *each* line in the input.
*/
private static readonly Regex _methodRegexTemplate = new Regex(
@"^(?<indent>[^\S\r\n]*)(?<body>(\[[^\]]*\]\s*)*(public|protected|private|internal)?\s*(virtual|abstract|override|static|sealed|async|\s)*[^\s]+\s+(<METHOD_NAME_HERE>)\s*\([^)]*\)\s*\{)",
RegexOptions.Compiled | RegexOptions.Multiline
);

/// <summary>
/// Inserts <paramref name="attributeToInsert"/> above each matching method (by exact name),
/// preserving indentation and ensuring no duplicate attributes or extra blank lines.
/// </summary>
public static string InsertAttributeAboveMethod(
string sourceCode,
string methodName,
string attributeToInsert)
{
if (string.IsNullOrEmpty(sourceCode)) return sourceCode;
if (string.IsNullOrEmpty(methodName)) return sourceCode;
if (string.IsNullOrEmpty(attributeToInsert)) return sourceCode;

// Build a new regex by substituting the actual method name
var pattern = _methodRegexTemplate
.ToString()
.Replace("<METHOD_NAME_HERE>", Regex.Escape(methodName));

var methodRegex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.Multiline);

// Perform the replacement
return methodRegex.Replace(sourceCode, match =>
{
var indent = match.Groups["indent"].Value; // Only spaces or tabs
var body = match.Groups["body"].Value;

// If we already have the attribute in the body, don't add it again
if (body.Contains(attributeToInsert))
{
return match.Value;
}

/*
* We rebuild:
* <indent>[Attribute]
* <indent>public void OnEnter() {
* ...
* }
*/
return $"{indent}{attributeToInsert}\n{indent}{body}";
});
}
}
}
3 changes: 3 additions & 0 deletions Editor/Migration/MethodAttributeInserter.cs.meta

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

73 changes: 73 additions & 0 deletions Editor/Migration/MigrationUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using UnityEngine;
using UnityEditor;
using System;
using System.IO;

public static class MigrationUtils
{
public static string GetPathForType(Type type)
{
var guids = AssetDatabase.FindAssets("t:MonoScript");

// Figure out the "base" name if this is an open generic type definition
var isOpenGeneric = type.IsGenericTypeDefinition;
var strippedBaseName = isOpenGeneric ? StripBacktick(type.Name) : null;

foreach (var guid in guids)
{
var path = AssetDatabase.GUIDToAssetPath(guid);

// 1. If we see an open generic, fallback to checking filename
if (isOpenGeneric && !string.IsNullOrEmpty(strippedBaseName))
{
var fileName = Path.GetFileName(path);
if (fileName.Equals(strippedBaseName + ".cs", StringComparison.OrdinalIgnoreCase))
{
var fullPath = Application.dataPath.Replace("Assets", "") + path;
if (File.Exists(fullPath))
{
return fullPath;
}
}
}

// 2. Otherwise, do the usual closed-generic / normal type check
var monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
if (monoScript == null) continue;

var scriptClass = monoScript.GetClass();
if (scriptClass == null) continue;

if (IsSameOrOpenGenericEquivalent(scriptClass, type))
{
var fullPath = Application.dataPath.Replace("Assets", "") + path;
if (File.Exists(fullPath))
{
return fullPath;
}
}
}

Debug.LogWarning($"Could not find a .cs file for type: {type.FullName}");
return null;
}

private static bool IsSameOrOpenGenericEquivalent(Type scriptClass, Type targetType)
{
if (scriptClass.IsGenericType && targetType.IsGenericType)
{
return scriptClass.GetGenericTypeDefinition() == targetType.GetGenericTypeDefinition();
}

return scriptClass == targetType;
}

private static string StripBacktick(string typeName)
{
// e.g. "RoundListState`1" => "RoundListState"
var index = typeName.IndexOf('`');
return (index >= 0)
? typeName.Substring(0, index)
: typeName;
}
}
3 changes: 3 additions & 0 deletions Editor/Migration/MigrationUtils.cs.meta

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

70 changes: 70 additions & 0 deletions Editor/Migration/StateMachineMigrator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using Nonatomic.VSM2.StateGraph;
using Nonatomic.VSM2.Utils;
using UnityEditor;
using UnityEngine;

namespace Nonatomic.VSM2.Editor.Migration
{
public static class StateMachineMigrator
{
public static void Migrate(StateMachineModel stateMachineModel)
{
if (GuardUtils.GuardAgainstRuntimeOperation()) return;

MigrateNodePorts(stateMachineModel);
MigrateTransitions(stateMachineModel);
SaveModel(stateMachineModel);
}

private static void SaveModel(StateMachineModel stateMachineModel)
{
Debug.Log($"Flag as dirty: {stateMachineModel.name}");
EditorUtility.SetDirty(stateMachineModel);
}

private static void MigrateTransitions(StateMachineModel stateMachineModel)
{
if (GuardUtils.GuardAgainstRuntimeOperation()) return;

for (var index = stateMachineModel.Transitions.Count - 1; index >= 0; index--)
{
var transition = stateMachineModel.Transitions[index];

// Handle migration (Older state machines had an OnEnterState method)
if (transition.DestinationNodeId == "OnEnterState")
{
transition.DestinationNodeId = "OnEnter";
}

if(transition.DestinationPort.Id == "OnEnterState")
{
transition.DestinationPort.Id = "OnEnter";
}
}
}

private static void MigrateNodePorts(StateMachineModel stateMachineModel)
{
if (GuardUtils.GuardAgainstRuntimeOperation()) return;

foreach (var node in stateMachineModel.Nodes)
{
foreach (var port in node.InputPorts)
{
if(port.Id == "OnEnterState")
{
port.Id = "OnEnter";
}
}

foreach (var port in node.OutputPorts)
{
if(port.Id == "OnEnterState")
{
port.Id = "OnEnter";
}
}
}
}
}
}
Loading