#if UNITY_EDITOR using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace FMODUnity { public static class CodeGeneration { public static void GenerateStaticPluginRegistration(string filePath, Platform platform, Action reportError) { List validatedPlugins = ValidateStaticPlugins(platform.StaticPlugins, reportError); using (StreamWriter file = new StreamWriter(filePath)) { WriteStaticPluginRegistration(file, platform.IsFMODStaticallyLinked, validatedPlugins); } } private static void WriteStaticPluginRegistration(StreamWriter file, bool isFMODStaticallyLinked, IEnumerable pluginFunctions) { file.WriteLine("#if ENABLE_IL2CPP"); file.WriteLine(); file.WriteLine("// This file was generated by FMOD for Unity from the Static Plugins list in the FMOD settings."); file.WriteLine(); file.WriteLine("using System;"); file.WriteLine("using System.Runtime.InteropServices;"); file.WriteLine(); file.WriteLine("namespace FMODUnity"); file.WriteLine("{"); file.WriteLine(" class {0}", Platform.RegisterStaticPluginsClassName); file.WriteLine(" {"); // Import the plugin functions foreach (string pluginFunction in pluginFunctions) { file.WriteLine(" [DllImport(\"__Internal\")]"); file.WriteLine(" private static extern IntPtr {0}();", pluginFunction); file.WriteLine(); } // Import the RegisterDSP function file.WriteLine(" [DllImport(FMOD.VERSION.dll)]"); file.WriteLine(" private static extern FMOD.RESULT FMOD5_System_RegisterDSP(IntPtr system, IntPtr description, IntPtr handle);"); file.WriteLine(); file.WriteLine(" public static void {0}(FMOD.System coreSystem, Action reportResult)", Platform.RegisterStaticPluginsFunctionName); file.WriteLine(" {"); if (pluginFunctions.Any()) { file.WriteLine(" FMOD.RESULT result;"); foreach (string pluginFunction in pluginFunctions) { file.WriteLine(); file.WriteLine(" result = FMOD5_System_RegisterDSP(coreSystem.handle, {0}(), IntPtr.Zero);", pluginFunction); file.WriteLine(" reportResult(result, \"Registering static plugin '{0}'\");", pluginFunction); } } file.WriteLine(" }"); file.WriteLine(" }"); file.WriteLine("}"); file.WriteLine(""); file.WriteLine("#endif // ENABLE_IL2CPP"); } private static List ValidateStaticPlugins(List staticPlugins, Action reportError) { List result = new List(); for (int i = 0; i < staticPlugins.Count; ++i) { string functionName = staticPlugins[i]; string trimmedName = (functionName != null) ? functionName.Trim() : null; if (string.IsNullOrEmpty(trimmedName)) { reportError(string.Format("Static plugin {0} has no name and will be ignored.", i + 1)); } else if (IsValidFunctionName(trimmedName, reportError)) { result.Add(trimmedName); } } return result; } private static bool IsValidFunctionName(string name, Action reportError) { if (!(char.IsLetter(name[0]) || name[0] == '_')) { reportError(string.Format( "Plugin name '{0}' is not valid. Names must start with a letter or an underscore ('_').", name)); return false; } for (int i = 1; i < name.Length; ++i) { if (!(char.IsLetterOrDigit(name[i]) || name[i] == '_')) { reportError(string.Format( "Plugin name '{0}' is not valid. " + "Character '{1}' at position {2} is invalid - it must be a letter, a number, or an underscore ('_').", name, name[i], i)); return false; } } return true; } } } #endif