//--- Constructors --- public NotificationDelayQueue(TimeSpan delay, CoroutineHandler<NotificationUpdateRecord, Result> callback) { _delay = delay; _callback = callback; _queueTimer = new TaskTimer(CheckExpire, null); _queueTimer.Change(_delay, TaskEnv.None); _dispatchQueue = new ProcessingQueue<NotificationUpdateRecord>(Dispatch, 10); }
private void OnActivated(Point pos) { foreach (var layer in this.Map.Tiles.TileLayers) { var tile = layer.GetTile(pos.X, pos.Y); if (tile.IsBlank) { continue; } var tilesetTile = tile.GetTilesetTile(this.Map.Tiles); // switches if (tilesetTile.Properties.GetBool("Switch")) { foreach (var other in this.Map.Tiles.TileLayers) { if (other.Properties.GetInt("ActivatorX") != pos.X || other.Properties.GetInt("ActivatorY") != pos.Y) { continue; } var activated = other.Properties.GetBool("Activated"); var co = activated ? this.Map.RemoveLayerFromGround(other) : this.Map.AddLayerToGround(other); this.activationCutscenes.Add(CoroutineHandler.Start(co)); other.Properties["Activated"] = (!activated).ToString(); } var active = tilesetTile.Properties.GetInt("ActiveState"); if (active > 0) { this.Map.SetTile(pos.X, pos.Y, active, layer.Name); } MlemGame.LoadContent <SoundEffect>("Sounds/Button").Play(); } } }
//Android用 TODO そのままCoroutineで返したほうがいい static void CopyFile(IObserver <Unit> observer, string fileName) { string baseFilePath = string.Format("{0}/{1}.json", Application.streamingAssetsPath, fileName); string targetFilePath = string.Format("{0}/{1}.json", Application.persistentDataPath, fileName); CoroutineHandler.StartStaticCoroutine(CopyFileCoroutine(observer, baseFilePath, targetFilePath)); }
// File management static public void Create() { if (m_Instance == null) { m_Instance = new PlayerData(); //if we create the PlayerData, mean it's the very first call, so we use that to init the database //this allow to always init the database at the earlier we can, i.e. the start screen if started normally on device //or the Loadout screen if testing in editor CoroutineHandler.StartStaticCoroutine(CharacterDatabase.LoadDatabase()); CoroutineHandler.StartStaticCoroutine(ThemeDatabase.LoadDatabase()); } m_Instance.saveFile = Application.persistentDataPath + "/save.bin"; if (File.Exists(m_Instance.saveFile)) { // If we have a save, we read it. m_Instance.Read(); } else { // If not we create one with default data. NewSave(); } m_Instance.CheckMissionsCount(); }
public void TestEventBasedCoroutine() { var counter = 0; var myEvent = new Event(); IEnumerator <Wait> OnEventTriggered() { counter++; yield return(new Wait(myEvent)); counter++; } var cr = CoroutineHandler.Start(OnEventTriggered()); Assert.AreEqual(1, counter, "instruction before yield is not executed."); CoroutineHandler.Tick(1); CoroutineHandler.RaiseEvent(myEvent); Assert.AreEqual(2, counter, "instruction after yield is not executed."); CoroutineHandler.Tick(1); CoroutineHandler.RaiseEvent(myEvent); Assert.AreEqual(2, counter, "instruction after yield is not executed."); Assert.AreEqual(true, cr.IsFinished, "Incorrect IsFinished value."); Assert.AreEqual(false, cr.WasCanceled, "Incorrect IsCanceled value."); Assert.AreEqual(cr.MoveNextCount, 2, "Incorrect MoveNextCount value."); }
public void Update(GameTime time) { if (this.currentMove != null && !this.currentMove.IsFinished) { return; } do { if (this.remainingRound.Count <= 0) { this.PopulateRound(); } this.currentEntity = this.remainingRound.Dequeue(); if (this.currentEntity.IsDead) { continue; } var turn = this.currentEntity.MakeTurn(this); if (turn == null) { continue; } this.currentMove = CoroutineHandler.Start(turn.GetEnumerator()); break; } while (true); }
public void DisplayCaption(string[] text, Action <GameImpl> afterDisplay = null) { IEnumerator <IWait> CaptionImpl() { foreach (var par in text) { this.caption.RemoveChildren(); var lines = par.Split("\n"); var paragraphs = new Paragraph[lines.Length]; for (var i = 0; i < lines.Length; i++) { paragraphs[i] = this.caption.AddChild(new Paragraph(Anchor.AutoCenter, 1, lines[i], true)); } this.caption.DrawAlpha = 0; while (this.caption.DrawAlpha < 1) { this.caption.DrawAlpha += 0.01F; yield return(new WaitEvent(CoroutineEvents.Update)); } yield return(new WaitSeconds(3)); while (this.caption.DrawAlpha > 0) { this.caption.DrawAlpha -= 0.01F; yield return(new WaitEvent(CoroutineEvents.Update)); } yield return(new WaitSeconds(1)); } afterDisplay?.Invoke(this); } this.cutscene = CoroutineHandler.Start(CaptionImpl()); }
public override void ChangePhase(Phase changedPhase) { if (!Initialized) { return; } switch (changedPhase) { case Phase.P2D: vcams[1].SetActive(false); vcams[2].SetActive(false); switch (LastAttackPlayerNum) { case 0: CoroutineHandler.StartStaticCoroutine(LerpCamView(0, new Rect(0, 0, 1, 1), 0.25f)); CoroutineHandler.StartStaticCoroutine(LerpCamView(1, new Rect(1, 0, 0, 1), 0.25f)); break; case 1: CoroutineHandler.StartStaticCoroutine(LerpCamView(0, new Rect(0, 0, 0, 1), 0.25f)); CoroutineHandler.StartStaticCoroutine(LerpCamView(1, new Rect(0, 0, 1, 1), 0.25f)); break; } break; case Phase.P3D: vcams[1].SetActive(true); vcams[2].SetActive(true); CoroutineHandler.StartStaticCoroutine(LerpCamView(0, new Rect(0, 0, 0.5f, 1), 0.25f)); CoroutineHandler.StartStaticCoroutine(LerpCamView(1, new Rect(0.5f, 0, 0.5f, 1), 0.25f)); break; } }
static public IEnumerator LoadDatabase(List <string> packages) { if (m_SkinsDict == null) { m_SkinsDict = new Dictionary <string, Skin>(); foreach (string s in packages) { AssetBundleLoadAssetOperation op = AssetBundleManager.LoadAssetAsync(s, "skin", typeof(GameObject)); yield return(CoroutineHandler.StartStaticCoroutine(op)); Skin c = op.GetAsset <GameObject>().GetComponent <Skin>(); if (c != null) { m_SkinsDict.Add(c.skinName, c); m_skinNameList.Add(c.skinName); overlapCharNameList.Add(c.characterName); } } for (int i = 0; i < overlapCharNameList.Count; i++) { if (!m_charNameList.Contains(overlapCharNameList[i])) { m_charNameList.Add(overlapCharNameList[i]); } } m_Loaded = true; } }
public static void Main() { var seconds = CoroutineHandler.Start(WaitSeconds(), "Awesome Waiting Coroutine"); CoroutineHandler.Start(PrintEvery10Seconds(seconds)); CoroutineHandler.Start(EmptyCoroutine()); CoroutineHandler.InvokeLater(new Wait(5), () => { Console.WriteLine("Raising test event"); CoroutineHandler.RaiseEvent(TestEvent); }); CoroutineHandler.InvokeLater(new Wait(TestEvent), () => Console.WriteLine("Example event received")); CoroutineHandler.InvokeLater(new Wait(TestEvent), () => Console.WriteLine("I am invoked after 'Example event received'"), priority: -5); CoroutineHandler.InvokeLater(new Wait(TestEvent), () => Console.WriteLine("I am invoked before 'Example event received'"), priority: 2); var lastTime = DateTime.Now; while (true) { var currTime = DateTime.Now; CoroutineHandler.Tick(currTime - lastTime); lastTime = currTime; Thread.Sleep(1); } }
void Start() { if (m_singleton == null) { m_singleton = this; m_coroutines = new Dictionary<int, CoroutineInstance>(); } }
void Awake() { fadeHandler = new CoroutineHandler(this, FadeOut(2f, canvasGroup)); GetComponent <SceneLoader>() .OnSceneLoaded(this, 1) .LoadAsync(1); }
public void TestTimerBasedCoroutine() { var counter = 0; IEnumerator <Wait> OnTimeTickCodeExecuted() { counter++; yield return(new Wait(0.1d)); counter++; } var cr = CoroutineHandler.Start(OnTimeTickCodeExecuted()); Assert.AreEqual(1, counter, "instruction before yield is not executed."); Assert.AreEqual(string.Empty, cr.Name, "Incorrect default name found"); Assert.AreEqual(0, cr.Priority, "Default priority is not minimum"); for (var i = 0; i < 5; i++) { CoroutineHandler.Tick(1); } Assert.AreEqual(2, counter, "instruction after yield is not executed."); Assert.AreEqual(true, cr.IsFinished, "Incorrect IsFinished value."); Assert.AreEqual(false, cr.WasCanceled, "Incorrect IsCanceled value."); Assert.AreEqual(cr.MoveNextCount, 2, "Incorrect MoveNextCount value."); }
public static void TweetWithImage(string gameId, string text, params string[] hashTags) { if (_currentCoroutine != null) { Debug.Log("画像アップロード中に多重呼び出しされました。"); return; } var tweetData = new TweetData(gameId, text, hashTags); var title = tweetData.GameUrl; var desc = text; _currentCoroutine = CoroutineHandler.StartStaticCoroutine( GyazoUploader.CaptureScreenshotAndUpload( title , desc , (res, error) => { if (string.IsNullOrEmpty(error)) { Debug.Log("画像アップロード成功 : " + res.permalink_url); //エラーなし => ツイートする tweetData.ImageUrl = res.permalink_url; Tweet(tweetData); } else { //エラーあり Debug.LogError("画像アップロード失敗 : " + error); } _currentCoroutine = null; })); }
// 엔딩 연출 private IEnumerator Ending() { SoundManager.Instance.PlayBGM("Ending"); SoundManager.Instance.PlaySfx("Firework", 0.1f); canvasUI.SetActive(false); cardCanvas.SetActive(false); endingUI.transform.GetChild(0).gameObject.SetActive(true); CoroutineHandler.Start_Coroutine(ShowConfetti()); float startScale = 0.1f; float endScale = 1; float time = 0; float endTime = 0.15f; while (time < endTime) { float progress = Mathf.Lerp(startScale, endScale, time / endTime); endingUI.transform.localScale = new Vector3(progress, progress, progress); time += Time.deltaTime; yield return(new WaitForSeconds(Time.deltaTime)); } yield return(new WaitForSeconds(0.9f)); while (true) { CoroutineHandler.Start_Coroutine(ShowConfetti()); yield return(new WaitForSeconds(1.35f)); } }
public void StartTask() { if (null == task || !task.Running) { finish = false; Debug.Log("协程开始"); task = MyAwesomeTask().Start(); task.OnCompleted.AddListener(v => //第一种事件注册方式 { if (v) { Debug.Log("操作完成:用户取消了操作!"); } else { Debug.Log("操作完成!"); } }); task.OnComplete(v => Debug.Log("喵呜~ ---" + v)); //第二种事件注册方式(链式) } else { Debug.Log("不需要启动的Task"); } }
//--- Constructors --- public UpdateRecordDispatcher(CoroutineHandler <UpdateRecord, Result> callback, int maxParallelism, int maxRetry, TimeSpan retrySleep) { _dispatchQueue = new ProcessingQueue <QueueItem>(DispatchRecord, maxParallelism); _callback = callback; _maxRetry = maxRetry; _retrySleep = retrySleep; }
// 배틀 시작 이벤트가 오면 init하고 자기 자신 업데이트에 넣기 // 몬스터가 죽는 이벤트가 오면 카운트 증가시키고 죽은 몬스터가 현재 스테이지의 몬스터 수가 되면 배틀 종료 이벤트 발행 public bool OnEvent(IEvent e) { Type eventType = e.GetType(); if (eventType == typeof(BattleStageStartEvent)) { BattleStageStartEvent battleStateStartEvent = e as BattleStageStartEvent; Init(battleStateStartEvent.Stage); GameManager.Instance.AddUpdate(this); return(true); } else if (eventType == typeof(MonsterDeadEvent)) { MonsterDeadEvent monsterDeadEvent = e as MonsterDeadEvent; stageMonsterList.Remove(monsterDeadEvent.DeadUnit); deadMonsterCount++; if (deadMonsterCount >= currentStageMonsterCount) { if (GameManager.Instance.Stage + 1 >= stageGroupData.StageDataGroup.Count) { CoroutineHandler.Start_Coroutine(Ending()); } else { CoroutineHandler.Start_Coroutine(EndBattleStage()); } } return(true); } return(false); }
public override void Enter(AState from) { m_CountdownRectTransform = countdownText.GetComponent <RectTransform>(); m_LifeHearts = new Image[k_MaxLives]; for (int i = 0; i < k_MaxLives; ++i) { m_LifeHearts[i] = lifeRectTransform.GetChild(i).GetComponent <Image>(); } if (MusicPlayer.instance.GetStem(0) != gameTheme) { MusicPlayer.instance.SetStem(0, gameTheme); CoroutineHandler.StartStaticCoroutine(MusicPlayer.instance.RestartAllStems()); } m_AdsInitialised = false; m_GameoverSelectionDone = false; StartGame(); }
/// <summary> /// 最新データをダウンロードする /// </summary> /// <returns></returns> private IEnumerator SetLastNews() { //最新ニュースデータ取得 var Async = ClalisForLiplisGetNewsList.GetNewsList(); //非同期実行 yield return(Async); //データ取得 ResLpsBaseNewsList DataList = (ResLpsBaseNewsList)Async.Current; //データセット LiplisStatus.Instance.NewsList.SetData(DataList); //取得ニュースデータ保存 CoroutineHandler.StartStaticCoroutine(Save()); //最終更新時刻設定 LiplisStatus.Instance.NewsList.LastUpdateTime = LpsDatetimeUtil.Now; //要求データセット LiplisCache.Instance.ImagePath.SetRequestUrlQ(); yield return(null); }
public void InvokeLaterAndNameTest() { var myEvent = new Event(); var counter = 0; var cr = CoroutineHandler.InvokeLater(new Wait(myEvent), () => { counter++; }, "Bird"); CoroutineHandler.InvokeLater(new Wait(myEvent), () => { counter++; }); CoroutineHandler.InvokeLater(new Wait(myEvent), () => { counter++; }); Assert.AreEqual(0, counter, "Incorrect counter value after 5 seconds."); CoroutineHandler.Tick(1); CoroutineHandler.RaiseEvent(myEvent); Assert.AreEqual(3, counter, "Incorrect counter value after 10 seconds."); Assert.AreEqual(true, cr.IsFinished, "Incorrect IsFinished value."); Assert.AreEqual(false, cr.WasCanceled, "Incorrect IsCanceled value."); Assert.AreEqual(cr.MoveNextCount, 2, "Incorrect MoveNextCount value."); Assert.AreEqual(cr.Name, "Bird", "Incorrect name of the coroutine."); }
public override void _Ready() { if (Coroutine == null) { Coroutine = new CoroutineHandler(); } }
public void TestOnFinishedEventExecuted() { var myEvent = new Event(); var counter = 0; IEnumerator <Wait> OnEvent() { counter++; yield return(new Wait(myEvent)); } void SetCounterToUnreachableValue(ActiveCoroutine coroutine) { counter = -100; } var cr = CoroutineHandler.Start(OnEvent()); CoroutineHandler.Tick(1); cr.OnFinished += SetCounterToUnreachableValue; for (var i = 0; i < 10; i++) { CoroutineHandler.RaiseEvent(myEvent); } Assert.AreEqual(-100, counter, "Incorrect counter value."); }
private IEnumerator setRemoteDesc(RTCSdpType type, string sdp) { var desc = new RTCSessionDescription { type = type, sdp = sdp }; OnLogEvent.Invoke($"SetRemoteDescription {type}", ""); var opSetDesc = peer.SetRemoteDescription(ref desc); yield return(opSetDesc); if (opSetDesc.IsError) { OnErrorEvent.Invoke($"SetRemoteDescription {type}", opSetDesc.Error.message); yield break; } if (type == RTCSdpType.Offer) { yield return(CoroutineHandler.StartStaticCoroutine(sendDesc(RTCSdpType.Answer))); } else { OnOpen.Invoke(); } }
// Use this for initialization void Start() { BehaviorTree tree = new BehaviorTree(); tree.Prepare(); tree.Awake(); CoroutineHandler.StartStaticCoroutine(tree.Update()); }
protected override void ImmediateReaction() { //canvas = TutorialController.Instance.cutScenePannel; myCorotine = CoroutineHandler.Start_Coroutine(FadeOut()).gameObject; }
//--- Constructors --- public NotificationDelayQueue(TimeSpan delay, CoroutineHandler <NotificationUpdateRecord, Result> callback) { _delay = delay; _callback = callback; _queueTimer = new TaskTimer(CheckExpire, null); _queueTimer.Change(_delay, TaskEnv.None); _dispatchQueue = new ProcessingQueue <NotificationUpdateRecord>(Dispatch, 10); }
public static void Shake(this Camera camera, float duration) { if (_startingCoroutine != null) { CoroutineHandler.StopStaticCoroutine(_startingCoroutine); } _startingCoroutine = CoroutineHandler.StartStaticCoroutine(_Shake(camera.transform, duration)); }
/// <summary> /// オブジェクトが非アクティブまたは削除される際の処理(解放) /// </summary> public void OnDisable() { if (Instance) { Destroy(Instance.gameObject); Instance = null; } }
private Yield Call_CatchAndLog(CoroutineHandler <int, Result <int> > coroutine, int value, Result <int> result) { Result <int> inner; yield return((inner = Coroutine.Invoke(coroutine, value, new Result <int>())).CatchAndLog(_log)); result.Return(inner); }
private static Yield Call(CoroutineHandler <int, Result <int> > coroutine, int p, Result <int> result) { Result <int> inner; yield return(inner = Coroutine.Invoke(coroutine, p, new Result <int>())); result.Return(inner); }
private Yield Call_Set_Fail(CoroutineHandler <int, Result <int> > coroutine, int value, Result <int> result) { int?receive = null; yield return(Coroutine.Invoke(coroutine, value, new Result <int>()).Set(_ => Assert.Fail())); result.Return(receive.Value); }
//--- Constructors --- /// <summary> /// Creates a new stage instance. /// </summary> /// <param name="name">Stage name.</param> /// <param name="handler">Stage handler.</param> /// <param name="access">Stage access level.</param> public DreamFeatureStage(string name, CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>> handler, DreamAccess access) { if(handler == null) { throw new ArgumentNullException("handler"); } this.Name = name ?? UNNAMED; this.Access = access; _handler = handler; }
public void Awake() { if (m_instance == null) { m_instance = this; DontDestroyOnLoad(this); } else { if (this != m_instance) { Destroy(gameObject); } } }
void Awake() { main = this; if (!Application.isPlaying) { return; } Application.targetFrameRate = 60; coroutineHandler = this.AddChild<CoroutineHandler>(); coroutineHandler.name = "CoroutineHandler"; Level level = GetComponentInChildren<Level>(); if (level == null) { LoadLevel(); } else { level.onPlayerReachedGoal = OnPlayerReachedGoal; foreach (Obstacle obstacle in GetComponentsInChildren<Obstacle>()) { obstacle.coroutineHandler = coroutineHandler; obstacle.onPlayerDetected = OnPlayerDetectedByObstacle; } foreach (Key key in GetComponentsInChildren<Key>()) { key.onTouchedByPlayer = level.TriggerPlayerObtainedKey; } } uiController.ToggleStart(true); }
//--- Constructors --- public UpdateRecordDispatcher(CoroutineHandler<UpdateRecord, Result> callback, int maxParallelism, int maxRetry, TimeSpan retrySleep) { _dispatchQueue = new ProcessingQueue<QueueItem>(DispatchRecord, maxParallelism); _callback = callback; _maxRetry = maxRetry; _retrySleep = retrySleep; }
private Yield Call_Set_Fail(CoroutineHandler<int, Result<int>> coroutine, int value, Result<int> result) { int? receive = null; yield return Coroutine.Invoke(coroutine, value, new Result<int>()).Set(_ => Assert.Fail()); result.Return(receive.Value); }
private Yield Call_Set(CoroutineHandler<int, Result<int>> coroutine, int value, Result<int> result) { int? receive = null; var res = Coroutine.Invoke(coroutine, value, new Result<int>()); yield return res.Set(v => receive = v); result.Return(receive.Value); }
private Yield Call_CatchAndLog(CoroutineHandler<int, Result<int>> coroutine, int value, Result<int> result) { Result<int> inner; yield return (inner = Coroutine.Invoke(coroutine, value, new Result<int>())).CatchAndLog(_log); result.Return(inner); }
private static Yield Call(CoroutineHandler<int, Result<int>> coroutine, int p, Result<int> result) { Result<int> inner; yield return inner = Coroutine.Invoke(coroutine, p, new Result<int>()); result.Return(inner); }
public void RegisterCopyIntercept(CopyInterceptDelegate intercept) { _copyIntercept = delegate(BulkCopy copier, ExportItem exportItem, Result<ExportItem> result) { return intercept(copier, exportItem, result); }; }
//--- Constructors --- public UpdateRecordDispatcher(CoroutineHandler<UpdateRecord, Result> callback) { _callback = callback; _dispatchQueue = new ProcessingQueue<UpdateRecord>(DispatchQueued, 10); }
/// <summary> /// Creates a new stage instance. /// </summary> /// <param name="service">Service instance to which the stage belongs to.</param> /// <param name="method">Method definintion for stage handler.</param> /// <param name="access">Stage access level.</param> public DreamFeatureStage(IDreamService service, MethodInfo method, DreamAccess access) { if(service == null) { throw new ArgumentNullException("service"); } if(method == null) { throw new ArgumentNullException("method"); } this.Name = service.GetType().FullName + "!" + method.Name; this.Access = access; _method = method; _service = service; // determine what kind of method we were given var parameters = method.GetParameters(); if((method.ReturnType == typeof(Yield)) && (parameters.Length == 3) && (parameters[0].ParameterType == typeof(DreamContext)) && (parameters[1].ParameterType == typeof(DreamMessage)) && (parameters[2].ParameterType == typeof(Result<DreamMessage>))) { // classical coroutine feature handler _handler = (CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>)Delegate.CreateDelegate(typeof(CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>), service, method); } else { // TODO (arnec): Eventually DreamMessage should have a DreamMessage<T> with custom serializers allowing arbitrary return types // validate method return type if(method.ReturnType != typeof(Yield) && method.ReturnType != typeof(DreamMessage) && method.ReturnType != typeof(XDoc)) { throw new InvalidCastException(string.Format("feature handler '{0}' has return type {1}, but should be either DreamMessage or IEnumerator<IYield>", method.Name, method.ReturnType)); } // create an execution plan for fetching the necessary parameters to invoke the method _plan = new List<DreamFeatureAdapter>(); foreach(var param in method.GetParameters()) { var attributes = param.GetCustomAttributes(false); QueryAttribute queryParam = (QueryAttribute)attributes.FirstOrDefault(i => i is QueryAttribute); PathAttribute pathParam = (PathAttribute)attributes.FirstOrDefault(i => i is PathAttribute); HeaderAttribute header = (HeaderAttribute)attributes.FirstOrDefault(i => i is HeaderAttribute); CookieAttribute cookie = (CookieAttribute)attributes.FirstOrDefault(i => i is CookieAttribute); // check attribute-based parameters if(queryParam != null) { // check if a single or a list of query parameters are requested if(param.ParameterType == typeof(string)) { _plan.Add(MakeContextParamGetter(queryParam.Name ?? param.Name)); } else if(param.ParameterType == typeof(string[])) { _plan.Add(MakeContextParamListGetter(queryParam.Name ?? param.Name)); } else { _plan.Add(MakeConvertingContextParamGetter(queryParam.Name ?? param.Name, param.ParameterType)); } } else if(pathParam != null) { if(param.ParameterType == typeof(string)) { _plan.Add(MakeContextParamGetter(pathParam.Name ?? param.Name)); } else { _plan.Add(MakeConvertingContextParamGetter(pathParam.Name ?? param.Name, param.ParameterType)); } } else if(cookie != null) { Assert(method, param, typeof(string), typeof(DreamCookie)); // check which cookie type is requested if(param.ParameterType == typeof(string)) { _plan.Add(MakeRequestCookieValueGetter(cookie.Name ?? param.Name)); } else if(param.ParameterType == typeof(DreamCookie)) { _plan.Add(MakeRequestCookieGetter(cookie.Name ?? param.Name)); } else { throw new ShouldNeverHappenException(); } } else if(header != null) { Assert(method, param, typeof(string)); _plan.Add(MakeRequestHeaderGetter(header.Name ?? param.Name)); } else { // check name-based parameters if(param.Name.EqualsInvariant("verb")) { Assert(method, param, typeof(string)); _plan.Add(new DreamFeatureAdapter(param.Name, GetContextVerb)); } else if(param.Name.EqualsInvariant("path")) { Assert(method, param, typeof(string[]), typeof(string)); if(param.ParameterType == typeof(string)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpath)); } else { _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpathSegments)); } } else if(param.Name.EqualsInvariant("uri")) { Assert(method, param, typeof(XUri)); _plan.Add(new DreamFeatureAdapter(param.Name, GetContextUri)); } else if(param.Name.EqualsInvariant("body")) { Assert(method, param, typeof(XDoc), typeof(string), typeof(Stream), typeof(byte[])); // check which body type is requested if(param.ParameterType == typeof(XDoc)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsDocument)); } else if(param.ParameterType == typeof(string)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsText)); } else if(param.ParameterType == typeof(Stream)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsStream)); } else if(param.ParameterType == typeof(byte[])) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsBytes)); } else { throw new ShouldNeverHappenException(); } } else { // check type-based parameters if(param.ParameterType == typeof(DreamContext)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetContext)); } else if(param.ParameterType == typeof(DreamMessage)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequest)); } else if(param.ParameterType == typeof(Result<DreamMessage>)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetMessageResponse)); } else if(param.ParameterType == typeof(Result<XDoc>)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetDocumentResponse)); } else if(param.ParameterType == typeof(DreamCookie)) { _plan.Add(MakeRequestCookieGetter(param.Name)); } else if(param.ParameterType == typeof(string)) { _plan.Add(MakeContextParamGetter(param.Name)); } else if(param.ParameterType == typeof(string[])) { _plan.Add(MakeContextParamListGetter(param.Name)); } else { _plan.Add(MakeConvertingContextParamGetter(param.Name, param.ParameterType)); } } } } } }
/// <summary> /// Creates a new stage instance. /// </summary> /// <param name="service">Service instance to which the stage belongs to.</param> /// <param name="method">Method definintion for stage handler.</param> /// <param name="access">Stage access level.</param> public DreamFeatureStage(IDreamService service, MethodInfo method, DreamAccess access) { if(service == null) { throw new ArgumentNullException("service"); } if(method == null) { throw new ArgumentNullException("method"); } this.Name = service.GetType().FullName + "!" + method.Name; this.Access = access; _method = method; _service = service; // determine what kind of method we were given var parameters = method.GetParameters(); if((method.ReturnType == typeof(Yield)) && (parameters.Length == 3) && (parameters[0].ParameterType == typeof(DreamContext)) && (parameters[1].ParameterType == typeof(DreamMessage)) && (parameters[2].ParameterType == typeof(Result<DreamMessage>))) { // classical coroutine feature handler _handler = (CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>)Delegate.CreateDelegate(typeof(CoroutineHandler<DreamContext, DreamMessage, Result<DreamMessage>>), service, method); } else { // validate method return type if(method.ReturnType != typeof(Yield) && method.ReturnType != typeof(DreamMessage) && method.ReturnType != typeof(XDoc)) { throw new InvalidCastException(string.Format("feature handler '{0}' has return type {1}, but should be either DreamMessage or IEnumerator<IYield>", method.Name, method.ReturnType)); } // create an execution plan for fetching the necessary parameters to invoke the method _plan = new List<DreamFeatureAdapter>(); foreach(var param in parameters) { // check name-based parameters if(param.Name.EqualsInvariant("verb")) { Assert(method, param, typeof(string)); _plan.Add(new DreamFeatureAdapter(param.Name, GetContextVerb)); } else if(param.Name.EqualsInvariant("path")) { Assert(method, param, typeof(string[]), typeof(string)); if(param.ParameterType == typeof(string)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpath)); } else { _plan.Add(new DreamFeatureAdapter(param.Name, GetContextFeatureSubpathSegments)); } } else if(param.Name.EqualsInvariant("uri")) { Assert(method, param, typeof(XUri)); _plan.Add(new DreamFeatureAdapter(param.Name, GetContextUri)); } else if(param.Name.EqualsInvariant("body")) { Assert(method, param, typeof(XDoc), typeof(string), typeof(Stream), typeof(byte[])); // check which body type is requested if(param.ParameterType == typeof(XDoc)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsDocument)); } else if(param.ParameterType == typeof(string)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsText)); } else if(param.ParameterType == typeof(Stream)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsStream)); } else if(param.ParameterType == typeof(byte[])) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequestAsBytes)); } else { throw new ShouldNeverHappenException(); } } else { // check type-based parameters if(param.ParameterType == typeof(DreamContext)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetContext)); } else if(param.ParameterType == typeof(DreamMessage)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetRequest)); } else if(param.ParameterType == typeof(Result<DreamMessage>)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetMessageResponse)); } else if(param.ParameterType == typeof(Result<XDoc>)) { _plan.Add(new DreamFeatureAdapter(param.Name, GetDocumentResponse)); } else if(param.ParameterType == typeof(DreamCookie)) { _plan.Add(MakeRequestCookieGetter(param.Name)); } else if(param.ParameterType == typeof(string)) { _plan.Add(MakeContextParamGetter(param.Name)); } else if(param.ParameterType == typeof(string[])) { _plan.Add(MakeContextParamListGetter(param.Name)); } else { _plan.Add(MakeConvertingContextParamGetter(param.Name, param.ParameterType)); } } } } }