Events: How can performance and stability of event implementation be testedEvents: How can performance and stability of event implementation be testedEvent "SetAttributeValue" - Special ConsiderationWilfrid Utzhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=186032013-04-09T07:29:13Z2013-04-09T06:48:42ZSpecific considerations are necessary when implementing an AdoScript that is triggered by the "SetAttributeValue" event. The event is triggered by any kind of update/modification on attribute values (by the user or platform) when modifying the model and instances. This is especially of interest in the case of move events, where the event is triggered for any kind of position update and also redraw functions (creation/build up of model).<br /><br />To implement an AdoScript for the event make sure that you:<br />- know exactly the cases the AdoScript is implemented for (validation against the attribute ID and its type) to prevent unncessary processing<br />- make sure that user interaction scripting is targeted to the specific cases (in case of a script during move of objects and relations, the event is continously triggered and the scope is lost)<br />- for performance considerations, make sure that the script loading is done in effective way, reading and executing AdoScripts on the event potentally results in an unstable and/or time-consuming implementation of your method. It is recommended to pre-load script using the PROCEDURE mechanism and just trigger the respective procedure for each case.<br />- run type checking (attributeID first and then all other checks) in the ON_EVENT definition, this makes sure that scripts that are not necessary are not loaded just for the checking purpose<br /><br />The event definition can be found below.<br />Event name: <strong>"SetAttributeValue"</strong><br /><strong>Parameters:</strong><br /><em>instid : integer</em> (ID of the changed instance)<br /><em>attrid : integer</em> (Attribute ID)<br /><em>modelid : integer</em> (ID of the model containing the changed instance.<br /><em>attrtypeid : integer</em> (Attribute type code)<br />0 INTEGER<br />1 DOUBLE<br />2 STRING<br />3 DISTRIBUTION<br />4 TIME<br />5 ENUMERATION<br />6 ENUMERATIONLIST<br />7 CORE_LONGSTRING<br />8 PROGRAMCALL<br />9 INTERREF<br />10 EXPRESSION<br />11 RECORD<br />12 ATTRPROFREF<br />13 DATE<br />14 DATETIME<br />15 CLOB<br /><em>oldval : string</em> (The original value (as string))<br />This is the Core internal value (not UI value).<br />For attributes of type RECORD this is always an empty string.<br />The new value can be determined via the "Core" MessagePort.<br /><strong>Exit value</strong><br /><em>N/A</em><br /><br /><strong>EXAMPLE Implementation:</strong><br /><br /><div class="code"><span class="code-lines"> 1</span>ON_EVENT "SetAttributeValue" {<br /><span class="code-lines"> 2</span> EVENT_LOG msgType:"EVENT_LOG" message: ("SetAttributeValue with parameters instid : " + STR instid + " attrid : " + STR attrid + " modelid : " + STR modelid + " attrtypeid : " + STR attrtypeid + " oldval : " + oldval)<br /><span class="code-lines"> 3</span> # CASE A: Validate against AttrID and ClassID - first validation against AttrID, the right-hand part is preloaded in "AppInitialized"<br /><span class="code-lines"> 4</span> IF (attrid = nPreLoadedAttrIDACase) {<br /><span class="code-lines"> 5</span> # ClassID is not part of the event, in case of this attribute ID, get it and only run for specific classes<br /><span class="code-lines"> 6</span> CC "Core" GET_CLASS_ID objid: (instid)<br /><span class="code-lines"> 7</span> SET nClassID: (classid)<br /><span class="code-lines"> 8</span> # Validation against PreloadedClassID, done "AppInitialized" event<br /><span class="code-lines"> 9</span> IF (nClassID = nPreloadedClassIDACase) {<br /><span class="code-lines">10</span> # perform action for Case A<br /><span class="code-lines">11</span> ...<br /><span class="code-lines">12</span> }<br /><span class="code-lines">13</span> }<br /><span class="code-lines">14</span> # CASE B: Validate against AttrID only<br /><span class="code-lines">15</span> IF (attrid = nPreloadedAttrIDBCase){<br /><span class="code-lines">16</span> # perform action for Case B<br /><span class="code-lines">17</span> ...<br /><span class="code-lines">18</span> }<br /><span class="code-lines">19</span>}<br /></div>Wilfrid Utz2013-04-09T06:48:42ZEvent LoggingWilfrid Utzhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=185972013-04-09T05:52:05Z2013-04-09T05:33:04ZAs a means for event logging the CREATE_OUTPUT_WIN command of the AdoScript message port can be used to a) open a new dockable window and b) continously log the event streams that are captured. This visualisation could potentially highlight performance issues in the event implementation.<br /><br />In the following the steps are explained to set up event logging, including code snipplets for the setup and the actual listening.<br /><br />1. Add the event log window and procedure to the "AppInitialized" event in the Library attribute "External coupling"<br /><div class="code"><span class="code-lines"> 1</span>#All configuration and implementations that need to be triggered during startup<br /><span class="code-lines"> 2</span>ON_EVENT "AppInitialized" {<br /><span class="code-lines"> 3</span> # create the dockable window for the output stream<br /><span class="code-lines"> 4</span> CC "AdoScript" CREATE_OUTPUT_WIN winid:"EVENTLOG" title:"Event Logging"<br /><span class="code-lines"> 5</span> <br /><span class="code-lines"> 6</span> # establish a global procedure as a helper implementation for timestamped logging<br /><span class="code-lines"> 7</span> PROCEDURE global EVENT_LOG msgType:string message:string {<br /><span class="code-lines"> 8</span> CC "Application" GET_DATE_TIME date-format:"dd/mm/yyyy" time-format:"hh:mm:ss"<br /><span class="code-lines"> 9</span> SET currentDateTime: ((date) + " " + (time))<br /><span class="code-lines">10</span> CC "AdoScript" OUT winid:"EVENTLOG" text: ("[" + (msgType) + "@" + currentDateTime + "]: " + (message) + "\n")<br /><span class="code-lines">11</span> }<br /><span class="code-lines">12</span> # Initial event log message for the "AppInitialized" event<br /><span class="code-lines">13</span> EVENT_LOG msgType:"EVENT_LOG" message: ("AppInitialized")<br /><span class="code-lines">14</span> # Perform other things for the event<br /><span class="code-lines">15</span>}<br /></div><br /><br />2. Add event logger messages to the events. This should be done before anything else is performed for the event, to limit the dependency on other implementations<br /><div class="code"><span class="code-lines"> 1</span>ON_EVENT "BeforeCreateRelationInstance" {<br /><span class="code-lines"> 2</span> # Log event plus all parameters set for the event<br /><span class="code-lines"> 3</span> EVENT_LOG msgType:"EVENT_LOG message: ("BeforeCreateRelationInstance with parameters frominstid : " + STR frominstid + " toinstid : " + STR toinstid + " relationclassid : " + STR relationclassid + " componentid " + STR componentid)<br /><span class="code-lines"> 4</span> # Perform other things for the event<br /><span class="code-lines"> 5</span>}<br /><span class="code-lines"> 6</span><br /><span class="code-lines"> 7</span>ON_EVENT "SetAttributeValue" {<br /><span class="code-lines"> 8</span> # Log event plus all parameters set for the event<br /><span class="code-lines"> 9</span> EVENT_LOG msgType:"EVENT_LOG" message: ("SetAttributeValue with parameters instid : " + STR instid + " attrid : " + STR attrid + " modelid : " + STR modelid + " attrtypeid : " + STR attrtypeid + " oldval : " + oldval)<br /><span class="code-lines">10</span> # Perform other things for the event<br /><span class="code-lines">11</span>}<br /></div><br /><br />This can be done for each event available in ADOxx. Details on the events available and their parameters are available in the online help. Please use "SetAttributeValue" carefully, since it is trigger in any kind of interaction that results in an update of an attribute on instance and model level (moving of objects, drawing, etc.). The attached screenshot shows the result of the above.Wilfrid Utz2013-04-09T05:33:04ZRE: Events: How can performance and stability of event implementation be teWilfrid Utzhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=185892013-04-08T12:24:31Z2013-04-08T12:21:39ZFor testing of performance and scalability, a automated testscript as the one below can be used to go through the view modes, analyse the classes available in each and create a predefined number of objects in the model currently open. For the test runs, the number of for instances per class and view have been defined in the header, additional code to be performed after each instance creation can be added accordingly. The script helps when test-driving the up-scale of the implementation to potentially analyze clitches in performance when it comes to event implementation.<br /><br /><em>Highlights:</em><br />- Configuration of model size<br />- Validation of "core" events and performance<br />- Additional custom code can be added<br />- Log file is written to a dockable window in the modelling tool, and provided at the end as an EDITBOX to save and further analyse<br /><em><br />Limitations:</em><br />- Relation classes are currently not considered and need to be tested separetly<br /><br />To run the code, integrate it in a menu item or run directly from the AdoScript Debug Shell:<br />EXECUTE file: ("PATH_TO_LOCAL_FILE\\NumberOfObjects.asc")<br /><br /><div class="code"><span class="code-lines"> 1</span># create a debug window to display result messages<br /><span class="code-lines"> 2</span>SETG sDebugWINID: ("debug")<br /><span class="code-lines"> 3</span>SETG nNumberOfObjects: (40)<br /><span class="code-lines"> 4</span>SETG lSkipClasses: ("Organisation")<br /><span class="code-lines"> 5</span>SETG xPos: (2)<br /><span class="code-lines"> 6</span>SETG yPos: (2)<br /><span class="code-lines"> 7</span>SETG nCounter: (1)<br /><span class="code-lines"> 8</span>SETG logMessages: ("")<br /><span class="code-lines"> 9</span>DEBUG_PRINTER debugmessage: ("START OF LOGGING for " + STR nNumberOfObjects + " each model contruct per view") <br /><span class="code-lines">10</span>CC "AdoScript" CREATE_OUTPUT_WIN winid: (sDebugWINID) title:"Performance Debug"<br /><span class="code-lines">11</span>DEBUG_PRINTER debugmessage: ("###############################################") <br /><span class="code-lines">12</span>DEBUG_PRINTER debugmessage: ("New performance test started") <br /><span class="code-lines">13</span># make sure that a model is loaded before starting<br /><span class="code-lines">14</span>CC "Modeling" GET_ACT_MODEL<br /><span class="code-lines">15</span>DEBUG_PRINTER debugmessage: ("modelid: " + STR modelid) <br /><span class="code-lines">16</span>IF (modelid = -1) {<br /><span class="code-lines">17</span> DEBUG_PRINTER debugmessage: ("No test model open .... EXITING")<br /><span class="code-lines">18</span> EXIT<br /><span class="code-lines">19</span>}<br /><span class="code-lines">20</span>SET nTestModelID: (modelid)<br /><span class="code-lines">21</span> # get model info<br /><span class="code-lines">22</span>CC "Core" GET_MODEL_INFO modelid: (nTestModelID)<br /><span class="code-lines">23</span>DEBUG_PRINTER debugmessage: ("modeltype: " + modeltype) <br /><span class="code-lines">24</span>SETL sTestModelType: (modeltype)<br /><span class="code-lines">25</span># get all view modes<br /><span class="code-lines">26</span>CC "Core" GET_ALL_MODES_OF_MODELTYPE modeltype: (sTestModelType) sep:"|"<br /><span class="code-lines">27</span>DEBUG_PRINTER debugmessage: ("available_view_modes: " + modenames) <br /><span class="code-lines">28</span>SETL lViewModes: (modenames)<br /><span class="code-lines">29</span># interate through modes<br /><span class="code-lines">30</span>FOR sModeName in: (lViewModes) sep:"|" {<br /><span class="code-lines">31</span> CC "Modeling" SET_VIEW_MODE mode-name: (sModeName)<br /><span class="code-lines">32</span> CC "Core" GET_ALL_CLASSES_OF_MODE modeltype: (sTestModelType) modename: (sModeName)<br /><span class="code-lines">33</span> DEBUG_PRINTER debugmessage: ("available_classes: " + classids) <br /><span class="code-lines">34</span> SETG lClassIDs: (classids)<br /><span class="code-lines">35</span> # iterate through all classids<br /><span class="code-lines">36</span> FOR sClassID in: (lClassIDs) {<br /><span class="code-lines">37</span> # get the class name and check whether a relation<br /><span class="code-lines">38</span> CC "Core" GET_CLASS_NAME classid: (VAL sClassID)<br /><span class="code-lines">39</span> # if relation, skip<br /><span class="code-lines">40</span> IF (isrel != 1) {<br /><span class="code-lines">41</span> FOR varName from:1 to: (nNumberOfObjects) {<br /><span class="code-lines">42</span> SETL sNewObjName: (classname + "-" +STR nCounter)<br /><span class="code-lines">43</span> CC "Core" CREATE_OBJ modelid: (nTestModelID) classid: (VAL sClassID) objname: (sNewObjName)<br /><span class="code-lines">44</span> DEBUG_PRINTER debugmessage: ("create object: " + sNewObjName) <br /><span class="code-lines">45</span> CC "Modeling" SET_OBJ_POS objid: (objid) x: (CM xPos) y: (CM yPos)<br /><span class="code-lines">46</span> DEBUG_PRINTER debugmessage: ("position object: " + sNewObjName) <br /><span class="code-lines">47</span> ################# SECURE TROPOS SPECIFIC CODE TO IMMIDATE THE EVENT CODE - START #################<br /><span class="code-lines">48</span> CC "Core" SET_ATTR_VAL objid: (objid) attrname: ("_View") val: (sModeName)<br /><span class="code-lines">49</span> DEBUG_PRINTER debugmessage: ("SECURETROPOS_SPECIFIC - set view mode in object: " + sNewObjName) <br /><span class="code-lines">50</span> ################# SECURE TROPOS SPECIFIC CODE TO IMMIDATE THE EVENT CODE - END #################<br /><span class="code-lines">51</span> SETG xPos: (xPos + 2)<br /><span class="code-lines">52</span> SETG nCounter: (nCounter + 1)<br /><span class="code-lines">53</span> }<br /><span class="code-lines">54</span> }<br /><span class="code-lines">55</span> SETG xPos: (2)<br /><span class="code-lines">56</span> SETG yPos: (yPos + 2)<br /><span class="code-lines">57</span> }<br /><span class="code-lines">58</span> SETG yPos: (2)<br /><span class="code-lines">59</span> DEBUG_PRINTER debugmessage: (".... SWITCHING VIEW MODE ....") <br /><span class="code-lines">60</span><br /><span class="code-lines">61</span>}<br /><span class="code-lines">62</span>CC "AdoScript" EDITBOX text: (logMessages) title:"Logged information" oktext:"Close" fileeditor<br /><span class="code-lines">63</span><br /><span class="code-lines">64</span>DEBUG_PRINTER debugmessage: ("###############################################") <br /><span class="code-lines">65</span><br /><span class="code-lines">66</span><br /><span class="code-lines">67</span><br /><span class="code-lines">68</span>#*************************************************************************************#<br /><span class="code-lines">69</span># #<br /><span class="code-lines">70</span> PROCEDURE DEBUG_PRINTER debugmessage:string<br /><span class="code-lines">71</span> #<br /><span class="code-lines">72</span>#*************************************************************************************#<br /><span class="code-lines">73</span><br /><span class="code-lines">74</span>{<br /><span class="code-lines">75</span> CC "Application" GET_DATE_TIME date-format:"DD.MM.YYYY" time-format:"HH:MM:SS"<br /><span class="code-lines">76</span> CC "AdoScript" OUT winid: (sDebugWINID) text: (time + ": " + debugmessage + "\n")<br /><span class="code-lines">77</span> SETG logMessages: (logMessages + time + ": " + debugmessage + "\n")<br /><span class="code-lines">78</span>}<br /><span class="code-lines">79</span>#*************************************************************************************#<br /></div>Wilfrid Utz2013-04-08T12:21:39ZEvents: How can performance and stability of event implementation be testedhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=185832014-03-27T12:30:31Z2013-04-08T12:02:49ZHow is it possibile to validate the scalability of event implementations in ADOxx? In the test-case at hand, a model with 100 objects in different view modes is established, the view switch takes time to be performed. The event used is "AfterUpdateGrObjects".2013-04-08T12:02:49Z