private static void GenerateVisibleProperty(ICodeBlock codeBlock, IElement element, EntitySave entitySave) { bool inheritsFromIVisible = entitySave.GetInheritsFromIVisible(); #region Get whether we use virtual or override if (!inheritsFromIVisible) { codeBlock.Line("protected bool mVisible = true;"); } #endregion var prop = codeBlock.Property("Visible", Public: true, Override: entitySave.GetInheritsFromIVisible(), Virtual: !entitySave.GetInheritsFromIVisible(), Type: "bool"); if (inheritsFromIVisible) { prop.Get() .Line("return base.Visible;"); } else { prop.Get() .Line("return mVisible;"); } var set = prop.Set(); #region History on the before set code // See comment above about why we no longer // check to see if it creates an event. //if (createsVisibleEvent) //{ // Keep hasChanged around just in case we want to make a Changed event. It won't be used by the Set event // Update November 27, 2011 // This is just polluting code. Let's remove it for now //set.Line("bool hasChanged = value != mVisible;"); #endregion EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.Before, "Visible", entitySave); if (entitySave.GetInheritsFromIVisible()) { set.Line("base.Visible = value;"); } else { set.Line("mVisible = value;"); } // May 6, 2012 // We used to manually // set the Visible of all // children, but now we no // longer do that because there // is a concept of relative visibility. // WriteVisibleSetForNamedObjectSaves(set, entitySave); EventCodeGenerator.GenerateEventRaisingCode(set, BeforeOrAfter.After, "Visible", entitySave); }
internal static void TryGenerateEventsForVariable(ICodeBlock codeBlock, CustomVariable customVariable, IElement container) { var shouldGenerate = ShouldGenerateEventsForVariable(customVariable, container); // Currently we don't support events on static variables if (shouldGenerate) { EventCodeGenerator.GenerateEventsForVariable(codeBlock, customVariable.Name); } }
private static void GenerateEnabledVariable(ICodeBlock codeBlock, IElement element) { CustomVariable exposedEnabledVariable = element.CustomVariables.FirstOrDefault(item => item.Name == "Enabled" && item.Type == "bool"); bool isEnableVariableExposed = exposedEnabledVariable != null; bool hasEvents = exposedEnabledVariable != null && exposedEnabledVariable.CreatesEvent && element.Events.Any(item => item.SourceVariable == exposedEnabledVariable.Name); if (hasEvents) { EventCodeGenerator.GenerateEventsForVariable(codeBlock, exposedEnabledVariable.Name); } string prefix; string propertyName; if (isEnableVariableExposed) { prefix = "public bool"; propertyName = "Enabled"; } else { prefix = "bool"; propertyName = "FlatRedBall.Gui.IWindow.Enabled"; } codeBlock.Line(Resources.Resource1.IWindowTemplate); var property = codeBlock.Property(prefix, propertyName); property.Get().Line("return mEnabled;"); var setBlock = property.Set(); if (hasEvents) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, exposedEnabledVariable.Name, element); } var setIf = setBlock.If("mEnabled != value"); setIf.Line("mEnabled = value;"); setIf.Line("EnabledChange?.Invoke(this);"); if (hasEvents) { EventCodeGenerator.GenerateEventRaisingCode(setIf, BeforeOrAfter.After, exposedEnabledVariable.Name, element); } }
public static void CreateEmptyCodeIfNecessary(IElement currentElement, string fullFileName, bool forceRegenerateContents) { bool doesFileExist = File.Exists(fullFileName); if (!doesFileExist) { PluginManager.ReceiveOutput("Forcing a regneration of " + fullFileName + " because Glue can't find it anywhere."); // There is no shared code file for this event, so we need to make one ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(fullFileName, true); } if (!doesFileExist || forceRegenerateContents) { string namespaceString = GlueCommands.Self.GenerateCodeCommands.GetNamespaceForElement(currentElement); ICodeBlock templateCodeBlock = new CodeDocument(); EventCodeGenerator.AddUsingStatementsToBlock(templateCodeBlock); ICodeBlock namespaceCB = templateCodeBlock.Namespace(namespaceString); ICodeBlock classCB = namespaceCB.Class("public partial", currentElement.ClassName, null); classCB ._() .End() .End(); string templateToSave = templateCodeBlock.ToString(); FlatRedBall.Glue.IO.FileWatchManager.IgnoreNextChangeOnFile(fullFileName); FileManager.SaveText(templateToSave, fullFileName); } // Add if it isn't part of the project const bool saveFile = false; // don't save it - we just want to make sure it's part of the project ProjectManager.CodeProjectHelper.CreateAndAddPartialCodeFile(fullFileName, saveFile); }
public override ICodeBlock GenerateFields(ICodeBlock codeBlock, IElement element) { EntitySave entitySave = element as EntitySave; if (entitySave != null && entitySave.ImplementsIVisible) { #region Comments on the history of events // CustomVariable visibleCustomVariable = entitySave.GetCustomVariable("Visible"); // September 22, 2011 (Victor Chelaru) // We used to only create events if the // user set them in Glue. We're changing // the approach for events now to always have // them available in code, but then have them be // exposed in Glue. This enables us to centralize // event code generation instead of spreading it out // through every module that may create events. //bool createsVisibleEvent = // visibleCustomVariable != null && visibleCustomVariable.CreatesEvent; //if (createsVisibleEvent) //{ #endregion bool isNew = entitySave.GetInheritsFromIVisible(); EventCodeGenerator.GenerateEventsForVariable(codeBlock, "Visible", isNew); GenerateVisibleProperty(codeBlock, element, entitySave); GenerateIgnoresParentVisibility(codeBlock, entitySave); GenerateAbsoluteVisible(codeBlock, entitySave); GenerateIVisibleParent(codeBlock, entitySave); } return(codeBlock); }
/// <summary> /// Injects the insideOfMethod into an event for the argument /// </summary> /// <param name="currentElement">The IElement containing the EventResponseSave.</param> /// <param name="eventResponseSave">The EventResponseSave which should have its contents set or replaced.</param> /// <param name="insideOfMethod">The inside of the methods to assign.</param> /// <returns>The full file name which contains the method contents.</returns> public static string InjectTextForEventAndSaveCustomFile(IElement currentElement, EventResponseSave eventResponseSave, string insideOfMethod) { // In case the user passes null we don't want to have null reference exceptions: if (insideOfMethod == null) { insideOfMethod = ""; } ParsedMethod parsedMethod = eventResponseSave.GetParsedMethodFromAssociatedFile(); string fullFileName = eventResponseSave.GetSharedCodeFullFileName(); bool forceRegenerate = false; string fileContents = null; if (File.Exists(fullFileName)) { fileContents = FileManager.FromFileText(fullFileName); forceRegenerate = fileContents.Contains("public partial class") == false && fileContents.Contains("{") == false; if (forceRegenerate) { GlueGui.ShowMessageBox("Forcing a regneration of " + fullFileName + " because it appears to be empty."); } } CreateEmptyCodeIfNecessary(currentElement, fullFileName, forceRegenerate); fileContents = FileManager.FromFileText(fullFileName); int indexToAddAt = 0; if (parsedMethod != null) { int startIndex; int endIndex; GetStartAndEndIndexForMethod(parsedMethod, fileContents, out startIndex, out endIndex); // We want to include the \r\n at the end, so add 2 endIndex += 2; string whatToRemove = fileContents.Substring(startIndex, endIndex - startIndex); fileContents = fileContents.Replace(whatToRemove, null); indexToAddAt = startIndex; // remove the method to re-add it } else { indexToAddAt = EventManager.GetLastLocationInClass(fileContents, startOfLine: true); } ICodeBlock codeBlock = new CodeDocument(2); codeBlock.TabCharacter = " "; insideOfMethod = "" + insideOfMethod.Replace("\r\n", "\r\n "); codeBlock = EventCodeGenerator.FillWithCustomEventCode(codeBlock, eventResponseSave, insideOfMethod, currentElement); string methodContents = codeBlock.ToString(); fileContents = fileContents.Insert(indexToAddAt, codeBlock.ToString()); eventResponseSave.Contents = null; try { FlatRedBall.Glue.IO.FileWatchManager.IgnoreNextChangeOnFile(fullFileName); FileManager.SaveText(fileContents, fullFileName); } catch (Exception e) { PluginManager.ReceiveError("Could not save file to " + fullFileName); } return(fullFileName); }
private static ICodeBlock GenerateCurrentStateProperty(IElement element, ICodeBlock codeBlock, string enumType, List <StateSave> states) { // early out if (states.Count == 0) { return(codeBlock); } string variableNameModifier = enumType; if (enumType == "VariableState") { variableNameModifier = ""; } string qualifiedEnumType = element.Name.Replace("\\", ".").Replace("/", ".") + "." + enumType; string variableToLookFor = "Current" + variableNameModifier + "State"; CustomVariable customVariable = element.GetCustomVariable(variableToLookFor); bool hasEvent = customVariable != null && customVariable.CreatesEvent; #region Header and Getter stuff - simple stuff with no logic codeBlock .Line($"private {enumType} mCurrent{variableNameModifier}State = null;"); string publicWithOptionalNew = "public"; if (IsStateDefinedInBase(element, enumType)) { publicWithOptionalNew += " new"; } // This is inclusive (-1), but includes 0 and 1 values (+2), which means the net is +1 int maxIntValueInclusive = states.Count + 1; var setBlock = codeBlock .Property(publicWithOptionalNew + " " + qualifiedEnumType, "Current" + variableNameModifier + "State") .Get() .Line(string.Format("return mCurrent{1}State;", enumType, variableNameModifier)) .End() .Set(); #endregion #region Set the state value and call an event if necessary bool stillNeedsToAssignValue = true; if (hasEvent) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, variableToLookFor, element); } if (stillNeedsToAssignValue) { setBlock.Line("mCurrent" + variableNameModifier + "State = value;"); } #endregion bool isElse = false; foreach (StateSave stateSave in states) { GenerateVariableAssignmentForState(element, setBlock, stateSave, enumType, isElse); isElse = true; } if ((enumType == "VariableState" && DoesBaseHaveUncategorizedStates(element)) || (!string.IsNullOrEmpty(element.BaseElement) && GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true).Any(category => category == enumType))) { setBlock.Else() .Line("base.Current" + variableNameModifier + "State = base.Current" + variableNameModifier + "State;"); } if (hasEvent) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.After, variableToLookFor, element); } return(codeBlock); }
private static ICodeBlock GenerateCurrentStateProperty(IElement element, ICodeBlock codeBlock, string enumType, List <StateSave> states) { var createField = false; if (enumType == "VariableState" && !DoesBaseHaveUncategorizedStates(element)) //Uncategorized and not base { createField = true; } else if (enumType != "VariableState") //Check if this state category exists in a parent entity { if (element.BaseElement != null) { var categories = GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true); if (!categories.Any(category => category == enumType)) { createField = true; } } else { createField = true; } } string variableNameModifier = enumType; if (enumType == "VariableState") { variableNameModifier = ""; } string qualifiedEnumType = element.Name.Replace("\\", ".").Replace("/", ".") + "." + enumType; if (states.Count != 0) { string variableToLookFor = "Current" + variableNameModifier + "State"; CustomVariable customVariable = element.GetCustomVariable(variableToLookFor); bool hasEvent = customVariable != null && customVariable.CreatesEvent; #region Header and Getter stuff - simple stuff with no logic if (createField) { codeBlock .Line(string.Format("protected int mCurrent{0}State = 0;", variableNameModifier)); } string publicWithOptionalNew = "public"; if (ShouldUseNewKeyword(element, enumType)) { publicWithOptionalNew += " new"; } var setBlock = codeBlock .Property(publicWithOptionalNew + " " + qualifiedEnumType, "Current" + variableNameModifier + "State") .Get() .If(string.Format("System.Enum.IsDefined(typeof({0}), mCurrent{1}State)", enumType, variableNameModifier)) .Line(string.Format("return ({0})mCurrent{1}State;", enumType, variableNameModifier)) .End() .Else() .Line(string.Format("return {0}.Unknown;", enumType)) .End() .End() .Set(); #endregion #region Set the state value and call an event if necessary bool stillNeedsToAssignValue = true; if (element is EntitySave) { EntitySave asEntitySave = element as EntitySave; //if (!string.IsNullOrEmpty(asEntitySave.CurrentStateChange)) //{ // setBlock // .If("value != mCurrent" + variableNameModifier + "State") // .Line("mCurrent" + variableNameModifier + "State = value;") // .Line(asEntitySave.CurrentStateChange + "(this, null);"); // stillNeedsToAssignValue = false; //} } if (hasEvent) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.Before, variableToLookFor, element); } if (stillNeedsToAssignValue) { setBlock.Line("mCurrent" + variableNameModifier + "State = (int)value;"); } #endregion var switchBlock = setBlock.Switch("Current" + variableNameModifier + "State"); switchBlock.Case(enumType + ".Uninitialized"); switchBlock.Case(enumType + ".Unknown"); foreach (StateSave stateSave in states) { GenerateCurrentStateCodeForIndividualState(element, switchBlock, stateSave, enumType); } if ((enumType == "VariableState" && DoesBaseHaveUncategorizedStates(element)) || (!string.IsNullOrEmpty(element.BaseElement) && GetAllStateCategoryNames(ObjectFinder.Self.GetIElement(element.BaseElement), true).Any(category => category == enumType))) { switchBlock.Default() .Line("base.Current" + variableNameModifier + "State = base.Current" + variableNameModifier + "State;"); } if (hasEvent) { EventCodeGenerator.GenerateEventRaisingCode(setBlock, BeforeOrAfter.After, variableToLookFor, element); } } return(codeBlock); }