Generated code and partial class

I’ll try to be as clear as possible

I am making Localization Manager and try to keep it as auto-sufficient as possible as it will be used in various different project at the same time
The localization part is working great but I am trying to add some sort of “auto completion” system to help when typing localization key
(Here at the bottom of the script component)
8120837--1052468--LocalizerAuto.png

To display the auto completion, I’m looping trough a list of string all generated from a .csv file, along with some “LocalizerKey” that are used for other things, in a script called “LocalizerBank” that is unique to the project, like this :

// THIS FILE IS GENERATED AUTOMATICALY IN LocalizerManager

namespace Polonium
{
    public static partial class LocalizerBank
    {
        public static LocalizerKey MainMenuPlay = new LocalizerKey("MainMenuPlay");
        public static LocalizerKey MainMenuOptions = new LocalizerKey("MainMenuOptions");
        public static LocalizerKey MainMenuCredits = new LocalizerKey("MainMenuCredits");
        public static LocalizerKey MainMenuQuit = new LocalizerKey("MainMenuQuit");

        public static string[] allKey = {"MainMenuPlay","MainMenuOptions","MainMenuCredits","MainMenuQuit"};
    }
}

The list “allKey” is used in the LocalizerAuto as such :

            string previsual = "";
            foreach (string key in LocalizerBank.allKey)
            {
                if (key.StartsWith(myTarget.locKey.key))
                {
                    previsual = key;
                    break;
                }
            }
            GUILayout.Label(previsual, EditorStyles.centeredGreyMiniLabel);

The thing is, when I’m importing this code in a new project, where the LocalizerBank was never generated, of course it bugs because allKey does not exist as well
So is there a way to fix this ? Like using a #define in LocalizerBank that could be global to the project and putting the problematic code between #if #end (if that’s possible) or something else ?

How about using a partial method instead? The non-generated file would contain:

public partial static string[] GetAllKeys();

and the generated file would fill in the body:

private static string[] allKeys = {"MainMenuPlay","MainMenuOptions","MainMenuCredits","MainMenuQuit"};

public partial static string[] GetAllKeys()
{
   return allKeys;
}

You’d just have to change how you access the arrays slightly in your consumer code.

2 Likes

I didn’t know you could do that, this could be usefull

However the problem still remain, as when the generated part is not yet generated it displays an error that says “GetAllKeys() need an implementation because it has accessibility modificator”
8121968--1052750--upload_2022-5-12_12-12-41.png
(sorry the error is in french)

Ah, right. Sorry about that. You’ll have to generate the data inside the method instead. This works:

// file 1
public static partial class LocalizerBank
{
   private static List<string> _allKeys = new List<string>();

   public static List<string> allKeys
   {
       get
       {
           if (_allKeys.Count == 0)
               GenerateKeys();

           return _allKeys;
       }
   }

   static partial void GenerateKeys();
}

/*
// file 2
// remove the comment block to test
public partial class LocalizerBank
{
   static partial void GenerateKeys()
   {
       _allKeys.Add("Main Menu");
       _allKeys.Add("Pause Menu");
       _allKeys.Add("Options");
   }
}
*/

// test
public sealed class Help_PartialStaticClass : MonoBehaviour
{
   private void Start()
   {
       // prints 0 if commented out, 3 if uncommented
       Debug.LogFormat
       (
           "all keys count: {0}, content: {1}",
           LocalizerBank.allKeys.Count,
           string.Join(",", LocalizerBank.allKeys)
       );
   }
}
2 Likes

Thanks a lot, it works perfectly !