Chatterã«ã¯äŸ¡å€ããããŸããã ã³ãŒããèŠããŠãã ããã
-ã©ã€ãã¹ã»ããŒãã«ãº
ã¿ãªããããã«ã¡ã¯ïŒ ç§ã¯å°ããªïŒãããèªãã«æãïŒgamedevãªãã£ã¹ã§ããã°ã©ããŒãšããŠåããŠããŸãã é廿°å¹Žéãå瀟ã¯match3ãžã£ã³ã«ã®ã¢ãã€ã«ã²ãŒã çšã®ã«ãžã¥ã¢ã«ã²ãŒã ããªãªãŒã¹ããŠããŸããã ç§ãã¡ã¯CïŒïŒããã¯åã°ããããåŸãªãïŒã§èšè¿°ããUnityã䜿çšããŸããïŒãŸããã»ãšãã©ïŒã ç§ã®è²¬ä»»ã®äž»ãªé åã¯ãã²ãŒã ãã¬ã€ãšUIã§ãã CïŒãšãã®ãšã³ã·ã¹ãã ã«ã倢äžã§ãã 仿¥ã¯ãã²ãŒã ã³ã³ãã³ãã®ç·šéã«
Roslynã³ãŒãåââæããã³å€æŽããŒã«ãã©ã®ããã«äœ¿çšãããã説æããŸãã èª°ãæ°ã«ãã-ç§ã¯ç«ããé¡ãããŸãã
ãæ³šæ å®è£
æ¹æ³ãçè§£ããã³ãŒãäŸãæäŸãã
ã»ã¯ã·ã§ã³ã«ã¯ãèŠåºãã®
[æè¡ã»ã¯ã·ã§ã³]ãä»ããŠããŸãã ãã®ã¬ãã«ã®è©³çްã«é£ã³èŸŒã¿ãããªãå Žåã¯ãã¹ãããããŠãã ããã ããã¯ãã¢ã€ãã¢ã®äžè¬çãªçè§£ã«ã¯åœ±é¿ããŸããã
ããã¯ã°ã©ãŠã³ãã 1ã€ã®Match3ã§ãã£ã±ãã«ãªãããšã¯ãããŸãã
match3ãžã£ã³ã«ã®å€ãã®ã²ãŒã ã«ã¯ãã²ãŒã ã®äžçã衚ãå¥ã®ãšã³ãã£ãã£ããããŸãã ãããã«ãŒããšåŒã³ãŸãã ã«ãŒãã®æ©èœã¯ç°ãªãå ŽåããããŸããéåžžã«åçŽãªïŒã²ãŒã ã®é²è¡ç¶æ³ã®ã€ã³ãžã±ãŒã¿ãŒïŒããæ¬æ Œçãªã¢ã¯ã·ã§ã³ã·ãŒã³ïŒç¬èªã®å
éšã¹ããŒãªãŒãããããããã£ã©ã¯ã¿ãŒãªã©ïŒãŸã§ã§ãã
ç§ãåãçµãã§ãããããžã§ã¯ãã®1ã€ã§ã¯ããããããšãããã«ç¹å¥ãªæ³šæãæãããŠããŸãã ååãªèŠä»¶ããããŸãïŒå€§éã®ã³ã³ãã³ãã倿§æ§ãé
åãããæŽçãããã«ããã·ãŒã³ãªã©ã ãŸãããããã¯ãã¹ãŠç°¡åã«ç·šéããã³å±éã§ããå¿
èŠããããŸãã ä»ãŸã§ãç§ãã¡ã®ã¹ã¿ãžãªã®ã²ãŒã ãããžã§ã¯ãã«ã¯ãã®ãããªãã®ã¯ãããŸããã§ããã ããããã·ã¹ãã ãšãã®ããŒã«ã®äž¡æ¹ããŒãããéçºããå¿
èŠããããŸããã
ããããã¢ãŒããã¯ãã£[æè¡ã»ã¯ã·ã§ã³]
ããããå
šäœãå¥ã
ã®éé-ã¯ãšã¹ãã«åå²ããŸãã ã¯ãšã¹ãã¯äžé£ã®ã¹ããŒãžïŒç¶æ
ïŒã§ãããããããã«ç¬èªã®ããžãã¯ããããŸãã ã¹ã¿ãã¯ãšã¹ãã®ã³ãŒããèŠãŠã¿ãŸãããã
enum StubQuestState { Initial, } class Stub : SectorComponent<StubQuestState> {} class StubQuest : SectorBehaviour<Stub, StubQuestState> { [State(StubQuestState.Initial)] private IEnumerator<object> InitialState() { yield break; } }
ã ããç§ãã¡ã¯èŠãïŒ
- åæåStubQuestState-ã¯ãšã¹ãã®ã¹ããŒã¿ã¹ã
- ã¯ã©ã¹ã¹ã¿ã-ã¯ãšã¹ãã®ã³ã³ããŒãã³ããç¶æ
ãšãªãã·ã§ã³ã®ããŒã¿ãä¿åããŸãã
- StubQuestã¯ã©ã¹-ã¯ãšã¹ãããžãã¯ã ã¯ãšã¹ãã®åç¶æ
ã¯ãã€ãã¬ãŒã¿ãè¿ãã¡ãœããã«å¯Ÿå¿ããå¿
èŠããããŸãïŒã¡ãœããã¯State屿§ãä»ããŠæ¥ç¶ããããã®ç¶æ
ã§çŽæ¥å®è¡ãããã¢ã¯ã·ã§ã³ã決å®ããŸãïŒã
ãŸããåã¯ãšã¹ãã«ã¯ã¢ã¯ãã£ããŒã·ã§ã³æ¡ä»¶ããããŸã-èµ·åããå¿
èŠãããå ŽåïŒã³ãŒãã§ã¯FuncãšããŠè¡šç€ºãããååã¯ReachedConditionã«ãªããŸãïŒã
ã¿ã€ãã«ã«ã€ããŠç§ã¯ååãããŸãããéžã°ããªãã£ãããšãèªããªããã°ãªããŸãã-ããã¯ãNPCã«è©±ããããã-ã10åã®æçãæã«å
¥ããŸããã-ãåæ Œããnishtyakã«ãªããŸããããšããæ£èŠã®ã·ãŒã±ã³ã¹ã§ã¯ãããŸããã ã¯ãšã¹ããéããŠããããããä¿é²ãããšãã®æ©èœã®çºèŠãåã²ãŒã ã®å Žæã«åºæã®è³ã®çºè¡ãªã©ãããªãå€ãã®ç°ãªããã®ãå®è£
ãããŸãã ãBehaviorãomïŒUnityãªã©ïŒãåŒã³åºãæ¹ãé©åã§ãããéåžžã®ååã®ãŸãŸã«ããããšã«ããŸããã
ã¯ãšã¹ãã¯ãã»ã¯ã¿ãŒïŒSectorNãªã©ã®ååã®éçã¯ã©ã¹ïŒã®çšèªã§ãå Žæã«ãã£ãŠåå²ãããŠããŸãã åã»ã¯ã¿ãŒã«ã¯ããããïŒããã§ã¯ã°ã©ãã£ãã¯ãã¢ãã¡ãŒã·ã§ã³ãæå³ããïŒããã¥ãŒããªã¢ã«ïŒäžéšã¯ã¯ãšã¹ããéããŠå®è£
ããããç¬ç«ãããšã³ãã£ãã£ã§ãïŒãããã³ã¯ãšã¹ãèªäœãåæåããInitializeã¡ãœããããããŸãã åæåã³ãŒãã®äŸã次ã«ç€ºããŸãã
var fixSubmarineQuest = new FixSubmarineQuest { ReachedCondition = () => plot.Levels.Completed > 3, }; var removeSeaweedQuest = new RemoveSeaweedQuest { ReachedCondition = () => fixSubmarineQuest.Component.IsFinished, }; var fixGateStatuesQuest = new FixGateStatuesQuest { ReachedCondition = () => removeSeaweedQuest.Component.IsFinished && fixSubmarineQuest.Component.IsFinished, };
ã¯ãšã¹ãã®æ¥ç¶ãèŠèŠåããŸãïŒ

ã芧ã®ããã«ãã¯ãšã¹ãã¯éé£çµã®éåŸªç°æåã°ã©ãã圢æããŸãã
ã¯ãšã¹ãã®ã¹ããŒã¿ã¹ã®ããžãã¯ãåæããŸãããã åç¶æ
ã¯ãåºæ¬çã«ãã®ç¶æ
ã§å®è¡ããå¿
èŠãããäžé£ã®ã¢ã¯ã·ã§ã³ã§ãã ã¢ã¯ã·ã§ã³ã¯å®å
šã«ç°ãªãå ŽåããããŸããã¢ãã¡ãŒã·ã§ã³ã®ã¢ã¯ãã£ãåãã·ãŒã³å
ã§ã®ã«ã¡ã©ã®ç§»åãã²ãŒã ã¬ãã«ã®èµ·åãã«ããã·ãŒã³ã®èµ·åãšç®¡çãªã©ã äŸïŒ
yield return WaitForMapScreenOnTop(); MapScreen.HideUi(); yield return MapScreen.ScrollToMapNodeTask( MapScreen.Map._Sector02._RadioTower.It, zooming: MapZooming.Minimal, screenPivot: new Vector2(0.5f, 0.4f) ); yield return MapScreen.Map._Sector02._RadioTower.RunAnimationFixTower(); yield return MapScreen.Map._Sector02._RadioTower.RunAnimationCommunicate(); var dialog = new CutScene(CharacterEmotion.Playfulness); dialog.AddBubble("Bla-bla-bla"); yield return Task.WaitWhile(() => !dialog.IsNearlyHidden); MapScreen.ShowUiWithDelay(); SetState(FixCommunicationCrystalQuestState.Final);
ãã®äŸã§ã¯ã次ã®ããšãè¡ããŸãã
- ããããäžçªäžã®ãã€ã¢ãã°ãšããŠè¡šç€ºããããŸã§åŸ
ã¡ãŸãã
- UIãé衚瀺ã«ããŠãã«ã¡ã©ãç§»åããŸãã
- ããããã¢ãã¡ãŒã·ã§ã³ãé æ¬¡èµ·åããŸãã
- ãBla-bla-blaããšãã幞ããªãã£ã©ã¯ã¿ãŒã®ã«ããã·ãŒã³ã玹ä»ããŸãã
- UIã衚瀺ããŠã次ã®ç¶æ
ã«é²ã¿ãŸãã
ããºãªã³ãšã³ã³ãã³ã
ãåãã®ããã«ãgamedevã¯ãœãããŠã§ã¢éçºã®ããªã極端ãªåéã§ãã ã²ãŒã ã¯ã·ã¹ãã ãšã³ã³ããŒãã³ãã®ãå¯ãéããã§ããã ãã§ãªãããããã®éã®é¢ä¿ã¯é»å
ç³ç«ã®é床ã«ãã£ãŠå€åããŸãïŒå Žåã«ãã£ãŠã¯ãæ¯ãåã®åçã«ãã£ãŠãïŒåé€ãè¿åŽââãååã®åé€...ïŒã 掻çºãªéçºã®æ®µéã§ãããããã¯çµ¶ããå€åããŠããŸãã ããã¯ãèšè¿°ãããã¢ãŒããã¯ãã£ã®ãã¹ãŠã®ã¬ãã«ã«åœ±é¿ããŸãïŒã¯ãšã¹ãéã®é¢ä¿ïŒãããã®é åºïŒãã¯ãšã¹ãã®ã»ã¯ã¿ãŒãžã®åå²ããããŠçŽæ¥ã¯ãšã¹ãããžãã¯ïŒç¶æ
ãšã¢ã¯ã·ã§ã³ïŒã ç§ã¯æ£çŽãªãšããããã¹ãŠãæã§æžãïŒãŸãã¯Ctrl + CãCtrl + Vãè¡ã£ãŠããååã倿Žãããªã©ïŒã®ã«ããããããŠãããããæåã«WinFormsã§å°ããªã¢ããªã±ãŒã·ã§ã³ãäœæããŠãæå®ãããååãšã¹ããŒã¿ã¹ã®StubQuestãçæããŸããã ãããŠãRoslynã«ã€ããŠæãåºããããããç·šéããŒã«ãäœæããããšã«ããŸããã
äžã§èª¬æããããã«ãããããå
šäœã¯ã³ãŒãã«ãã£ãŠèšå®ãããŸãã ããã°ã©ãã³ã°ã¹ãã«ããªããã°ç·šéã§ããŸããã äžèšã®ãã¹ãŠã®ã³ã³ããŒãã³ãïŒã¯ãšã¹ããé åºãããžãã¯ãã¢ã¯ã·ã§ã³ïŒãä»ã®äººïŒãããã¥ãŒãµãŒãã²ãŒã ãã¶ã€ããŒïŒã«å€æŽããæ©èœãæäŸããäœåãéãäœæ¥ããããã«ãRoslynãéèŠãªåœ¹å²ãæ
ããšãã£ã¿ãŒãäœæãããŸããã ãã®ä»äºã®åçïŒ
- RoslynïŒç¹ã«ãMicrosoft.CodeAnalysis.CSharpïŒã䜿çšããŠãã²ãŒã ã³ãŒããåæãããè«çã¢ãã«ãæ§ç¯ãããŸãã
- è«çã¢ãã«ãå³ã«è¡šç€ºãããŸãã
- ãã€ã¢ã°ã©ã ãžã®å€æŽãã¢ãã«ã«è¡šç€ºããããã®åŸïŒåã³Roslynãä»ããŠããã ãAPIã䜿çšããŠã³ãŒããçæããã³å€æŽããŠïŒã³ãŒãããŒã¹ã«æ»ããŸãã
æŠç¥çã«ã¯ãããã¯æ¬¡ã®ããã«è¡šçŸã§ããŸãã

è«ç衚çŸèªäœã¯éåžžã«åçŽã§ã-ã²ãŒã ãšã³ãã£ãã£ã衚ãã¯ã©ã¹/æ§é ã®ã»ãããããããèšè¿°/è£è¶³ã§ããããŸããŸãªããŒã¿ãããã³ãããã®ãšã³ãã£ãã£éã®é¢ä¿ã è«çã¢ãã«ã®ãããã§ãæ¯ãèãã®æ£ç¢ºããç°¡åã«ç¢ºèªã§ããŸãïŒããšãã°ãã°ã©ãå
ã®ãµã€ã¯ã«ã®ååšããã«ããã·ãŒã³ã®åŸã«UIã衚瀺ããéçºè
ã®å¿ããããïŒã ã³ãŒãåââæãšè«çæ§é ã®æ§ç¯ã«ã€ããŠè©³ãã説æããŸãã
éããã°ã©ããŒã«ããVisual Studioã®å€éšã§ã®ã³ãŒãç·šéã®æ±ºå®ã«ã€ããŠæçè«è
ã¯å°ãããããããŸããïŒãªãããããã¹ãŠãªã®ãïŒ ããã°ã©ã以å€ã®äººãã³ãŒããç·šéã§ããããã«ããã«ã¯ã©ãããã°ããã§ããïŒ
çãã¯æ¬¡ã®ãšããã§ããéåžžã«ç°¡åã§ãã ãã®ããŒã«ã䜿çšãããšãã³ãŒãã®å³å¯ã«å®çŸ©ãããéšåã®ã¿ãç·šéã§ããæ£ç¢ºæ§ã確èªã§ããŸãã ããã䜿çšãããšããããžã§ã¯ãã®ã¢ã»ã³ããªãå£ãããšã¯ã§ããŸããã
ãçµ¶ããæ¥éã«å€åããèŠä»¶ãã«ã€ããŠã¯ã©ãã§ããïŒ ãã¹ãŠãç°¡åã§ããå¿
èŠã«å¿ããŠæ°ããæ©èœã远å ãããŸãã ã³ã³ã»ãããå®è£
ãããæ¿èªãããããããã®ããŸããŸãªå Žæã§æºãããããšããã«ãããŒã«ã宿ããŸãã
ã³ãŒãåââæãšã¢ãã«æ§ç¯[æè¡ã»ã¯ã·ã§ã³]ã
ã³ãŒããšã¯äœã§ããïŒ æå§ãã«ãããã¯åãªãããã¹ãã§ãã æ¬¡ã«ã
æ§æè§£ææ®µéã§ãASTïŒ
Abstract Syntax Tree ïŒãååŸãããŸãã ã»ãã³ãã£ãã¯åæã®åŸ
ãã·ã³ãã«ããŒãã«ã衚瀺ãããŸãã Roslynã䜿çšããŠãå¿
èŠãªããŒã¿æ§é ãååŸããããšã¯é£ãããããŸããïŒäŸ
ãããããåã
ãŸã ïŒã
var tree = CSharpSyntaxTree.ParseText(@" public class MyClass { int MyMethod() { return 0; } }" ); var Mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); var compilation = CSharpCompilation.Create( "MyCompilation", syntaxTrees: new[] { tree }, references: new[] { Mscorlib } );
ãã®ãããåæã«äŸ¿å©ãªåœ¢åŒã®ã³ãŒãããããŸãã ãããããããã®è«çæ§é ãšãªã³ã¯ããããšã¯æ®ã£ãŠããŸãã ãããžã§ã¯ãã®ãã¡ã€ã«æ§é ãšäžèšã®ã¢ãŒããã¯ãã£ã¯ã次ã®ç¹ã§åœ¹ç«ã¡ãŸãã

public void LoadSectorCode(string dirPath) { var sectorFile = Directory.EnumerateFiles(dirPath) .FirstOrDefault(p => new FileInfo(p).Name.StartsWith("Sector")); if (sectorFile == null) { throw new SectorFileNotFoundException(); } code.ReadFromFile(Path.Combine(dirPath, sectorFile), CodeBulkType.Sector); var questsDir = Path.Combine(dirPath, "Quests"); if (Directory.Exists(questsDir)) { var files = Directory.EnumerateFiles(questsDir); foreach (var filePath in files) { code.ReadFromFile(filePath, CodeBulkType.Quest); } } }
ã³ãŒãããŒã¹ã®åãã¡ã€ã«ã¯ãã¿ã€ãïŒenum CodeBulkTypeïŒã«é¢é£ä»ããããŠããŸãïŒã¯ãšã¹ããã»ã¯ã¿ãŒãæ§æãã¡ã€ã«ãªã©ã ã¿ã€ãããããã°ãããé«ãã¬ãã«ã®åæãè¡ãããšãã§ããŸãã ããšãã°ãã¯ãšã¹ãããŒã¿ãèªã¿åããŸãã
class QuestReader : CodeReader { public override CodeBulkType[] AcceptedTypes => new[] { CodeBulkType.Quest, }; public override void Read(CodeBulk codeBulk, Code code, ref Flow flow) { var quest = FromCodeTransformer.ReadQuest(codeBulk.Tree);
ããŒã¿ã¢ãŒããã¯ãã£ãšèªã¿åãã«ã€ããŠå°ããããžã§ã¯ãã®å€æŽã«äŒŽããéçºçšã®ããŒã«ã倿Žããããããæ¡åŒµæ§ãšæè»æ§ãã¢ãŒããã¯ãã£ã®å¿
é èŠä»¶ã§ããã è«çã¢ãã«ã¯ãªããžããªãšèŠãªãããŸããããŒã¿ã远å ã倿Žãåé€ã§ããŸãã ããŒã¿ã®æ¡åŒµæ§ïŒ
public interface IData {} public class DataStorage { public List<IData> Records = new List<IData>();
èªæžïŒ
interface ICodeReader { CodeBulkType[] AcceptedTypes { get; } void Read(CodeBulk codeBulk, Code code, ref Flow flow); } abstract class CodeReader : ICodeReader { public abstract CodeBulkType[] AcceptedTypes { get; } public abstract void Read(CodeBulk codeBulk, Code code, ref Flow flow); }
äœãèªãå¿
èŠããããŸããïŒ ã¯ã©ã¹ãååŸããCodeReaderããç¶æ¿ããICodeReaderãå®è£
ããŸãã 远å ããå¿
èŠããããŸãã åæçšããŒã¿ïŒ çŽ æŽããããIDataããç¶æ¿ããå¿
èŠãªå Žæããããããèªã¿åããå¿
èŠãªå Žæã«è¿œå ããŸãã
æ§æããªãŒã®åæãšç·šéã«ã¯ã
Visitorãã¿ãŒã³ïŒ
LINQ ïŒãç©æ¥µçã«äœ¿çšãããŸãã åŸè
ã¯éåžžã«äžäŸ¿ã§ãéåžžã«åçŽãªåæã«é©ããŠããŸãã ãããžã§ã¯ãã³ãŒãã§ã¯ã
SyntaxVisitor ã
SyntaxWalkerããã³
SyntaxRewriterã¯ã©ã¹ãç©æ¥µçã«äœ¿çšã
ãŸãã ã æåã®2ã€ã®ãŠãŒã¹ã±ãŒã¹-æ§æããªãŒã®åæã ããšãã°ãã¯ãšã¹ããããããã«è¿œå ããããéãã«æšªã«ãªã£ãŠèª°ã«ãè§Šããªãããã«ããããšãã§ããŸãã ãã®ç¹æ§ã倿ããã«ã¯ãã¯ãšã¹ãã³ã³ã¹ãã©ã¯ã¿ãŒãã©ããã§åŒã³åºããããã©ããã確èªããå¿
èŠããããŸãã Roslynã䜿çšãããšãããã¯éåžžã«ç°¡åã§ããSyntaxWalkerããç¶æ¿ãããã¹ãŠã®ObjectCreationExpressionãã蚪åãããŸãã
æ§ç¯ãããã¢ãã«ã®è¡šç€ºã
ããã§ãã¢ãã«ãäœæããŸããã ããã衚瀺ãããŸãŸã«ããŠãç·šéæ¹æ³ãåŠã³ãŸãã
ã¢ãã«ãããã³ã°ã¯ã
NShapeãªãŒãã³ã©ã€ãã©ãªã䜿çšããŠå®è£
ãããŸããã ãã®ãããžã§ã¯ãã¯ç¿åŸãæãç°¡åã§ãæ©èœãè±å¯ã§ããããšã倿ããŸããïŒãã ããæ¡åŒµã®æ©äŒããã£ãšå¿
èŠãªå ŽåããããŸã...ïŒã ã¯ãšã¹ãã°ã©ãã®é ç¹ãé
眮ããããã«ã
Microsoft Automatic Graph Layoutã©ã€ãã©ãªã®
Sugiyamaã¢ã«ãŽãªãºã ã䜿çšããŸããããŸããããã€ãã®ãã¥ãŒãªã¹ãã£ãã¯ãäœæããå¿
èŠããããŸããã
æåã®ã»ã¯ã¿ãŒã§ã®ã¯ãšã¹ãã®äŸãæããŸãã

åæåã³ãŒããããã¯ããã«ãŠãŒã¶ãŒãã¬ã³ããªãŒã«èŠããŸãããïŒ ïŒããã¯ãŸã éåžžã«åçŽãªäŸã§ãã¯ãšã¹ãã¯ã»ãšãã©ãªããç·åœ¢ã®é åºã§åæåãããŠããŸããïŒãããŠãããã«ã¯ãšã¹ãããžãã¯ã®è¡šç€ºããããŸãïŒãããã°ã©ããŒçšãã¢ãŒãã¯ã³ãŒãã衚瀺ããããã§ãã

ã¢ãã«ã®ç·šé[æè¡ã»ã¯ã·ã§ã³]ã
NShapeã©ã€ãã©ãª
㯠ããã€ã¢ã°ã©ã ãäœæããã³ç·šéããããã«èšèšãããŠããŸãã è«çæ§é ãå³åœ¢åŒã§è¡šç€ºããã®ã§ããã®ïŒæ§é ïŒèŠèŠçç·šéã®å¯èœæ§ããããŸãã äž»ãªããšã¯ã倿Žãæ£ããè§£éããç¡å¹ãªå€æŽãçŠæ¢ããããšã§ãã
ãã€ã¢ã°ã©ã äžã®ã¢ã¯ã·ã§ã³ã®è«çã¢ã¯ã·ã§ã³ãžã®å€æã¯ãNShapeã©ã€ãã©ãªã®ããŒã«ã®ç¹å¥ãªã©ãããŒã§è¡ãããŸãïŒãã®ã³ãŒããæžãã®ã¯ãŸã åã³ã§ããïŒã è«çã¢ãã«ã®ã³ã³ããã¹ãã§äœããã®æå³ãæã€ã¢ã¯ã·ã§ã³ã®ã¿ã倿ãããŸãïŒããšãã°ãã¯ãšã¹ãã瀺ã圢ç¶ã®å転ã¯ãè¡šç€ºæ¹æ³ã®æ§é çãªå€æŽãæå³ããŸããïŒã ãã¹ãŠã®ã¢ã¯ã·ã§ã³ã¯Commandã¿ã€ãã®ãªããžã§ã¯ãã«ã«ãã»ã«åããïŒ
ãã¿ãŒã³ãèªèããŸãããïŒïŒãå
ã«æ»ãããšãã§ããŸãã
delegate void DoneHandler(bool firstTime); delegate void UndoneHandler(); interface ICommand { DoneHandler Done { get; set; } UndoneHandler Undone { get; set; } void Do(); void Undo(); }
ãã®ã€ã³ã¿ãŒãã§ã€ã¹ïŒããã³ãããå®è£
ããæœè±¡ã¯ã©ã¹ïŒã¯ãè«çã¢ãã«ãšã³ãŒãã®å€æŽãæ
åœããŸãã èŠèŠçãªãã¬ãŒã³ããŒã·ã§ã³ã¯ãDone / Undoneããªã²ãŒããžã®ãµãã¹ã¯ãªãã·ã§ã³ãéããŠæŽæ°ãããŸãã
è€åã¢ã¯ã·ã§ã³ã®åå²äžéšã®ã¢ã¯ã·ã§ã³ã¯ãä»ã®ããã€ãã®ã¢ã¯ã·ã§ã³ã§æ§æãããŠããŸãã ããšãã°ã2ã€ã®ã¯ãšã¹ãããªã³ã¯ããŸãã äž¡æ¹ãã¢ã¯ãã£ãã«ãªã£ãŠããå Žåããã®1ã€ã®ã¢ã¯ã·ã§ã³ã¯æ¥ç¶ã®çŽæ¥è¿œå ã§ãã ãããã®å°ãªããšã1ã€ãéã¢ã¯ãã£ãã§ããå Žåãæ¥ç¶ã確ç«ããåã«ãæå¹åãããå¿
èŠããããŸãã ãŸãã¯å¥ã®äŸ-ã¯ãšã¹ãã®åé€ã ã¯ãšã¹ããåé€ããåã«ãåå ããŠãããã¹ãŠã®ãªã³ã¯ãåé€ããã¯ãšã¹ããç¡å¹ã«ããå¿
èŠããããŸãã ãã®ãããªåå²ã«ãããè€éãªã¢ã¯ã·ã§ã³ãã³ã³ããŒãã³ãã«åå²ãããããããä»ã®ã¢ã¯ã·ã§ã³ãèšèšã§ããŸãã
ã³ãŒãã§ã¯ãããã¯ã³ãã³ãã®ç¹å®ã®ã±ãŒã¹-CompositeCommandãä»ããŠå®è£
ãããŸãã
class CompositeCommand : Command { private readonly List<ICommand> commands = new List<ICommand>(); public override void Do() { foreach (var cmd in commands) { cmd.Do(); } } public override void Undo() { foreach (var cmd in Enumerable.Reverse(commands)) { cmd.Undo(); } } }
ããã§ã¯ããã®ã³ãã³ãã®[å
ã«æ»ã]ããããã£ã®ç·šéã匷調衚瀺ããŸãã å®éã«ã¯ãã³ãã³ãã¯è¿œå ã®é åºã§å®è¡ãããããŒã«ããã¯ãããŸã-éã«ã ãããã£ãŠãå
ã«æ»ãããªã²ãŒãã¯éã®é åºã§çµåããå¿
èŠããããŸãã
public void AddCommands(IEnumerable<ICommand> commandsToAdd) {
æ§æããªãŒã®ç·šéã«ã¯ãäžèšã®ããã«
CSharpSyntaxRewriterã¯ã©ã¹ã®æ¡åŒµã䜿çšãããŸãïŒææ³ã«ã€ããŠã¯ã
ãã¡ãã§è©³ãã説æãããŠã
ãŸã ïŒã ã¯ãšã¹ããç¡å¹ã«ããäŸïŒã³ã³ã¹ãã©ã¯ã¿ãŒåŒã³åºããåé€ããïŒïŒ
class DeactivateQuestCommand : Command {
Roslynã«ã¯ãããã«äœ¿çšã§ããç·šéæ©èœãããã€ãçšæãããŠããŸãã é¡èãªäŸã¯ãååã®å€æŽïŒ
Renamer ïŒããã³ã¹ããŒã¹ã®ãã©ãŒãããïŒ
Formatter ïŒã§ãã ãããŠãããã¯äººçã倧ãã«ç°¡çŽ åããŸãã
çŸæç¹ã§ã¯ãæ¢åã®ã³ãŒããåé€/倿Žãããšããäºå®ã®ã¿ãæ±ããŸããã ãããŠãæ°ããäžä»£ã¯ã©ãã§ããïŒ ããã¯ã
SyntaxFactory .Parse *ããã³ããŒââã倿Žé¢æ°ãä»ããŠç°¡åã«å®è¡ãããŸãã
var linkExprText = $"ReachedCondition = {newLinkText}"; var newInitializer = node.Initializer.AddExpressions(SyntaxFactory.ParseExpression(linkExprText));
ãæ°ã¥ããããããŸãããïŒ2è¡ç®ãæ³šææ·±ãèŠããšïŒãAddExpressions颿°ã¯æ°ããããŒããè¿ããŸãã äžè¬ã«ãRoslynå
šäœã¯ã¢ãŒããã¯ãã£ã®æ©èœçã¢ãããŒãã«åŸããŸããäœãã倿Žããå Žåã¯ãå¿
èŠãªãã©ã¡ãŒã¿ãŒã䜿çšããŠæ°ãããã®ãäœæããŸãã æåã¯äžäŸ¿ã§ãããããããããªãã¯ãããæãå§ããŸãã
ã³ãŒãä¿®æ£ã«ã€ããŠRoslynã¯è¯ãããŒã«ã§ãããå
šèœã§ã¯ãããŸããã ããšãã°ãã³ãŒãã®å€æŽåŸãäºçްãªã³ã³ãã€ã«ãšã©ãŒãçºçããå ŽåããããŸãã ãããŠãããããèªåã§ä¿®æ£ããå¿
èŠããããŸãã ãã®ãããç§ã¯ã»ã¯ã¿ãŒå
ã®ã¯ãšã¹ãã®åæåã®é åºã®ããã«ã³ãŒãä¿®æ£ãæžããªããã°ãªããŸããã§ããã
ãã®ãããªã³ãŒããäœæããã«ã¯ãææ³ïŒç¢ºèª/ç·šé/äœæããå¿
èŠãããæ§æåäœã®çš®é¡ïŒãšRoslyn APIã®ååãªç¥èãå¿
èŠã§ãã ããããå¿
èŠãªãã®ããã¹ãŠæã£ãåŸãRoslynã䜿çšããããã°ã©ãã³ã°ã¯æ¥œãããã®ã«ãªããŸãïŒç¹ã«ã¢ãŒããã¯ãã£ã®ç¹ã§ãç§ã¯çŸããã³ãŒããšæ©èœã®å€§ãã¡ã³ã§ãïŒã
ãšãã£ã¿ãŒã®æ©èœãšãã¬ãŒããªãã å®çšçãªäŸã
ãããŸã§ããšãã£ã¿ãŒãšãã®æ©èœã«ã€ããŠã¯ã»ãšãã©èšåãããŠããŸããã§ããã ç¶æ³ãä¿®æ£ããŸãããïŒæåŸã«ãæ£ç¢ºã«ç·šéã§ããå
å®¹ãæ©èœã®è±å¯ããšè€éãã®ãã©ã³ã¹ããšãããã«ã©ã®ãããªåŠ¥åãå¿
èŠããè°è«ããå®éã®å®è·µããã®äŸãæ€èšããŸãïŒå€å°ç°¡ç¥åãããŠããŸããïŒã
ããã§ãã³ãŒããç·šéããããšã«ããŸããã èšèé£ãã¯éåžžã«æãããšãèªããŠããŸãã ããã§ã¯ã人ã
ã¯ãã€ãæ¬æ¥ã®ããã«æžããšã¯éããŸããããä»ã®ã³ãŒãã
åæããŠ
å€æŽ ããããã°ã©ã ãæžãå¿
èŠããããŸãã ãããŠãããã¯å¿
ãããç§ãã¡ã«ãã£ãŠæžãããŠããããã§ã¯ãããŸããã å¶éãªãã§ã¯ã§ããŸããã
ç§ãæåã«èª¬æãããã®ã¯ãè§£éæ¹æ³ãããããªãã³ãŒããèŠã€ããå Žåã®ãšãã£ã¿ãŒã®åäœã§ãïŒããã°ã©ããŒã®å
éšã®åé¡ããããã³ã°ããããžã§ã¯ãã«å
¥ããã©ãããæ£ç¢ºã«èšãããšãã§ããªãæ°æ©èœãªã©ã ã ãã®ç¶æ³ã¯éåžžã«æ
éã«ã解決ãããå¿
èŠããããŸãã ããããªããšãããŒã«ã¯è¯ãããšããã害ã«ãªããŸãã
ãã®åé¡ãã©ã®ããã«è§£æ±ºããŸãããïŒ
ããªããçè§£ããŠããªãããšã§éã°ãªãã§ãã ããã çè§£ãããšããããšã¯ãã³ãŒãã®è«ççãªæå³ã«é¢ããããã°ã©ã ã®ç¥èãæå³ããŸãã æœè±¡çãããïŒ ä»¥äžã«äŸãããã€ã瀺ããŸãã
æåã®äŸã ã¯ãšã¹ãã¯ã次ã®ã¬ãã«ã ãã§ãªãã3ã€ã®ã¬ãã«ãå®äºããåŸã«ãã¢ã¯ãã£ãã«ããå¿
èŠããããŸãã ãŸãã¯5ã ãããŠããŠãŒã¶ãŒãæ¯æ¥ã®å ±é
¬ãäžããããåŸã§ãã äžè¬çã«ãããã€ãã®è¿œå æ¡ä»¶ããããŸãã äžè¬çãªã±ãŒã¹ã§ã¯ããšãã£ã¿ãŒãããã®ãããªæ¡ä»¶ãæå®ããããšã¯ã§ããŸãããããã°ã©ããŒã®ä»å
¥ãå¿
èŠã§ãã ããŠãããã°ã©ããŒã¯ã€ãã«èªåèªèº«ãè§£æŸããã³ãŒãã«æ°è¡ã远å ããŸããã æ¬¡ã¯ïŒ ãŸãããšãã£ã¿ãŒã¯ãããå³ã«è¡šç€ºããŸãã

ãŠãŒã¶ãŒã¯ããã®ã¯ãšã¹ãã§ã¯ããã»ã©ç°¡åã§ã¯ãªãããšãããã«ããããŸãã 第äºã«ãæªç¥ã®ïŒãšãã£ã¿ãŒã«ãã£ãŠãœãŒããããŠããªãïŒæ¡ä»¶ãç·šéããããšã¯çŠæ¢ãããŠããŸãã ã§ããããšã®æå€§ã¯ããœãŒã¹ã³ãŒããšããã«æ®ãããã³ã¡ã³ããèªãããšã§ãïŒäŸ¿å©ãªæ©èœ-ããã°ã©ããŒãã³ãŒãã®æå³ãæªçµéšè
ã«èª¬æã§ããããã«ããŸãïŒã 第äžã«ã
æ°ããæ¡ä»¶ã®è¿œå ã®ã¿ãèš±å¯ãããŸãïŒãããŠãã¡ããããããã®ç·šéãšåé€ïŒã ããªãã¡ æ¡ä»¶ã
ããå³ãããªãããšãã£ã¿ãŒãèš±å¯ããç¯å²å
ã«ãªãå¯èœæ§ããããŸãã
2çªç®ã®äŸã ã¯ãšã¹ãã®ããžãã¯ïŒã¢ã¯ã·ã§ã³ïŒã®åæ§ç¯ãããŠããªãã³ãŒãã ããããæãäžè¬çãªç¶æ³ã ããã§ã®å²åŠã¯åãã§ãïŒç·šéãèš±å¯ãããéæ¿ã«ç®ç«ããªã
èŠåã衚瀺ããŸã ïŒäžè¬ã«ãã¢ã»ã³ãã«ãããŠããªãã³ãŒããé衚瀺/衚瀺ãããã§ãã¯ããŒã¯ããããŸãïŒã
2çªç®ã«è°è«ããããšã¯ãå®è¡ã¹ã¬ããã®ç·šéã§ãã ããšãã°ãã¯ãšã¹ãã®1ã€ã«ã¯ããžãã¯ã®äžéšããããããèªäœã¯ãªãã·ã§ã³ã§ãããç¹å®ã®äžå¯åãªæ¡ä»¶ã«ãã£ãŠã®ã¿èµ·åãããŸãã ç·šéãå®å
šã«çŠæ¢ããã®ã¯æããªããšã§ãã ãããã£ãŠããã®å¯èœæ§ããŠãŒã¶ãŒã«ä»»ããããšã決å®ãããŸããããããã€ãã®æ³šæäºé
ããããŸãïŒéå§æ¡ä»¶ïŒifãwhileã®æ¡ä»¶ïŒã®ç·šéã¯èš±å¯ããããäžè¬çãªã±ãŒã¹ã§ã¯ãããã¯å
šäœãç§»åããŸãïŒã¯ããèŠãçå®-ç§»åã¯ã³ã³ãã€ã«ãäžæãããããã«æªãããšã«ãããžãã¯ã倿Žããããšã¯æããã§ã¯ãããŸããïŒã ããžãã¯ãç§»åããå¿
èŠããããŸããïŒ 2ã€ã®ãªãã·ã§ã³ïŒãŠãããããªãã«ããŠé©åãªå Žæã«æ°ãããŠããããäœæããããããã°ã©ãã«ã¿ã¹ã¯ãäžããŸãã
次ã«ãç°¡åãªäŸã瀺ããŠèª¬æããŸãã ã²ãŒã ãã¶ã€ããŒã¯ãFindKeyã¯ãšã¹ããšOpenTheDoorã¯ãšã¹ãã®éã«TalkToLeeroyã¯ãšã¹ããæ¿å
¥ããŸãã ã¯ãšã¹ãã§ã¯ãã«ããã·ãŒã³ã衚瀺ããã¯ãšã¹ãã®çŽæ¥ééãåŸ
ã£ãŠããã2çªç®ã®ã«ããã·ãŒã³ã衚瀺ããŠãã¯ãšã¹ããå®äºããŸãã ã²ãŒã ãã¶ã€ããŒã®ã¢ã¯ã·ã§ã³ã®ã¢ã«ãŽãªãºã ïŒåœŒã«ä»£ãã£ãŠïŒïŒ
- æ°ããã¯ãšã¹ããæ¿å
¥ããå¿
èŠãããã¯ãšã¹ããèŠã€ããŸãïŒ

- ç®çã®ååã§æ°ããã¯ãšã¹ãã远å ããæ¥ç¶ãã¹ããŒããŸãã

- ã¯ãšã¹ãç·šéãŠã£ã³ããŠãéããå¿
èŠãªç¶æ
ã远å ããŸãã

- 次ã«ãåç¶æ
ã«å¿
èŠãªã¢ã¯ã·ã§ã³ãå
¥åããŸãã ããšãã°ãåæç¶æ
ã®ã¿ã¹ã¯ã¯ãæåã®ã«ããã·ãŒã³ã衚瀺ããããšã§ãã

- 顿šã«ãããæ®ãã®ç¶æ
ãæºããããŸãã
- ãšã©ãŒãçªç¶æ€åºãããå ŽåïŒããšãã°ãã€ã³ã¿ãŒãã§ã€ã¹ãé ããŠè¡šç€ºããã®ãå¿ããå ŽåïŒãããã«ã€ããŠèŠèŠçã«èŠåãããŸãïŒå³ã«ç¹å¥ãªããŒã¯ã衚瀺ãããŸãïŒã ãšã©ãŒãä¿®æ£ããŸãã
- ã²ãŒã ãéå§ãããã¹ãŠãæå³ãããšããã«æ©èœããããšã確èªããŸãã
ã ãããã¿ã¹ã¯ã¯å®äºããããããããªãã¶ã€ããŒã¯éãã«ãã¹ãã®ããã«åœŒå¥³ãéãããè¶ã飲ãããã«å»ããŸãããšãã£ã¿ãŒã®ç®çã¯ãã³ã³ãã³ãã®ãããã¿ã€ãããã°ããäœæããŠå
¥åããããšã§ãããæçµçã«ã¯ãã²ãŒã ã®ããžãã¯ïŒä»®æ³äžçã®å°ããªçãšç¥ïŒã«å¯Ÿãã絶察çãªåãæã€ã®ã¯ããã°ã©ãã ãã§ããããŒã«ã倧å¹
ã«è€éåããã®ã§ã¯ãªããã²ãŒã ã®æ©èœãæŽç·Ž/æ¹è¯ããã¿ã¹ã¯ã圌ã«äžããæ¹ãå®äŸ¡ã§ãïŒãããã£ãŠãããé©åã§ãïŒããããŠãããã¯ãã®ãããªç¶æ³ã«ããã»ã©è¿ããããŸããïŒ
ãããã«
ç§ã¯ãã¹ãŠãšã¯ã»ã©é ãããšãè¿°ã¹ãŠããŸãããããã€ãã®ç¹ïŒãšã©ãŒã®åæãšèŠèŠåãã»ã¯ã¿ãŒã®æäœãªã©ïŒãçç¥ããªããã°ãªããŸããã§ãããèå³ãããã°ãã³ã¡ã³ããæžããŠãããããå¥ã®èšäºãæžãã§ããããããã®ç®çã¯ãã²ãŒã éçºã«ããŸãé¢ä¿ããªããšæããããã®ãããªããŒã«ã§ãããå®éã«ããŸãé©çšã§ããããšã瀺ãããšã§ãããæçµçã«è¡ããããã®ïŒ- æã«ã¯ä»äºãå é
- ã²ãŒã ã®æ§é ãšã¢ãŒããã¯ãã£ã®æ¹å
- èè
ã¯Roslynãç ç©¶ããCïŒã®ç¥èãæ·±ããèšèšã¹ãã«ãåäžãããŸããã
RoslynãåŠç¿ãšäœ¿çšã«æšå¥šããŸããïŒ ãã¡ããã
èŸæ±åŒ·ãè¡ããŸãããã