Пример #1
0
    /// <summary>
    /// Send a message to the engine
    /// </summary>
    /// <param name="message"></param>
    public void sendMessage(TMsgHeader message)
    {
        TNativeMsgHeader msgPtr = new TNativeMsgHeader();
        uint             nBytes = message.nDataBytes;

        try
        {
            msgPtr.version    = message.version;
            msgPtr.msgType    = message.msgType;
            msgPtr.from       = message.from;
            msgPtr.to         = message.to;
            msgPtr.msgID      = message.msgID;
            msgPtr.toAck      = message.toAck;
            msgPtr.nDataBytes = nBytes;

            if (nBytes == 0)
            {
                msgPtr.dataPtr = IntPtr.Zero;
            }
            else
            {
                msgPtr.dataPtr = Marshal.AllocHGlobal((int)nBytes);
                Marshal.Copy(message.dataPtr, 0, msgPtr.dataPtr, (int)nBytes);
            }
            _callengine(ref componentID, ref msgPtr);
        }
        finally
        {
            if (nBytes > 0)
            {
                Marshal.FreeHGlobal(msgPtr.dataPtr);
            }
        }
    }
Пример #2
0
    // -----------------------------------------------------------------------
    /// <summary>
    /// Handler for all QuerySetValue messages.
    /// </summary>
    /// <param name="message"></param>
    public void onQuerySetValue(TMsgHeader message)
    {
        int    iPropertyID;
        uint   iReplyTo;
        uint   msgID;
        uint   dataSize;
        string DDML;

        interpreter.loadMessage(message);    //take ownership of this msg
        iReplyTo    = message.from;
        msgID       = message.msgID;
        iPropertyID = interpreter.getIntField(Msgs.MSG_QUERYSET_ID);           // Parse the request message
        byte[] dataPtr = new byte[1];
        dataSize = interpreter.getValueField(Msgs.MSG_QUERYSET_VALUE, ref dataPtr);
        DDML     = interpreter.getTextField(Msgs.MSG_QUERYSET_TYPE);

        //find the property by ID in the regNames list
        String propKey = IDToPropertyName(iPropertyID);

        if (propKey.Length > 0)
        {
            Reg r = regNames[propKey];
            r.data.setData(dataPtr, dataSize, 0); // change the value of the variable.
            sendReplySetValueSuccess(msgID, iReplyTo, true);
        }
        else
        {
            sendReplySetValueSuccess(msgID, iReplyTo, false);
        }
    }
Пример #3
0
    /// <summary>
    /// Handler for all QueryValue messages.
    /// </summary>
    /// <param name="message"></param>
    public void onQueryValue(TMsgHeader message)
    {
        String sDDML    = "";
        uint   iReplyTo = message.from;        //the router

        interpreter.loadMessage(message);
        //expect the wrapper to trigger a returnValue message
        int iPropertyID   = interpreter.getIntField(Msgs.MSG_QUERYVALUE_ID);
        int requestedByID = interpreter.getIntField(Msgs.MSG_QUERYVALUE_REQBY);       //source of the request

        //find the property by ID in the regNames list
        String propKey = IDToPropertyName(iPropertyID);

        if (propKey.Length > 0)
        {
            Reg    r    = regNames[propKey];
            byte[] data = new byte[r.data.sizeBytes()];
            r.data.getData(ref data);   //get the value
            sDDML = r.ddml;
            sendReplyValue(message.msgID, (uint)requestedByID, sDDML, data, data.Length);
        }
        else
        {
            string errorMsg = string.Format("onQueryValue(): Cannot find property {0}", iPropertyID);
            error(errorMsg, true);
        }
    }
Пример #4
0
    // -----------------------------------------------------------------------
    /// <summary>
    /// Handler for all Event messages.
    /// </summary>
    /// <param name="message"></param>
    // -----------------------------------------------------------------------
    public void onEvent(TMsgHeader message)
    {
        interpreter.loadMessage(message);    //take ownership of this msg
        int id = interpreter.getIntField(Msgs.MSG_EVENT_ID);

        byte[] dataPtr  = new byte[1];
        uint   dataSize = interpreter.getValueField(Msgs.MSG_EVENT_PARAMS, ref dataPtr);
        uint   publBy   = (uint)interpreter.getIntField(Msgs.MSG_EVENT_PUBLISHEDBY);
        string DDML     = interpreter.getTextField(Msgs.MSG_EVENT_TYPE);

        /*  TODO implement event handling
         * Reg* reg = (Reg*) cmpevent.ID;
         * Packable& data = *(reg->data);
         *
         * if (cmpevent.ID == tickID)
         * {
         *  unpack(messageData, tick);
         *  messageData.reset();
         *  unpack(messageData, cmpevent);
         *  haveWrittenToStdOutToday = false;
         * }
         * // unpack the data - this will unpack and then call the function.
         * data.unpack(messageData, cmpevent.ddml);
         */
    }
Пример #5
0
 //============================================================================
 /// <summary>
 /// Override the init1 so that the Apsim component can have access to the SDML script.
 /// </summary>
 /// <param name="msg"></param>
 /// <param name="SDML"></param>
 /// <param name="FQN"></param>
 //============================================================================
 protected override void doInit1(TMsgHeader msg, string SDML, string FQN)
 {
     Comp.ComponentID = msg.to;  //ensure this is set
     Comp.Name        = FQN;
     Comp.setScript(SDML);
     base.doInit1(msg, SDML, FQN);
 }
Пример #6
0
/*      bool readFromSection(XMLNode::iterator initData,
 *                         XMLNode::iterator sectionData,
 *                         const std::string& parName,
 *                         Convertable* value);
 *    void readAndDemangleScripts(std::map<std::string, std::string> &scripts, XMLNode::iterator &data);
 *    void replaceManagerMacros(std::string& contents, XMLNode ui);
 */
    /// <summary>
    /// Terminate the simulation.
    /// </summary>
    private void terminate()
    {
        //create and send the msg to the parent
        interpreter.createMessage(Msgs.MSG_TERMINATE, parentID);
        TMsgHeader newMsg = interpreter.getMsg();

        sendMessage(newMsg);
    }
Пример #7
0
    //============================================================================
    /// <summary>
    /// Send an acknowledgement message
    /// </summary>
    /// <param name="msgTo">Component ID to which complete is sent.</param>
    /// <param name="msgID">ID of the message being acknowledged.</param>
    //============================================================================
    public void sendComplete(uint msgTo, uint msgID)
    {
        interpreter.setField(Msgs.MSG_COMPLETE_ACKID, msgID);
        interpreter.createMessage(Msgs.MSG_COMPLETE, msgTo);  //send back to the sender
        TMsgHeader ackMsg = interpreter.getMsg();

        sendMessage(ackMsg);
    }
Пример #8
0
 /// <summary>
 /// Handler for Init2 message.
 /// </summary>
 /// <param name="message"></param>
 public void onInit2(TMsgHeader message)
 {
     if ((tickID = nameToRegistrationID("tick", RegistrationKind.respondToEventReg)) == 0)
     {
         // We need a tick to determine when to write the "day = ..." heading to a summary file.
         tickID = RegisterWithPM("tick", "", "", RegistrationKind.respondToEventReg, "<type/>");
     }
 }
Пример #9
0
        //==============================================================================
        /// <summary>
        /// Send a message up to the owning system so it can be routed throughout
        /// the simulation. Overridden to allow the message data to be converted
        /// to a native pointer.
        /// </summary>
        /// <param name="msg">Message that will be sent to the engine.</param>
        //==============================================================================
        protected override void sendMessageToEngine(TMsgHeader msg)
        {
            // Copy from TMsgHeader to TNativeMsgHeader.
            // The difference is in the nature of the data pointer.
            try
            {
                TNativeMsgHeader msgPtr = new TNativeMsgHeader();
                uint             nBytes = msg.nDataBytes;
                try
                {
                    msgPtr.version    = msg.version;
                    msgPtr.msgType    = msg.msgType;
                    msgPtr.from       = msg.from;
                    msgPtr.to         = msg.to;
                    msgPtr.msgID      = msg.msgID;
                    msgPtr.toAck      = msg.toAck;
                    msgPtr.nDataBytes = nBytes;

                    if (nBytes == 0)
                    {
                        msgPtr.dataPtr = IntPtr.Zero;
                    }
                    else
                    {
                        /*
                         * if (nBytes > memAllocSize)
                         * {
                         *
                         *  if (memAllocSize > 0)
                         *      Marshal.FreeHGlobal(nativeMem);
                         *  nativeMem = Marshal.AllocHGlobal((int)nBytes);
                         *  memAllocSize = nBytes;
                         * }
                         * msgPtr.dataPtr = nativeMem; */
                        msgPtr.dataPtr = Marshal.AllocHGlobal((int)nBytes);
                        Marshal.Copy(msg.dataPtr, 0, msgPtr.dataPtr, (int)nBytes);
                    }
                    IntPtr dummy = (IntPtr)0;
                    msgNativeDestFunction(ref dummy, ref msgPtr);       //will take a copy
                }
                finally
                {
                    if (nBytes > 0)
                    {
                        Marshal.FreeHGlobal(msgPtr.dataPtr);
                    }
                }
            }
            catch (SEHException)
            { // This is the most likely exception to be caught here, but normally it will
            } // be handled elsewhere on the native side, and "External component has thrown an exception" is not a very helpful message
            catch (Exception e)
            {
                StringBuilder exmsg = new StringBuilder("sendMessageToEngine() failed ");
                exmsg.Append(e.Message);
                Console.WriteLine(exmsg);
            }
        }
Пример #10
0
        //private uint memAllocSize = 0;
        //private IntPtr nativeMem;

        //==============================================================================
        /// <summary>
        /// Send a message up to the owning system so it can be routed throughout
        /// the simulation. Overridden to allow the message data to be converted
        /// to a native pointer. This enables calling from embedded Microsoft Frameworks or Mono.
        /// The message itself then needs to be converted from a TNativeMsgHeader to a TMsgHeader,
        /// which includes taking a copy of the data referenced by the data pointer
        /// </summary>
        /// <param name="inVal">Message that will be sent to the engine.
        /// The value passed in, although described as a "ulong", is actually
        /// a pointer to a native TMsgHeader
        /// </param>
        //==============================================================================
        public void handleMessage(ulong inVal)
        {
            // We need to copy the "native" message point into a managed object.
            TNativeMsgHeader src = (TNativeMsgHeader)Marshal.PtrToStructure((IntPtr)inVal, typeof(TNativeMsgHeader));

            TMsgHeader msgPtr = TMessageInterpreter.NativeMsgToManagedMsg(ref src);

            handleMessage(msgPtr);  //calls the base class function
        }
Пример #11
0
    protected void sendReplyValue(uint queryMsgID, uint replyTo, string sParamType, byte[] aParams, int paramsSize)
    {
        interpreter.setField(Msgs.MSG_REPLYVALUE_QUERYID, queryMsgID);        //ID of queryValue
        interpreter.setField(Msgs.MSG_REPLYVALUE_TYPE, sParamType);           //DDML type
        interpreter.setField(Msgs.MSG_REPLYVALUE_VALUE, aParams, (uint)paramsSize);
        TMsgHeader msg = interpreter.createMessage(Msgs.MSG_REPLYVALUE, replyTo);

        sendMessage(msg);
    }
Пример #12
0
        //==============================================================================
        /// <summary>
        /// Send a message up to the owning system so it can be routed throughout
        /// the simulation. Overridden to allow the message data to be converted
        /// to a native pointer.
        /// </summary>
        /// <param name="msg">Message that will be sent to the engine.</param>
        //==============================================================================
        protected override void sendMessageToEngine(TMsgHeader msg)
        {
            // Copy from TMsgHeader to TNativeMsgHeader.
            // The difference is in the nature of the data pointer.
            try
            {
                TNativeMsgHeader msgPtr = new TNativeMsgHeader();
                uint             nBytes = msg.nDataBytes;
                try
                {
                    msgPtr.version    = msg.version;
                    msgPtr.msgType    = msg.msgType;
                    msgPtr.from       = msg.from;
                    msgPtr.to         = msg.to;
                    msgPtr.msgID      = msg.msgID;
                    msgPtr.toAck      = msg.toAck;
                    msgPtr.nDataBytes = nBytes;

                    if (nBytes == 0)
                    {
                        msgPtr.dataPtr = IntPtr.Zero;
                    }
                    else
                    {
                        /*
                         * if (nBytes > memAllocSize)
                         * {
                         *
                         *  if (memAllocSize > 0)
                         *      Marshal.FreeHGlobal(nativeMem);
                         *  nativeMem = Marshal.AllocHGlobal((int)nBytes);
                         *  memAllocSize = nBytes;
                         * }
                         * msgPtr.dataPtr = nativeMem; */
                        msgPtr.dataPtr = Marshal.AllocHGlobal((int)nBytes);
                        Marshal.Copy(msg.dataPtr, 0, msgPtr.dataPtr, (int)nBytes);
                    }
                    uint dummy = 0;
                    msgNativeDestFunction(ref dummy, ref msgPtr);       //will take a copy
                }
                finally
                {
                    if (nBytes > 0)
                    {
                        Marshal.FreeHGlobal(msgPtr.dataPtr);
                    }
                }
            }
            catch (Exception e)
            {
                StringBuilder exmsg = new StringBuilder("sendMessageToEngine() failed ");
                exmsg.Append(e.Message);
                Console.WriteLine(exmsg);
            }
        }
Пример #13
0
    // internal stuff.
    // -----------------------------------------------------------------------
    /// <summary>
    /// Called for all incoming messages.
    /// </summary>
    /// <param name="message"></param>
    // -----------------------------------------------------------------------
    private void messageToLogic(TMsgHeader message)
    {
        // We need to keep track of bits of the message because the FARMWI$E infrastructure
        // doesn't guarantee that a message is still valid at the end of this method.
        // eg. it deletes the Init1 message before we get to test the ack flag at the bottom.
        bool ack     = message.toAck == 1;
        uint msgID   = message.msgID;
        uint msgFrom = message.from;

        interpreter.loadMessage(message);    //take ownership of this msg
        try
        {
            switch (message.msgType)
            {
            case Msgs.MSG_EVENT:        onEvent(message); break;

            case Msgs.MSG_INIT1:
            {
                String SDML = interpreter.getTextField(Msgs.MSG_INIT1_SDML);
                String FQN  = interpreter.getTextField(Msgs.MSG_INIT1_FQN);
                onInit1(SDML, FQN);             //do init1 processing
            }
            break;

            case Msgs.MSG_INIT2:        onInit2(message); break;

            case Msgs.MSG_QUERYVALUE:   onQueryValue(message); break;

            case Msgs.MSG_QUERYSET:     onQuerySetValue(message); break;

            case Msgs.MSG_RETURNVALUE:
            case Msgs.MSG_RETURNINFO:
            case Msgs.MSG_NOTIFYSET:
            case Msgs.MSG_REPLYSET:
            {
                TMsgHeader copyMsg = new TMsgHeader();
                copyMsg = message;
                messages.Add(copyMsg);
            } break;
            }
            // if acknowledgement is required, then give it.
            if (ack)
            {
                sendComplete(msgFrom, msgID);
            }
        }
        catch (Exception err)
        {
            error(err.Message, true);
        }
    }
Пример #14
0
    // -----------------------------------------------------------------------
    /// <summary>
    /// Set the value of a variable in another component.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="units"></param>
    /// <param name="data"></param>
    // -----------------------------------------------------------------------
    public void set(String name, String units, ref TDDMLValue data)
    {
        clearMessages();
        int  id = nameToRegistrationID(name, RegistrationKind.setReg);
        bool alreadyRegistered = (id != 0);

        if (!alreadyRegistered)
        {
            id = RegisterWithPM(name, units, "", RegistrationKind.setReg, data.asDDML());
        }

        TMsgHeader msg = buildRequestSetMsg(id, data);

        if (msg.msgID != 0)
        {
            sendMessage(msg);
        }
    }
Пример #15
0
    public void error(String errorMessage, bool isFatal)
    {
        String sMsg = errorMessage + "\n";

        sMsg += "Component name: " + name + "\n";
        //use the new error msg
        interpreter.setField(Msgs.MSG_ERROR_FATAL, isFatal);
        interpreter.setField(Msgs.MSG_ERROR_MESSAGE, sMsg);  //its ID
        TMsgHeader msg = interpreter.createMessage(Msgs.MSG_ERROR, parentID);

        sendMessage(msg);

        if (isFatal)
        {
            terminate(); //may not be necessary ???
            errorHasOccurred = true;
        }
    }
Пример #16
0
    //==============================================================================
    /// <summary>
    /// Build a requestSetvalue message.
    /// </summary>
    /// <param name="iLocalSetPropID">Local identifier for the property.</param>
    /// <param name="Value">Value to which to set the property.</param>
    /// <returns>The new message. If this function fails then the returned message.msgID==0</returns>
    //==============================================================================
    protected TMsgHeader buildRequestSetMsg(int iLocalSetPropID, TTypedValue Value)
    {
        uint            valSize;
        TSetterProperty localProp = null;
        TMsgHeader      newMsg    = new TMsgHeader();

        newMsg.msgID = 0;   //default to fault

        valSize = Value.sizeBytes();
        byte[] valPtr = new byte[valSize];
        Value.getData(ref valPtr);

        //destination is the owning system
        interpreter.setField(Msgs.MSG_REQUESTSET_ID, iLocalSetPropID);      //local reg property ID
        interpreter.setField(Msgs.MSG_REQUESTSET_TYPE, localProp.sDDML);
        interpreter.setField(Msgs.MSG_REQUESTSET_VALUE, valPtr, valSize);
        newMsg = interpreter.createMessage(Msgs.MSG_REQUESTSET, parentID);
        return(newMsg);
    }
Пример #17
0
    // -----------------------------------------------------------------------
    /// <summary>
    /// Get the value of a variable from another component.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="units"></param>
    /// <param name="optional"></param>
    /// <param name="data"></param>
    /// <returns></returns>
    // -----------------------------------------------------------------------
    public Boolean get(String name, String units, Boolean optional, ref TDDMLValue data)
    {
        clearMessages();

        // see if we have an array specifier.   //// TODO: fix the ability to use array specifiers
        ////   ArraySpecifier* arraySpecifier = ArraySpecifier::create(name);
        String nameWithoutArraySpec = name;
        ////   if (arraySpecifier != NULL)
        ////      nameWithoutArraySpec = arraySpecifier->variableName();

        int     id = nameToRegistrationID(nameWithoutArraySpec, RegistrationKind.getReg);
        Boolean alreadyRegistered = (id != 0);

        if (!alreadyRegistered)
        {
            id = RegisterWithPM(nameWithoutArraySpec, units, "", RegistrationKind.getReg, data.asDDML());
        }

        interpreter.setField(Msgs.MSG_GETVALUE_ID, id);      //the driver ID code
        TMsgHeader msg = interpreter.createMessage(Msgs.MSG_GETVALUE, parentID);

        msg.toAck = 1;  //always
        sendMessage(msg);

        String errorMsg = "";

        if (messages.Count == 0)
        {
            errorMsg = "No component responded to a 'get' for variable: " + name;
        }

        else if (messages.Count == 1)
        {
            interpreter.loadMessage(messages[0]);    //take ownership of this msg
            int    iCompID     = interpreter.getIntField(Msgs.MSG_RETURNVALUE_COMPID);
            int    iPropertyID = interpreter.getIntField(Msgs.MSG_RETURNVALUE_ID);
            string DDML        = interpreter.getTextField(Msgs.MSG_RETURNVALUE_TYPE);
            byte[] dataPtr     = new byte[1];
            uint   dataSize    = interpreter.getValueField(Msgs.MSG_RETURNVALUE_VALUE, ref dataPtr);

            data.setData(dataPtr, dataSize, 0);

            ////if (arraySpecifier != NULL)
            ////arraySpecifier->summariseData(returnMessageData, returnValue.ddml);
        }
        else if (messages.Count > 1)
        {
            errorMsg = "Too many components responded to a 'get' for variable: " + name;
        }

        if (errorMsg != "")
        {
            if (!optional)
            {
                throw (new ApplicationException(errorMsg));
            }
            return(false);
        }
        else
        {
            return(true);
        }
    }