{"id":22724762,"url":"https://github.com/cschladetsch/flow","last_synced_at":"2025-04-13T19:05:27.875Z","repository":{"id":4432887,"uuid":"5570987","full_name":"cschladetsch/Flow","owner":"cschladetsch","description":"C# co-routine Kernel for .Net. Includes Futures, Barriers, Triggers, Timers and Groups. Gamasutra article provides extra documentation.","archived":false,"fork":false,"pushed_at":"2023-03-10T05:51:17.000Z","size":2518,"stargazers_count":68,"open_issues_count":0,"forks_count":14,"subscribers_count":13,"default_branch":"master","last_synced_at":"2023-03-27T18:04:18.435Z","etag":null,"topics":["continuations","coroutine","coroutines","csharp","dotnet","flow","flow-control"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cschladetsch.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2012-08-27T12:54:18.000Z","updated_at":"2023-07-05T15:39:37.895Z","dependencies_parsed_at":"2023-07-05T19:48:56.101Z","dependency_job_id":null,"html_url":"https://github.com/cschladetsch/Flow","commit_stats":null,"previous_names":[],"tags_count":1,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschladetsch%2FFlow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschladetsch%2FFlow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschladetsch%2FFlow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cschladetsch%2FFlow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cschladetsch","download_url":"https://codeload.github.com/cschladetsch/Flow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229082305,"owners_count":18017251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["continuations","coroutine","coroutines","csharp","dotnet","flow","flow-control"],"created_at":"2024-12-10T15:07:50.858Z","updated_at":"2024-12-10T15:07:51.546Z","avatar_url":"https://github.com/cschladetsch.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flow ![Foo](flow-small.jpg)\n[![Build status](https://ci.appveyor.com/api/projects/status/github/cschladetsch/flow?svg=true)](https://ci.appveyor.com/project/cschladetsch/flow)\n[![CodeFactor](https://www.codefactor.io/repository/github/cschladetsch/flow/badge)](https://www.codefactor.io/repository/github/cschladetsch/flow)\n[![License](https://img.shields.io/github/license/cschladetsch/flow.svg?label=License\u0026maxAge=86400)](./LICENSE.txt)\n![Release](https://img.shields.io/github/release/cschladetsch/flow.svg?label=Release\u0026maxAge=60)\n\nA C# coroutine-based Kernel for .Net. If you are one of the many developers using this library, I encourage you provide any feedback and/or fork.\n\nThis is Unity-friendly and will work on all versions of Unity after 4.0. Please let me know otherwise.\n\nCurrent documentation is at [GamaSutra](http://www.gamasutra.com/view/news/177397/Indepth_Flow__A_coroutine_kernel_for_Net.php) but the formatting is a bit screwy.\n\nThe original post was on [AltDevBlogADay](http://www.altdevblogaday.com/2012/09/07/flow-a-coroutine-kernel-for-net/) but that site is now lost for the ages.\n\n## Tests\n\nThe [tests](TestFlow/Editor) reside in _TestFlow/Editor_ so they can be used from Unity3d as well.\n\nThese tests, along with the GamaSutra article, are the best first sources of documentation.\n\n## Example 1\n\nUsing _Flow_ for async REST communications.\n\n```C#\nprivate void CreateHeartbeat()\n{\n    New.PeriodicTimer(TimeSpan.FromMinutes(2)).Elapsed += tr =\u003e\n    {\n        Get\u003cUserCount\u003e(\"user/alive\").Then(result =\u003e\n        {\n            if (result.Succeeded(out var val))\n            {\n                _activeUsers.Value = val.Num;\n                Info($\"{val.Num} users online.\");\n            }\n        });\n    };\n}\n```\n\n## Example 2\n\nThis is example code pulled straight for a [game](https://github.com/cschladetsch/Chess2) I'm quasi-working on:\n\n```C#\npublic void GameLoop()\n{\n    Root.Add(\n        New.Sequence(\n            New.Coroutine(StartGame).Named(\"StartGame\"),\n            New.While(() =\u003e !_gameOver),\n                New.Coroutine(PlayerTurn).Named(\"Turn\").Named(\"While\"),\n            New.Coroutine(EndGame).Named(\"EndGame\")\n        ).Named(\"GameLoop\")\n    );\n}\n```\nNote the `.Named(\"Name\")` extensions to the factory methods: these are for debugging and tracing purposes. The library comes with extensive debugging and visualisation support, so you can see in real time as the kernel changes.\n\nThe main logic _flow_ for starting a turn is:\n\n```C#\nprivate IEnumerator StartGame(IGenerator self)\n{\n    var start = New.Sequence(\n        New.Barrier(\n            WhitePlayer.StartGame(),\n            BlackPlayer.StartGame()\n        ).Named(\"Init Game\"),\n        New.Barrier(\n            WhitePlayer.DrawInitialCards(),\n            BlackPlayer.DrawInitialCards()\n        ).Named(\"Deal Cards\"),\n        New.Barrier(\n            New.TimedBarrier(\n                TimeSpan.FromSeconds(Parameters.MulliganTimer),\n                WhitePlayer.AcceptCards(),\n                BlackPlayer.AcceptCards()\n            ).Named(\"Mulligan\"),\n            New.Sequence(\n                WhitePlayer.PlaceKing(),\n                BlackPlayer.PlaceKing()\n            ).Named(\"Place Kings\")\n        ).Named(\"Preceedings\")\n    ).Named(\"Start Game\");\n    start.Completed += (tr) =\u003e Info(\"StartGame completed\");\n    yield return start;\n}\n```\n\nAnd the relevant IPlayerAgent Method declaractions as being:\n\n```C#\nITimer StartGame();\nITimer DrawInitialCards();\nITimedFuture\u003cbool\u003e AcceptCards();\nITimedFuture\u003cPlacePiece\u003e PlaceKing();\nITransient ChangeMaxMana(int i);\nITimedFuture\u003cICardModel\u003e DrawCard();\nITimedFuture\u003cPlacePiece\u003e PlayCard();\nITimedFuture\u003cMovePiece\u003e MovePiece();\nITimedFuture\u003cPass\u003e Pass();\n```\n\nThis is just a simple example on how the library is tyically used. It's a matter of chaining together sequences of _Barriers_, _Triggers_, and _Futures_ to remove the need to keep explicit track of internal state on each *Update* call.\n\nIn this case, I'm using a lot of timed futures because it's a real-time card game and there are time limits.\n\n## Notes\n### Verbose Logging\nWhen using `Verbose()` be mindful that the arguments passed into the log will be evaluated even if the verbosity is set lower than would print. Be diligent when using interpolated strings or complex functions in Verbose logging.\ne.g.\n```csharp\nVerbosity = 10;\nVerbose(15, $\"Result of complex function: {ComplexFunction()}.\");\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcschladetsch%2Fflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcschladetsch%2Fflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcschladetsch%2Fflow/lists"}