Exemple #1
0
        private VarNames BuildVariableNames(FsmModel model)
        {
            Dictionary <Type, string> interfaceArgs        = new Dictionary <Type, string>();
            Dictionary <Type, string> interfaceContextCall = new Dictionary <Type, string>();

            // TODO: conflict resolution between same name interfaces in different namespaces
            foreach (var iface in model.context.requiredInterfaces)
            {
                if (iface.Name[0] == 'I')
                {
                    interfaceArgs[iface]        = iface.Name.Substring(1, 1).ToLower() + iface.Name.Substring(2, iface.Name.Length - 2);
                    interfaceContextCall[iface] = iface.Name.Substring(1, 1).ToUpper() + iface.Name.Substring(2, iface.Name.Length - 2);
                }
                else
                {
                    interfaceArgs[iface]        = iface.Name.Substring(0, 1).ToLower() + iface.Name.Substring(1, iface.Name.Length - 1);
                    interfaceContextCall[iface] = iface.Name.Substring(0, 1).ToUpper() + iface.Name.Substring(1, iface.Name.Length - 1);
                }
            }

            Dictionary <MethodInfo, string> methodCalls = new Dictionary <MethodInfo, string>();

            foreach (var state in model.states)
            {
                foreach (var m in state.onEnter)
                {
                    methodCalls[m._delegate.method] = MakeMethodInvoke(m._delegate.method);
                }
                foreach (var m in state.onExit)
                {
                    methodCalls[m._delegate.method] = MakeMethodInvoke(m._delegate.method);
                }
                foreach (var m in state.internalActions)
                {
                    methodCalls[m._delegate.method] = MakeMethodInvoke(m._delegate.method);
                }
            }

            Dictionary <string, string> stateEnum = new Dictionary <string, string>();

            foreach (var state in model.states)
            {
                stateEnum[state.name] = state.name.Trim().Replace(" ", "");
            }

            Dictionary <string, string> eventEnum = new Dictionary <string, string>();

            foreach (var evt in model.events)
            {
                eventEnum[evt.name] = evt.name.Trim().Replace(" ", "");
            }

            return(new VarNames {
                interfaceArgs = interfaceArgs,
                interfaceContextCall = interfaceContextCall,
                stateNameToEnum = stateEnum,
                eventNameToEnum = eventEnum,
                methodInvoke = methodCalls,
            });
        }
Exemple #2
0
        private string GetIgnoreEvents(FsmModel model, VarNames varNames)
        {
            // Build state switch
            var sb    = new System.Text.StringBuilder();
            int count = 0;

            foreach (var state in model.states)
            {
                if (state.ignoreEvents.Count == 0)
                {
                    continue;
                }

                count++;

                sb.Append(ignoreEventsStateCaseTemplate
                          .Replace("{{name}}", varNames.stateNameToEnum[state.name])
                          .Replace("{{ignoreevents}}", GetStateIgnoreEvents(model, state, varNames))
                          .Replace("{{defaultbreak}}", ""));
            }

            if (count == 0)
            {
                return(PostIndent(ignoreEventsNoneTemplate, options.padding));
            }

            return(PostIndent(ignoreEventsTemplate
                              .Replace("{{states}}", sb.ToString()),
                              options.padding));
        }
Exemple #3
0
        private string GetImplementInterfaces(FsmModel model, VarNames varNames)
        {
            // This is gross, should add a list of interfaces and make it cleaner
            var  sb          = new System.Text.StringBuilder();
            bool addedPrefix = false;

            if (options.enableIntrospectionSupport)
            {
                addedPrefix = true;
                sb.Append(",\n");
                PreIndent(sb, options.padding);
                sb.Append("UnityFSMCodeGenerator.IFsmIntrospectionSupport");
            }

            if (options.enableDebugSupport)
            {
                if (!addedPrefix)
                {
                    sb.Append(",\n");
                }

                if (options.enableIntrospectionSupport)
                {
                    sb.Append(",\n");
                }

                PreIndent(sb, options.padding);
                sb.Append("UnityFSMCodeGenerator.IFsmDebugSupport");
            }

            return(sb.ToString());
        }
Exemple #4
0
        private string GetIntrospectionSupport(FsmModel model, VarNames varNames)
        {
            if (!options.enableIntrospectionSupport)
            {
                return("");
            }

            var sb  = new System.Text.StringBuilder();
            var sb2 = new System.Text.StringBuilder();

            // Make two dictionary initializer entries for introspection lookup
            // { "Hung Up", "HungUp" },
            // { "Hung Up", (object)State.HungUp},
            //
            for (int i = 0; i < model.states.Count; i++)
            {
                var state = model.states[i];
                // { "Hung Up", "HungUp" },
                PreIndent(sb, options.padding);
                sb.Append("{ State.");
                sb.Append(varNames.stateNameToEnum[state.name]);
                sb.Append(", \"");
                sb.Append(state.name);
                sb.Append("\" },\n");

                // { "Hung Up", (object)State.HungUp},
                PreIndent(sb2, options.padding);
                sb2.Append("{ \"");
                sb2.Append(state.name);
                sb2.Append("\", ");
                sb2.Append("State.");
                sb2.Append(varNames.stateNameToEnum[state.name]);
                sb2.Append(" },\n");
            }

            var stateLookups      = sb.ToString();
            var stringToEnumState = sb2.ToString();

            // Make list initializer of state names
            sb = new System.Text.StringBuilder();
            for (int i = 0; i < model.states.Count; i++)
            {
                var state = model.states[i];
                PreIndent(sb, options.padding);
                sb.Append("\"");
                sb.Append(state.name);
                sb.Append("\",\n");
            }

            return(PostIndent(introspectionSupportTemplate
                              .Replace("{{statelookups}}", stateLookups)
                              .Replace("{{stateenumlookup}}", stringToEnumState)
                              .Replace("{{statelist}}", sb.ToString()),
                              options.padding));
        }
Exemple #5
0
 private string GetStartState(FsmModel model, VarNames varNames)
 {
     foreach (var state in model.states)
     {
         if (state.isStart)
         {
             return("public const State START_STATE = State." + varNames.stateNameToEnum[state.name]);
         }
     }
     return("");
 }
Exemple #6
0
        private string GetDebugSupport(FsmModel model, VarNames varNames)
        {
            if (!options.enableDebugSupport)
            {
                return("");
            }

            return(PostIndent(debugSupportTemplate,
                              //.Replace("{{statelookups}}", stateLookups)
                              options.padding));
        }
Exemple #7
0
        private string GetDefaultContextInterfaces(FsmModel model, VarNames varNames)
        {
            var sb = new System.Text.StringBuilder();

            foreach (var kvp in varNames.interfaceArgs)
            {
                sb.Append("public ");
                sb.Append(kvp.Key.FullName);
                sb.Append(" ");
                sb.Append(varNames.interfaceContextCall[kvp.Key]);
                sb.Append(" { get; set; }\n");
            }
            return(PostIndent(sb.ToString(), options.padding * 2, false));
        }
Exemple #8
0
        private string GetDispatchOnExit(FsmModel model, VarNames varNames)
        {
            // Build state switch
            var sb = new System.Text.StringBuilder();

            foreach (var state in model.states)
            {
                sb.Append(dispatchStateCaseTemplate
                          .Replace("{{name}}", varNames.stateNameToEnum[state.name])
                          .Replace("{{methodcalls}}", GetDispatchMethodCalls(model, state, varNames, state.onExit)));
            }

            return(PostIndent(dispatchOnExitTemplate
                              .Replace("{{states}}", sb.ToString()),
                              options.padding));
        }
Exemple #9
0
        private string GetStateIgnoreEvents(FsmModel model, FsmStateModel state, VarNames varNames)
        {
            var sb    = new System.Text.StringBuilder();
            int count = 0;

            foreach (var ignore in state.ignoreEvents)
            {
                count++;

                sb.Append(PostIndent(ignoreEventTrue
                                     .Replace("{{event}}", varNames.eventNameToEnum[ignore.name]),
                                     options.padding * 2, false));
            }

            return(sb.ToString());
        }
Exemple #10
0
        private string GetStates(FsmModel model)
        {
            var sb = new System.Text.StringBuilder();

            for (int i = 0; i < model.states.Count; i++)
            {
                var state = model.states[i];
                PreIndent(sb, options.padding * 2);
                sb.Append(state.name.Trim().Replace(" ", ""));
                sb.Append(",");
                if (i + 1 != model.states.Count)
                {
                    sb.Append("\n");
                }
            }
            return(sb.ToString());
        }
Exemple #11
0
        private string GetStateInternalActions(FsmModel model, FsmStateModel state, VarNames varNames)
        {
            var sb    = new System.Text.StringBuilder();
            int count = 0;

            foreach (var action in state.internalActions)
            {
                count++;

                sb.Append(PostIndent(internalActionsEventTemplate
                                     .Replace("{{event}}", varNames.eventNameToEnum[action.evt.name])
                                     .Replace("{{methodcall}}", MakeMethodCall(action._delegate, varNames)),
                                     options.padding * 2, false));
            }

            return(sb.ToString());
        }
Exemple #12
0
        private string GetSingleInternalSendEvent(FsmModel model, VarNames varNames)
        {
            // Build state switch
            var sb = new System.Text.StringBuilder();

            foreach (var state in model.states)
            {
                bool needDefaultBreak = false;
                sb.Append(sendInternalEventStateCaseTemplate
                          .Replace("{{name}}", varNames.stateNameToEnum[state.name])
                          .Replace("{{transitions}}", GetTransitions(model, state, varNames, out needDefaultBreak))
                          .Replace("{{defaultbreak}}", needDefaultBreak ? PostIndent(defaultBreakEventHandlerTemplate, options.padding * 2, false) : ""));
            }

            return(PostIndent(sendInternalEventBaseTemplate
                              .Replace("{{states}}", sb.ToString()),
                              options.padding));
        }
Exemple #13
0
        private string GetTransitions(FsmModel model, FsmStateModel state, VarNames varNames, out bool needDefaultBreak)
        {
            var sb    = new System.Text.StringBuilder();
            int count = 0;

            foreach (var transition in state.transitions)
            {
                count++;
                sb.Append(PostIndent(stateTransitionTemplate
                                     .Replace("{{event}}", varNames.eventNameToEnum[transition.evt.name])
                                     .Replace("{{tostate}}", varNames.stateNameToEnum[transition.to.name]),
                                     options.padding * 2, false));
            }

            needDefaultBreak = count != model.events.Count;

            return(sb.ToString());
        }
        public static string CreateDescription(FsmModel model)
        {
            var sb = new System.Text.StringBuilder();

            sb.Append("\n");

            sb.Append("-----------------------\n");
            sb.Append("Required Interfaces \n");
            sb.Append("-----------------------\n\n");

            foreach (var _interface in model.context.requiredInterfaces)
            {
                sb.Append(_interface.FullName);
                sb.Append("\n");
            }

            sb.Append("\n");

            sb.Append("--------\n");
            sb.Append("Events \n");
            sb.Append("--------\n\n");

            foreach (var evt in model.events)
            {
                sb.Append(evt.name);
                sb.Append("\n");
            }

            sb.Append("\n");

            sb.Append("--------\n");
            sb.Append("States \n");
            sb.Append("--------\n\n");

            foreach (var state in model.states)
            {
                ToDebugStringAppendState(sb, state, 0);
                sb.Append("\n");
            }

            return(sb.ToString());
        }
Exemple #15
0
        private string GetNewDefaultContext(FsmModel model, VarNames varNames)
        {
            var sb    = new System.Text.StringBuilder();
            int count = 0;

            foreach (var kvp in varNames.interfaceArgs)
            {
                PreIndent(sb, options.padding);
                sb.Append(kvp.Key.FullName);
                sb.Append(" ");
                sb.Append(kvp.Value);
                if (count != varNames.interfaceArgs.Count - 1)
                {
                    sb.Append(",\n");
                }
                else
                {
                    sb.Append(",");
                }
                count++;
            }

            var _params = sb.ToString();

            sb = new System.Text.StringBuilder();
            foreach (var kvp in varNames.interfaceArgs)
            {
                sb.Append(varNames.interfaceContextCall[kvp.Key]);
                sb.Append(" = ");
                sb.Append(kvp.Value);
                sb.Append(", ");
            }

            var args = sb.ToString();

            return(PostIndent(newDefaultContextTemplate
                              .Replace("{{params}}", _params)
                              .Replace("{{args}}", args),
                              options.padding));
        }
Exemple #16
0
        private string GetIContext(FsmModel model, VarNames varNames)
        {
            var sb = new System.Text.StringBuilder();

            for (int i = 0; i < model.context.requiredInterfaces.Count; i++)
            {
                var iface = model.context.requiredInterfaces[i];

                PreIndent(sb, options.padding * 2);

                sb.Append(iface.FullName);
                sb.Append(" ");
                sb.Append(varNames.interfaceContextCall[iface]);
                sb.Append(" { get; }");

                if (i + 1 != model.context.requiredInterfaces.Count)
                {
                    sb.Append("\n");
                }
            }
            return(sb.ToString());
        }
Exemple #17
0
        private string GetHandleInternalActions(FsmModel model, VarNames varNames)
        {
            bool haveActions = false;

            foreach (var state in model.states)
            {
                if (state.internalActions.Count > 0)
                {
                    haveActions = true;
                    break;
                }
            }

            if (!haveActions)
            {
                return(PostIndent(noInternalActionsTemplate, options.padding));
            }

            // Build state switch
            var sb = new System.Text.StringBuilder();

            foreach (var state in model.states)
            {
                if (state.internalActions.Count == 0)
                {
                    continue;
                }

                sb.Append(internalActionsStateCaseTemplate
                          .Replace("{{name}}", varNames.stateNameToEnum[state.name])
                          .Replace("{{internalactions}}", GetStateInternalActions(model, state, varNames))
                          .Replace("{{defaultbreak}}", ""));
            }

            return(PostIndent(internalActionsTemplate
                              .Replace("{{states}}", sb.ToString()),
                              options.padding));
        }
Exemple #18
0
        private string GetDispatchMethodCalls(FsmModel model, FsmStateModel state, VarNames varNames, List <FsmOnEnterExitModel> calls)
        {
            var sb = new System.Text.StringBuilder();

            if (calls.Count > 0)
            {
                sb.Append("\n");
            }
            for (int i = 0; i < calls.Count; i++)
            {
                var call = calls[i];
                PreIndent(sb, options.padding * 2);
                sb.Append("context.");
                sb.Append(varNames.interfaceContextCall[call._delegate._interface]);
                sb.Append(".");
                sb.Append(varNames.methodInvoke[call._delegate.method]);
                sb.Append(";");
                if (i != calls.Count - 1)
                {
                    sb.Append("\n");
                }
            }
            return(sb.ToString());
        }
Exemple #19
0
        public Output Generate(FsmModel model, string className)
        {
            var output = new Output();

            var sb = new System.Text.StringBuilder();

            sb.Append(header);

            if (options.commentedOut)
            {
                sb.Append("/*\n");
            }

            var indentLevel = 0;

            // Add namespace
            if (!string.IsNullOrEmpty(options._namespace))
            {
                sb.Append(namespaceTemplate.Replace("{{ns}}", options._namespace));
                indentLevel = options.padding;
            }

            // Build variable names
            var varNames = BuildVariableNames(model);

            // Build class.
            // This is very inefficient with string.Replace, but I did not want to introduce
            // a dependency on an external templating library.
            sb.Append(PostIndent(
                          clsStartTemplate
                          .Replace("{{description}}", model.description != null ? "// " + model.description.Replace("\n", "") : "")
                          .Replace("{{cls}}", className)
                          .Replace("{{implementinterfaces}}", GetImplementInterfaces(model, varNames))
                          .Replace("{{genprefab}}", model.fromPrefab != null ? model.fromPrefab.Replace("\"", "") : "")
                          .Replace("{{genguid}}", model.prefabGuid != null ? model.prefabGuid.Replace("\"", "") : "")
                          .Replace("{{startstate}}", GetStartState(model, varNames))
                          .Replace("{{newdefaultcontext}}", GetNewDefaultContext(model, varNames))
                          .Replace("{{defaultcontextinterfaces}}", GetDefaultContextInterfaces(model, varNames))
                          .Replace("{{states}}", GetStates(model))
                          .Replace("{{events}}", GetEvents(model))
                          .Replace("{{icontext}}", GetIContext(model, varNames))
                          .Replace("{{singleinternalsendEvent}}", GetSingleInternalSendEvent(model, varNames))
                          .Replace("{{handleinternalactions}}", GetHandleInternalActions(model, varNames))
                          .Replace("{{checkignoreevents}}", GetIgnoreEvents(model, varNames))
                          .Replace("{{dispatchonenter}}", GetDispatchOnEnter(model, varNames))
                          .Replace("{{dispatchonexit}}", GetDispatchOnExit(model, varNames))
                          .Replace("{{introspectionsupport}}", GetIntrospectionSupport(model, varNames))
                          .Replace("{{debugsupport}}", GetDebugSupport(model, varNames)),
                          indentLevel));

            // Close namespace
            if (!string.IsNullOrEmpty(options._namespace))
            {
                sb.Append("}\n");
            }

            if (options.commentedOut)
            {
                sb.Append("*/\n");
            }

            output.code = sb.ToString();

            return(output);
        }