Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add extra logging for play mode and refresh #987

Merged
merged 1 commit into from
Jan 14, 2019
Merged
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
85 changes: 52 additions & 33 deletions unity/EditorPlugin/PluginEntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public static class PluginEntryPoint
static PluginEntryPoint()
{
PluginSettings.InitLog(); // init log before doing any logging
ourLogEventCollector = new UnityEventCollector(); // start collecting Unity messages asap
ourLogEventCollector = new UnityEventCollector(); // start collecting Unity messages asap

ourPluginSettings = new PluginSettings();
ourRiderPathLocator = new RiderPathLocator(ourPluginSettings);
var riderPath = ourRiderPathLocator.GetDefaultRiderApp(EditorPrefsWrapper.ExternalScriptEditor,
Expand Down Expand Up @@ -113,6 +113,8 @@ private static void Init()
// process csproj files once per Unity process
if (!RiderScriptableSingleton.Instance.CsprojProcessedOnce)
{
// Perform on next editor frame update, so we avoid this exception:
// "Must set an output directory through SetCompileScriptsOutputDirectory before compiling"
EditorApplication.update += SyncSolutionOnceCallBack;
}

Expand Down Expand Up @@ -153,7 +155,7 @@ private static void Init()
File.Delete(protocolInstanceJsonPath);
};

PlayModeSavedState = GetEditorState();
PlayModeSavedState = GetPlayModeState();
SetupAssemblyReloadEvents();

ourInitialized = true;
Expand Down Expand Up @@ -190,7 +192,16 @@ private static void ResetDefaultFileExtensions()
}
}

private static PlayModeState GetEditorState()
public enum PlayModeState
{
Stopped,
Playing,
Paused
}

public static PlayModeState PlayModeSavedState = PlayModeState.Stopped;

private static PlayModeState GetPlayModeState()
{
if (EditorApplication.isPaused)
return PlayModeState.Paused;
Expand All @@ -201,25 +212,26 @@ private static PlayModeState GetEditorState()

private static void SetupAssemblyReloadEvents()
{
// playmodeStateChanged was marked obsolete in 2017.1. Still working in 2018.3
#pragma warning disable 618
EditorApplication.playmodeStateChanged += () =>
#pragma warning restore 618
{
var newState = GetEditorState();
if (PlayModeSavedState != newState)
var newPlayModeState = GetPlayModeState();
if (PlayModeSavedState != newPlayModeState)
{
if (PluginSettings.AssemblyReloadSettings == AssemblyReloadSettings.RecompileAfterFinishedPlaying)
{
if (newState == PlayModeState.Playing)
if (newPlayModeState == PlayModeState.Playing)
{
EditorApplication.LockReloadAssemblies();
}
else if (newState == PlayModeState.Stopped)
else if (newPlayModeState == PlayModeState.Stopped)
{
EditorApplication.UnlockReloadAssemblies();
}
}
PlayModeSavedState = newState;
PlayModeSavedState = newPlayModeState;
}
};

Expand Down Expand Up @@ -266,12 +278,12 @@ private static void CreateProtocolAndAdvise(Lifetime lifetime, List<ProtocolInst
model.ApplicationContentsPath.SetValue(EditorApplication.applicationContentsPath);
model.ApplicationVersion.SetValue(Application.unityVersion);
model.ScriptingRuntime.SetValue(UnityUtils.ScriptingRuntime);

if (UnityUtils.UnityVersion >= new Version(2018, 2) && EditorPrefsWrapper.ScriptChangesDuringPlayOptions == 0)
model.NotifyIsRecompileAndContinuePlaying.Fire("General");
else if (UnityUtils.UnityVersion < new Version(2018, 2) && PluginSettings.AssemblyReloadSettings == AssemblyReloadSettings.RecompileAndContinuePlaying)
model.NotifyIsRecompileAndContinuePlaying.Fire("Rider");

ourLogger.Verbose("UnityModel initialized.");
var pair = new ModelWithLifetime(model, connectionLifetime);
connectionLifetime.AddAction(() => { UnityModels.Remove(pair); });
Expand All @@ -283,7 +295,8 @@ private static void CreateProtocolAndAdvise(Lifetime lifetime, List<ProtocolInst
{
ourLogger.Error("Init Rider Plugin " + ex);
}
}
}

private static void AdviseScriptCompilationDuringPlay(EditorPluginModel model, Lifetime lifetime)
{
model.SetScriptCompilationDuringPlay.AdviseNotNull(lifetime,
Expand Down Expand Up @@ -325,8 +338,11 @@ private static void AdviseRefresh(EditorPluginModel model)
{
if (force)
{
ourLogger.Verbose("Refresh: RequestScriptReload");
UnityEditorInternal.InternalEditorUtility.RequestScriptReload();
}

ourLogger.Verbose("Refresh: SyncSolution ");
UnityUtils.SyncSolution();
}
else
Expand All @@ -337,60 +353,63 @@ private static void AdviseRefresh(EditorPluginModel model)
});
}

public enum PlayModeState
{
Stopped,
Playing,
Paused
}

public static PlayModeState PlayModeSavedState = PlayModeState.Stopped;

private static void AdviseUnityActions(EditorPluginModel model, Lifetime connectionLifetime)
{
var isPlayingAction = new Action(() =>
var syncPlayState = new Action(() =>
{
MainThreadDispatcher.Instance.Queue(() =>
{
var isPlayOrWillChange = EditorApplication.isPlayingOrWillChangePlaymode;
var isPlaying = isPlayOrWillChange && EditorApplication.isPlaying;
var isPlaying = EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying;
if (!model.Play.HasValue() || model.Play.HasValue() && model.Play.Value != isPlaying)
{
ourLogger.Verbose("Reporting play mode change to model: {0}", isPlaying);
model.Play.SetValue(isPlaying);
}

var isPaused = EditorApplication.isPaused;
if (!model.Pause.HasValue() || model.Pause.HasValue() && model.Pause.Value != isPaused)
{
ourLogger.Verbose("Reporting pause mode change to model: {0}", isPaused);
model.Pause.SetValue(isPaused);
}
});
});
isPlayingAction(); // get Unity state
model.Play.AdviseNotNull(connectionLifetime, play =>

syncPlayState();

model.Play.Advise(connectionLifetime, play =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for changing AdviseNotNull to Advise here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because model.Play is an IRdProperty<bool>, so the value can't be null.

public static void AdviseNotNull<T>(this ISink<T> me, Lifetime lifetime, Action<T> handler)
{
  me.Advise(lifetime, (Action<T>) (v =>
  {
    if ((object) v == null)
      return;
    handler(v);
  }));
}

If T is a value type, then it has to have a value, but it's still cast to object (and boxed) to compare against null.

Perhaps @korifey can confirm that this change is ok?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarification.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Anyway, I guess we should add where clause to this method to suppress boxing.

{
MainThreadDispatcher.Instance.Queue(() =>
{
var res = EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying;
if (res != play)
var current = EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying;
if (current != play)
{
ourLogger.Verbose("Request to change play mode from model: {0}", play);
EditorApplication.isPlaying = play;
}
});
});

model.Pause.AdviseNotNull(connectionLifetime, pause =>
model.Pause.Advise(connectionLifetime, pause =>
{
MainThreadDispatcher.Instance.Queue(() =>
{
ourLogger.Verbose("Request to change pause mode from model: {0}", pause);
EditorApplication.isPaused = pause;
});
});

model.Step.AdviseNotNull(connectionLifetime, x =>
model.Step.Advise(connectionLifetime, x =>
{
MainThreadDispatcher.Instance.Queue(EditorApplication.Step);
});

var isPlayingHandler = new EditorApplication.CallbackFunction(() => isPlayingAction());
var onPlaymodeStateChanged = new EditorApplication.CallbackFunction(() => syncPlayState());

// left for compatibility with Unity <= 5.5
#pragma warning disable 618
connectionLifetime.AddBracket(() => { EditorApplication.playmodeStateChanged += isPlayingHandler; },
() => { EditorApplication.playmodeStateChanged -= isPlayingHandler; });
connectionLifetime.AddBracket(() => { EditorApplication.playmodeStateChanged += onPlaymodeStateChanged; },
() => { EditorApplication.playmodeStateChanged -= onPlaymodeStateChanged; });
#pragma warning restore 618
// new api - not present in Unity 5.5
// private static Action<PauseState> IsPauseStateChanged(UnityModel model)
Expand Down