Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Hybrid View

  1. #1
    Join Date
    Aug 2010
    Posts
    158

    Small bug in the proxy generation code

    For anyone else who is concerned. I found a small bug in the Proxy Generator code that was causing any return types that are generic to create invalid markup which will cause a compiler issue.

    Lets say for example you wanted to use the the ComponentInterface systems with a method that return
    Code:
    Deferred<IEnumerable<object>> GetSomeObjects();
    In the generator code we do a regex test to get the return type and if it is a Deferred<T> we pull out the generic type of the return type. In the example above "IEnumerable<object>". The problem is that we key on a closing ">" for the regex test and that means that we would pull out "IEnumerable<object" which would break the compilation. All we have to do is add a single character to our regex to fix this. Adding a "$" after the ">" will take care of this. ("(.*?)Deferred(<(.+?)>$)?"). This will ensure that we are at the end of the string at that point so the ">" before must be the closing ">". I commented in the code below where the issue lies.

    Code:
    using Microsoft.CodeAnalysis.CSharp;
    using Microsoft.CodeAnalysis.CSharp.Syntax;
    using MMO.Base;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    namespace MMO.Tools.ProxyGenerator
    {
        public class ProxySyntaxAnalyzer : CSharpSyntaxWalker
        {
            //private static readonly Regex ReturnTypeRegex = new Regex("(.*?)Deferred(<(.+?)>)?", RegexOptions.Compiled);
            private static readonly Regex ReturnTypeRegex = new Regex("(.*?)Deferred(<(.+?)>$)?", RegexOptions.Compiled);
    
            ...
    
            private Tuple<MappedMethodReturnType, string> GetMethodReturnType(MethodDeclarationSyntax method)
            {
                var returnType = method.ReturnType.ToString();
    
                if (returnType == "void")
                    return Tuple.Create(MappedMethodReturnType.Void, (string)null);
    
                var match = ReturnTypeRegex.Match(returnType);
                if (!match.Success)
                    throw new InvalidOperationException($"Method {method.Identifier} does not have a valid return type (found {returnType})");
    
                var resultType = match.Result("$3"); // This is where it causes issues. We match on group 3 which originally doesn't have the closing '>'
                if (string.IsNullOrWhiteSpace(resultType))
                    return Tuple.Create(MappedMethodReturnType.Response, (string)null);
    
                return Tuple.Create(MappedMethodReturnType.ResponseWithResult, resultType);
            }
        }
    }

  2. #2
    Join Date
    Nov 2006
    Location
    Vancouver, WA
    Posts
    236
    Thanks,
    I changed mine to match yours but mine was Regex("(.*?Deferred)(<(.+?)>)?", RegexOptions.Compiled)
    I do remember having issues on this line and spent much time on it.

  3. #3
    Join Date
    Feb 2014
    Posts
    277
    Yep mine had same as Matroblend and same as Nelson:

    Code:
    nelson's
    private static readonly Regex ReturnTypeRegex = new Regex("(.*?Deferred)(<(.+?)>)?", RegexOptions.Compiled);
    am385's
    private static readonly Regex ReturnTypeRegex = new Regex("(.*?)Deferred(<(.+?)>$)?", RegexOptions.Compiled);
    Have you tried Nelson's string (which is different from your commented out code) in the regex tester at https://regex101.com/?
    Last edited by oldngrey; 05-06-2017 at 07:15 AM.

  4. #4
    Join Date
    Aug 2010
    Posts
    158
    Thanks for the response, I was able to figure out what was going on.

    So it looks like I made a typo when watching the video. I can't believe I was that far off though. That being said, Nelson's will work for a simple generic as tested with with regex101 (same site I use for all my regex testing) like
    Code:
    Deferred<IEnumerable<object>>
    but would still fail on a more complex type like
    Code:
    Deferred<IEnumerable<IEnumerable<object>>>
    We can combine them though like
    Code:
    (.*?Deferred)(<(.+?)>$)?
    and get a fuller match that includes all of the groups if we need them as well as enclosing the generic types.

    Here is the combined match.
    Match 1
    Full match 0-42 `Deferred<IEnumerable<IEnumerable<object>>>`
    Group 1. 0-8 `Deferred`
    Group 2. 8-42 `<IEnumerable<IEnumerable<object>>>`
    Group 3. 9-41 `IEnumerable<IEnumerable<object>>`
    For reference
    Here is Nelsons match
    Match 1
    Full match 0-40 `Deferred<IEnumerable<IEnumerable<object>`
    Group 1. 0-8 `Deferred`
    Group 2. 8-40 `<IEnumerable<IEnumerable<object>`
    Group 3. 9-39 `IEnumerable<IEnumerable<object`
    Here is my match
    Match 1
    Full match 0-42 `Deferred<IEnumerable<IEnumerable<object>>>`
    Group 1. 0-0 ``
    Group 2. 8-42 `<IEnumerable<IEnumerable<object>>>`
    Group 3. 9-41 `IEnumerable<IEnumerable<object>>`

  5. #5
    Join Date
    Nov 2006
    Location
    Vancouver, WA
    Posts
    236
    So is it your recommendation to use (.*?Deferred)(<(.+?)>$)?

  6. #6
    Join Date
    Aug 2010
    Posts
    158
    It adds the ability to get a match group on 1 if we ever need to use it as well as getting a match group on 3 which is what we are extracting as the return type.

    That's what I am going with and it is working for me.

  7. #7
    Join Date
    Feb 2014
    Posts
    277
    Great.
    What I will do, if you don't mind, is to add it to the end of my series about "doin' the MMO vids again" along with your ideas for the Photon 4 upgrade. Full credit where due etc.

  8. #8
    Join Date
    Aug 2010
    Posts
    158
    Of course, feel free to do so. I think it would be good to document it in a single place when it is related.

    At this point my project is starting to look different from the base one but any updates I have to the base project I will write up a post and you can add what you need to your thread that documents all of the areas of the mmo videos.

    So far I have
    • Using Photon 4
    • Updated everything that can be updated to .Net 4.6.x (Unity for Windows Store App and XBOX can already do this but standard Windows exe can't so the Base, Base.Components, Client, and Client.Unity are all stuck at .Net 3.5 for now)
    • Started replacing 3rd party tools with ones that support .NetStandard 1.6
    • Ripped out AutoFac in exchange for Microsoft.Extensions.DependencyInjection
    • Created the NetworkTransform class which will hold the location of any game object that is networked and movable
    • Created a Login Server that hosts our login control and a character select system as a replacement for the master system
    • In process of changing our XML configs to JSON configs with Microsoft.Extensions.Configuration.Json


    On the Docket
    • Move fully to Azure. I am already hosting the website, database, and a small VM for a game host there. I would like to create a deployment model for simple deployment and scalability.
    • Add an Actor Framework for concurrent state using Orleans Cluster to
      • Manage Servers
      • Use as a NoSQL Document Store for everything in the database
      • Act as a new Backend for all services and servers
    • Replace Entity Framework with Entity Framework Code if I still need relational access to a database which I am hoping I won't
    • Create a "Cell" server as a replacement for the region server for handling all in game networking
    • Start moving to a Micro Service Architecture for all of the Web Services
    • Replace the website with ASP.NET MVC Core

  9. #9
    Join Date
    Nov 2006
    Location
    Vancouver, WA
    Posts
    236
    am385, Does that mean we will be able to bring our projects in line with yours and continue moving in a MMO direction?
    I really like what you have done and the things on the docket like setting up Azure I have watch a few videos on azure as I wish to keep everything in a Microsoft circle if I can.

  10. #10
    Join Date
    Aug 2010
    Posts
    158
    Yes we could. Honestly if we want to do that we should make a public github or bitbucket and migrate there. It would be hard to merge otherwise.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •