Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add UrlReference attempt number 2 #564

Merged
merged 9 commits into from Dec 20, 2019
Merged

Conversation

dfkeenan
Copy link
Contributor

@dfkeenan dfkeenan commented Dec 7, 2019

PR Details

This is an attempt to implement #390. Replacing PR #391.

Description

Add new type UrlReference and related engine and Game Studio changes.

Things to-do:

Related Issue

#390

Motivation and Context

See #390.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@dfkeenan
Copy link
Contributor Author

dfkeenan commented Dec 7, 2019

For the extension methods I did for UrlReference I used IContentManager. There are a couple of methods on the ContentManager class not on the IContentManager interface that I think would be good to make an extension method for. As far as I can tell there is only one implementation of this interface so I was wondering if it would be ok to change the interface?

The methods I am referring to are:

  • public T Get<T>(string url)
  • public bool IsLoaded(string url, bool loadedManuallyOnly = false)
  • public void Unload(string url)

@xen2 xen2 self-assigned this Dec 9, 2019
@xen2 xen2 self-requested a review December 9, 2019 14:19
@xen2 xen2 removed their assignment Dec 9, 2019
@xen2
Copy link
Member

xen2 commented Dec 9, 2019

Thanks for working again on this feature!

It might be good to also upgrade samples. I did a quick git grep of Content.Load (and also noticed a EffectSystem.LoadEffect that might benefit from it).
Note: maybe some of them can't be easily switched, I didn't look in details.

Games/JumpyJet/JumpyJet.Game/PipesScript.cs:            var pipeSetPrefab = Content.Load<Prefab>("Pipe Set");
Graphics/CustomEffect/CustomEffect.Game/CustomEffectRenderer.cs:            customEffect = EffectSystem.LoadEffect("Effect").WaitForResult();
Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/SceneStreaming.cs:                        Instance = Content.Load<Scene>(Url);
Templates/TopDownRPG/TopDownRPG/TopDownRPG.Game/Gameplay/SceneStreaming.cs:                        var localLoadingTask = loadingTask = Content.LoadAsync<Scene>(Url);
Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/Code/TutorialUI.cs:            tutorialScene = Content.Load<Scene>("Scenes/Basics/" + newTutorialScene.Value);
UI/GameMenu/GameMenu.Game/SplashScript.cs:                SceneSystem.SceneInstance.RootScene = Content.Load<Scene>("MainScene");
UI/UIElementLink/UIElementLink.Game/SplashScript.cs:            SceneSystem.SceneInstance.RootScene = Content.Load<Scene>(NextScene);

@dfkeenan
Copy link
Contributor Author

dfkeenan commented Dec 9, 2019

You are welcome. It has been a bit of a challenge but worth it I think. I have been wanting this feature for quite some time.

I should be able to upgrade the samples some time this week. Might not be until the weekend.

Not sure about EffectSystem.LoadEffect though. I had a quick look it not sure how this would work.

Regarding my proposed changes to IContentManager as stated above. Would this also be acceptable to include?

@xen2
Copy link
Member

xen2 commented Dec 10, 2019

Seems working well as far as I tested.
Glad you could figure it out -- and you found out a way that didn't require much change, all the better!
I will take a closer look at implementation but this should be good to go soon!

No problem to add some more method in IContentManager.

[DataStyle(DataStyle.Compact)]
[ReferenceSerializer]
[DataSerializer(typeof(UrlReferenceDataSerializer))]
public class UrlReference
Copy link
Member

@xen2 xen2 Dec 10, 2019

Choose a reason for hiding this comment

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

I was wondering if it wouldn't be better as a struct?
Especially since we also have to check for IsEmpty so there is two ways to have invalid values currently (either the UrlReference instance is not set, or IsEmpty is true). That might be little bit annoying to tests those two things everytime.

This would also remove lot of null check as well.
Not sure if all the converters and editor code will like it, but might be worth a try don't you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AttachedReferenceManager requires objects because it uses a ConditionalWeakTable to attach references. Ideally the UrlReference types would not have a default constructor so you could not instantiate "empty" ones. But various parts of the asset stuff and UI require a default constructor for them to work. It would require a lot more changes to accomplish this without default constructors.

I have created an interface and a base class so the UrlReference and UrlReference<T> types can both be sealed. I have also tidied up a bunch of things:

  • Fix some formatting (remove blank likes etc.)
  • Fixed/added doc comments
  • Fixed some exceptions being thrown (Had parameters around the wrong way).
  • Removed/sorted using statements
  • Added License notice to the tops of files

Copy link
Member

@xen2 xen2 Dec 18, 2019

Choose a reason for hiding this comment

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

Good point about attached reference, makes sense. Thanks!

Wondering, could we do it the other way around and forbid to use null/empty string then?
i.e. if not set in editor, UrlReference instance itself is null. If instance is set, it has to have an actual valid Url value?
This implies UrlReference wouldn't have an empty constructor anymore too.

Note: if annoying/complex, no need to do that now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did have a couple of solutions that didn't expose the default constructor that worked mostly. For example, make the default constructor internal and change how instantiation code works. I had a couple of different versions of this that "worked" but I wasn't too happy with the bits I changed.

Though I might have just thought of an option....

But even still, doing it this way meant that using collection properties i.e. List<UrlReference> don't work because the UI code cannot instantiate an instance without a default constructor. So would either have to leave this feature out or change the UI code.

Copy link
Member

Choose a reason for hiding this comment

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

That's true, let's keep it like this for now, thanks.

/// <typeparam name="T">The type off asset.</typeparam>
[DataStyle(DataStyle.Compact)]
[DataSerializer(typeof(UrlReferenceDataSerializer<>), Mode = DataSerializerGenericMode.GenericArguments)]
public sealed class UrlReference<T> : UrlReference
Copy link
Member

Choose a reason for hiding this comment

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

Same goes for this (struct).
Might need a IUrlReference with Url and IsEmpty to act as common base.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see reply above.

@dfkeenan
Copy link
Contributor Author

dfkeenan commented Dec 11, 2019

I don't think we can use a struct. That wouldn't work with the attached reference stuff. You wouldn't be able to use a struct as a key in ConditionalWeakTable.

I have put details in review response instead.

@dfkeenan
Copy link
Contributor Author

dfkeenan commented Dec 14, 2019

As suggested I have updated some of the samples/templates. I have updated:

  • All projects to 3.2.0.1-beta01
  • JumpyJet
  • TopDownRPG
  • GameMenu
  • UIElementLink
  • And the SceneStreaming script template.

Updating the SceneStreaming script template probably means I should also update the "Load scenes" documentation.

(I did not look at the CSharpBeginner tutorials.)

I have noticed some strange behaviour. Using the UrlReference on an asset does make it as referenced and includes it and it's dependencies in the build but they do not all seem to get the Green indicator:

image

In this example the "Pipe Set" Prefab is referenced as a url and it includes the "Pipe" Prefab. But is not being marked as green.

@xen2
Copy link
Member

xen2 commented Dec 18, 2019

@dfkeenan this is expected behavior. A prefab is typically design-time only since there's a full copy of it in the scene.
Thanks for the samples update.
Feel free to make the PR non-draft when you believe it's ready for last review/merge.

@dfkeenan
Copy link
Contributor Author

OK. I just never played with Prefabs before I guess. I just tried a small test in 3.1 and it does this. So I didn't break it, or at least not as bad as I thought.

I will change it to ready for review now. But I really should create unit tests.

Have you had a chance to look at the documentation PR? I had a couple of questions in there.

@dfkeenan dfkeenan marked this pull request as ready for review December 18, 2019 11:49
fd54344b6ac8b2ed232d62dc08820239: !GameMenu.SplashScript,GameMenu.Game
Id: c7c92d4b-2c04-446f-b8c5-59e9d2b989cd
NextSceneUrl: 9294c606-6173-4215-a8dc-0d5043d68333:MainScene
2f704fab49b226562874d765af6b6918: !GameMenu.SplashScript,GameMenu.Game
Copy link
Member

Choose a reason for hiding this comment

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

I suppose it's been added twice as mistake?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, not sure about that. Hope I haven't introduced some bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do kind of remember having some issues while updating the samples. Game Studio wasn't playing nice when I was changing code. Maybe I tried removing/adding the component while trying to do it. I would just remove it but you all ready merged the change.

@xen2
Copy link
Member

xen2 commented Dec 20, 2019

Pretty cool how the samples now look, with automatic type inference in the Load and the proper asset id stored in the xkscene!

@xen2 xen2 merged commit 5fd1765 into stride3d:master Dec 20, 2019
@dfkeenan dfkeenan deleted the UrlReferenceAlt branch December 20, 2019 13:42
phr00t pushed a commit to phr00t/FocusEngine that referenced this pull request Dec 20, 2019
…tride3d#390)

# Conflicts:
#	samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/CSharpBeginner.Game.csproj
#	samples/Tutorials/CSharpBeginner/CSharpBeginner/CSharpBeginner.Game/CSharpBeginner.Game.xkpkg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants