예제 #1
0
        public static void SendTimeTick(object timeObj)
        {
            /* 2. Send the tick */
            //  timer += updateIncrement;
            int time = (int)timeObj;
            int timer = time / 1000;
            int secs = timer % 60;
            int mins = (timer / 60) % 60;
            int hours = timer / 3600;
            const string name_Space = TimerTicker.name_Space;
            DateTime currTime = new DateTime(1, 1, 1, hours, mins, secs);
            string simulationTime = String.Format("{0:HH:mm:ss}", currTime);
            EventCommunicator.SendEvent(new TickEventType(time, simulationTime));
            //   current = DateTime.Now;
            //   TimeSpan ts = current - last;
            //   Console.WriteLine("timeslice: {0:+hh.mm.ss.ffffzz}", ts.ToString());
            //last = current;

            /* 3. Pull the events for this tick off the queue and handle them */
            List<ScenarioEventType> events = TimerQueueClass.RetrieveEvents(timer);
            if (events != null)
            {
                for (int v = 0; v < events.Count; v++)
                {
                    Coordinator.debugLogger.Writeline("Timer", "Time: " + time.ToString()
                        + "  ID: " + events[v].UnitID.ToString() +
                        " Event: " + events[v].GetType().ToString(), "test");
                    // track current state
                    if (UnitFacts.AnyDead(events[v].AllUnits))
                    {// skip an event that refers to a dead unit
                        continue;
                    }
                    string thisUnit = events[v].UnitID;
                    string thisTarget = "";
                    // Only a few outgoing events require two substitutions
                    switch (events[v].GetType().ToString())
                    {
                        case name_Space + "AttackObjectEvent":
                            thisTarget = ((AttackObjectEvent)events[v]).TargetObjectID;
                            break;

                        case name_Space + "LaunchEventType":
                            thisTarget = ((LaunchEventType)events[v]).Child;
                            break;
                        case name_Space + "WeaponLaunchEventType":
                            thisTarget = ((WeaponLaunchEventType)events[v]).Child;
                            break;
                        case name_Space + "SubplatformLaunchType":
                            thisTarget = ((SubplatformLaunchType)events[v]).ParentUnit;
                            break;
                        case name_Space + "SubplatformDockType":
                            thisTarget = ((SubplatformDockType)events[v]).ParentUnit;
                            break;
                        default:
                            break;

                    }

                    if (!events[v].EngramValid(thisUnit, thisTarget))
                    {
                        Coordinator.debugLogger.Writeline("Timer", "Time: Command" + events[v].GetType().ToString() + " ignored due to value of " + events[v].Range.Name, "test");
                    }
                    else
                    {
                        switch (events[v].GetType().ToString())
                        {
                            /* SInce the active region update requires both activity and visibility,
                             * must find current values of non-updated field just before sending event
                             */
                            case name_Space + "ActiveRegionActivityUpdateType":
                                ActiveRegionStateType currentStateForVisibility = (ActiveRegionStateType)(NameLists.activeRegionNames.ContainedData[((ActiveRegionActivityUpdateType)(events[v])).UnitID]);
                                currentStateForVisibility.IsActive = ((ActiveRegionActivityUpdateType)(events[v])).IsActive;
                                NameLists.activeRegionNames.ContainedData[((ActiveRegionActivityUpdateType)(events[v])).UnitID] = currentStateForVisibility;
                                ActiveRegionUpdateType activityUpdate = new ActiveRegionUpdateType(((ActiveRegionActivityUpdateType)(events[v])).UnitID, ((ActiveRegionActivityUpdateType)(events[v])).Time, currentStateForVisibility);
                                EventCommunicator.SendEvent(activityUpdate);
                                break;

                            case name_Space + "ActiveRegionVisibilityUpdateType":
                                ActiveRegionStateType currentStateForActivity = (ActiveRegionStateType)(NameLists.activeRegionNames.ContainedData[((ActiveRegionVisibilityUpdateType)(events[v])).UnitID]);
                                currentStateForActivity.IsVisible = ((ActiveRegionVisibilityUpdateType)(events[v])).IsVisible;
                                NameLists.activeRegionNames.ContainedData[((ActiveRegionVisibilityUpdateType)(events[v])).UnitID] = currentStateForActivity;
                                ActiveRegionUpdateType visibilityUpdate = new ActiveRegionUpdateType(((ActiveRegionVisibilityUpdateType)(events[v])).UnitID, ((ActiveRegionVisibilityUpdateType)(events[v])).Time, currentStateForActivity);
                                EventCommunicator.SendEvent(visibilityUpdate);
                                break;

                            case name_Space + "CloseChatRoomType":
                                if (ChatRooms.DropChatRoom(((CloseChatRoomType)(events[v])).Room))
                                    EventCommunicator.SendEvent(events[v]);
                                break;
                            case name_Space + "CloseVoiceChannelType":
                                if (VoiceChannels.DropVoiceChannel(((CloseVoiceChannelType)(events[v])).Channel))
                                    EventCommunicator.SendEvent(events[v]);
                                break;
                            case name_Space + "Reveal_EventType":
                                UnitFacts.CurrentUnitStates[events[v].UnitID] = ((Reveal_EventType)events[v]).InitialState;
                                EventCommunicator.SendEvent(events[v]);
                                break;
                            case name_Space + "StateChangeEvent":
                                string currentState = UnitFacts.CurrentUnitStates[events[v].UnitID];
                                if (("Dead" != currentState)
                                    && (!((StateChangeEvent)events[v]).IsException(currentState)))
                                {
                                    if ((((StateChangeEvent)events[v]).HasPrecursors())
                                        && (((StateChangeEvent)events[v]).IsPrecursor(currentState)))
                                    {
                                        EventCommunicator.SendEvent(events[v]);
                                    }
                                    else if (!((StateChangeEvent)events[v]).HasPrecursors())
                                    {
                                        EventCommunicator.SendEvent(events[v]);
                                    }
                                }
                                break;
                            case name_Space + "TransferEvent":
                                    if (UnitFacts.ChangeDM(events[v].UnitID,
                                        /*   ((TransferEvent)events[v]).From, */((TransferEvent)events[v]).To))
                                    {
                                        EventCommunicator.SendEvent(events[v]);
                                    }// and if not? Throw exception??
                                    else
                                    {
                                        Coordinator.debugLogger.LogError("Timed Queue Manager", "Transfer of Unit " + events[v].UnitID +
                                            " from " + ((TransferEvent)events[v]).From + " failed.");

                                    }
                                    break;
                                case name_Space + "SubplatformLaunchType":
                                    SubplatformLaunchType alias = ((SubplatformLaunchType)events[v]);
                                    List<string> nowDocked = SubplatformRecords.GetDocked(alias.ParentUnit);
                                    if (nowDocked.Contains(alias.UnitID))
                                    {
                                        SubplatformRecords.UnDock(alias.ParentUnit, alias.UnitID);
                                        EventCommunicator.SendEvent(events[v]);
                                    }
                                    break;
                                case name_Space + "SubplatformDockType":
                                    SubplatformDockType dock = ((SubplatformDockType)events[v]);
                                    string adopterID = dock.ParentUnit;
                               
                                    if (SubplatformRecords.CountDockedOfSpecies(adopterID, UnitFacts.GetSpecies(dock.UnitID)) <= SpeciesType.GetSpecies(UnitFacts.GetSpecies(adopterID)).GetSubplatformCapacity(UnitFacts.GetSpecies(dock.UnitID)))
                                    {
                                        if (SubplatformRecords.RecordDocking(thisTarget, dock.UnitID) == true)
                                        {
                                            EventCommunicator.SendEvent(events[v]);
                                        }
                                        else
                                        {
                                            string someError = "This failed because the subplatform wasn't able to be docked to this platform";
                                        }
                                    }
                                    break;
                            //SubplatformLaunchType is a response to a launch request,
                            //LaunchEventType was intended to be from the scenario. This needs to be rethought.                                   
                                case name_Space + "LaunchEventType":
                                    // Note -- it isn't an error if the thing isn't docked any more

                                    LaunchEventType launch = (LaunchEventType)events[v];
                                    // This comes from scenario so we only check if there is something to launch
                                    if ("" != launch.Child)
                                    {

                                        List<string> dockedNow = SubplatformRecords.GetDocked(launch.UnitID);
                                        if (dockedNow.Contains(launch.Child))
                                        {
                                            SubplatformRecords.UnDock(launch.UnitID, launch.Child);

                                            ///???        Subplatforms.GetDocked(launch.UnitID);
                                            // not in sim model      launch.Genus = Genealogy.GetGenus(launch.Child);
                                            SubplatformRecords.UnDock(launch.UnitID, launch.Child);
                                            EventCommunicator.SendEvent(launch);

                                        }
                                    }

                                    break;
                                case name_Space + "WeaponLaunchEventType":
                                    // Note -- it isn't an error if the thing isn't docked any more

                                    WeaponLaunchEventType launchWeapon = (WeaponLaunchEventType)events[v];
                                    // This comes from scenario so we only check if there is something to launch
                                    if ("" != launchWeapon.Child)
                                    {

                                        List<string> dockedNow = SubplatformRecords.GetDocked(launchWeapon.UnitID);
                                        if (dockedNow.Contains(launchWeapon.Child))
                                        {
                                            SubplatformRecords.UnDock(launchWeapon.UnitID, launchWeapon.Child);
                                            SubplatformRecords.UnDock(launchWeapon.UnitID, launchWeapon.Child);
                                            EventCommunicator.SendEvent(launchWeapon);

                                        }
                                    }

                                    break;
                            case name_Space + "EngramSettingType":
                                //This is the inital value so it was set in the table at parset time
                                EventCommunicator.SendEvent(events[v]);
                                break;

                            case name_Space + "ChangeEngramType":
                                ChangeEngramType newValue = ((ChangeEngramType)events[v]);
                                Engrams.Set(newValue.Name, newValue.UnitID, newValue.EngramValue);
                                EventCommunicator.SendEvent(new EngramSettingType(newValue.Name, newValue.UnitID, newValue.EngramValue, Engrams.GetType(newValue.Name)));
                                break;
                            case name_Space + "RemoveEngramEvent":
                                Engrams.Remove(((RemoveEngramEvent)events[v]).Name);
                                break;
                            case name_Space + "OpenChatRoomType":
                                //Requests from below are handled by EventCommunicator
                                //This processing is for commands in script -- ??
                                string chatFailureMessage = "";
                                OpenChatRoomType ocr = ((OpenChatRoomType)events[v]);
                                if (("EXP" != ocr.Owner) && !UnitFacts.IsDM(ocr.Owner))
                                    chatFailureMessage = "The name '" + ocr.Owner + "' is not a valid decision maker.";
                                else
                                {
                                    for (int i = 0; i < ocr.Members.Count; i++)
                                    {
                                        DecisionMakerType DMi = DecisionMakerType.GetDM(ocr.Members[i]);
                                        for (int mbr = 1 + i; mbr < ocr.Members.Count; mbr++)
                                        {
                                            if (!DMi.CanChatWith(ocr.Members[mbr]))
                                            {
                                                chatFailureMessage = "Decison Makers '" + DMi.Identifier + "' cannot be in a chat room with '" + ocr.Members[mbr] + "'";
                                                break;
                                            }
                                            if ("" != chatFailureMessage)
                                                break;
                                        }

                                    }

                                }
                                if ("" == chatFailureMessage)
                                {
                                    chatFailureMessage = ChatRooms.AddRoom(ocr);
                                    EventCommunicator.SendEvent(ocr);
                                }
                                if ("" != chatFailureMessage)
                                {
                                    // DON'T throw new ApplicationException("Could not create chatroom '"+ocr.Range+"': "+chatFailureMessage);
                                    // send a system message instead
                                }
                                break;
                            case name_Space + "SendChatMessageType":
                                // Script induced. Only need to check if there is such a room
                                if (ChatRooms.IsRoom(((SendChatMessageType)(events[v])).RoomName))
                                    EventCommunicator.SendEvent(events[v]);
                                break;
                            case name_Space + "OpenWhiteboardRoomType":
                                //Requests from below are handled by EventCommunicator
                                //This processing is for commands in script -- ??
                                string whiteboardFailureMessage = "";
                                OpenWhiteboardRoomType owr = ((OpenWhiteboardRoomType)events[v]);
                                if (("EXP" != owr.Owner) && !UnitFacts.IsDM(owr.Owner))
                                    whiteboardFailureMessage = "The name '" + owr.Owner + "' is not a valid decision maker.";
                                else
                                {
                                    for (int i = 0; i < owr.Members.Count; i++)
                                    {
                                        DecisionMakerType DMi = DecisionMakerType.GetDM(owr.Members[i]);
                                        for (int mbr = 1 + i; mbr < owr.Members.Count; mbr++)
                                        {
                                            if (!DMi.CanWhiteboardWith(owr.Members[mbr]))
                                            {
                                                whiteboardFailureMessage = "Decison Makers '" + DMi.Identifier + "' cannot be in a whiteboard room with '" + owr.Members[mbr] + "'";
                                                break;
                                            }
                                            if ("" != whiteboardFailureMessage)
                                                break;
                                        }

                                    }

                                }
                                if ("" == whiteboardFailureMessage)
                                    whiteboardFailureMessage = WhiteboardRooms.AddRoom(owr);
                                if ("" != whiteboardFailureMessage)
                                {
                                    // DON'T throw new ApplicationException("Could not create whiteboardroom '"+owr.Range+"': "+whiteboardFailureMessage);
                                    // send a system message instead
                                }
                                break;
                            case name_Space + "OpenVoiceChannelType":
                                //Requests from below would be/are handled by EventCommunicator
                                //This processing is for commands in script -- ??
                                string voiceFailureMessage = "";
                                OpenVoiceChannelType ovct = ((OpenVoiceChannelType)events[v]);
                                //if (("EXP" != ovct.Owner) && !UnitFacts.IsDM(ovct.Owner))
                                //{
                                //    voiceFailureMessage = "Open Voice Channel: The name '" + ovct.Owner + "' is not a valid decision maker.";
                                //    ErrorLog.Write(voiceFailureMessage);
                                //}
                                //else    
                                //{
                                voiceFailureMessage = VoiceChannels.AddChannel(ovct);
                                if ("" != voiceFailureMessage)
                                    ErrorLog.Write(voiceFailureMessage);
                                else
                                {
                                    //ovct.InitialMembers = DecisionMakerType.GetVoiceChannelMembers(ovct.Channel); //TODO: AD: Is this even NECESSARY?
                                    EventCommunicator.SendEvent(ovct);
                                }
                                //}
                                break;

                            case name_Space + "FlushEvents":
                                //first drop all timer events involving this unit
                                TimerQueueClass.FlushOneUnit(((FlushEvents)events[v]).UnitID);
                                // Then all events on happenin queue about this unit
                                for (int h = 0; h < HappeningList.Happenings.Count; h++)
                                {// Find first happening event that keys off this state change
                                    HappeningCompletionType incident = HappeningList.Happenings[h];
                                    if (incident.UnitID == ((FlushEvents)events[v]).UnitID)
                                    {
                                        HappeningList.Happenings.RemoveAt(h);
                                    }
                                    else //  examine all the DoThisLists
                                    {
                                        List<int> removals = new List<int>();
                                        for (int d = 0; d < incident.DoThisList.Count; d++)
                                        {
                                            if (incident.DoThisList[d].Involves(((FlushEvents)events[v]).UnitID))
                                            {
                                                removals.Add(d);
                                            }
                                            //then remove from back to front to preserve indices
                                            for (int r = removals.Count - 1; r >= 0; r--)
                                            {
                                                incident.DoThisList.RemoveAt(r);
                                            }
                                        }

                                    }


                                }
                                break;
                            case name_Space + "ForkReplayEventType":
                                EventCommunicator.SendEvent(events[v]);
                                break;
                            default:
                                EventCommunicator.SendEvent(events[v]);
                                break;
                        }

                    }
                }
                TimerQueueClass.DropNode(time);

            }


        }
예제 #2
0
 /// <summary>
 /// This method takes in an ActiveREgionUpdateType (ScenCon defined object), and retrieves
 /// the data from the object, packages up the data into a SimulationEvent (SimCore defined
 /// object), and then sends the event to the network server.  This method was pulled out of
 /// the main block of code to simplify sending the event and code readability.
 /// </summary>
 /// <param name="incoming">The Move_EventType object whose data is packaged
 /// into an outgoing SimulationEvent.</param>
 private static void SendActiveRegionUpdateEvent(ActiveRegionUpdateType incoming)
 {
     SimulationEvent e = SimulationEventFactory.BuildEvent(ref simModelInfo, "ActiveRegionUpdate");
     try
     {
         e["Time"] = DataValueFactory.BuildInteger(incoming.Time);
         e["ObjectID"] = DataValueFactory.BuildString(incoming.UnitID);
         e["IsVisible"] = DataValueFactory.BuildBoolean(incoming.IsVisible);
         e["IsActive"] = DataValueFactory.BuildBoolean(incoming.IsActive);
     }
     catch (SystemException f)
     {
         throw new ApplicationException("Missing Required Data for Active Region Update:", f);
     }
     server.PutEvent(e);
 }