82 %(var_access_code)s |
82 %(var_access_code)s |
83 |
83 |
84 static int write_iterator(uint32_t index, hmi_tree_item_t *dsc) |
84 static int write_iterator(uint32_t index, hmi_tree_item_t *dsc) |
85 { |
85 { |
86 uint32_t session_index = 0; |
86 uint32_t session_index = 0; |
87 if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) while(session_index < MAX_CONNECTIONS) |
87 int value_changed = 0; |
88 { |
88 if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) { |
89 if(dsc->wstate[session_index] == buf_set){ |
|
90 /* if being subscribed */ |
|
91 if(dsc->refresh_period_ms[session_index]){ |
|
92 if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){ |
|
93 dsc->age_ms[session_index] += ticktime_ms; |
|
94 }else{ |
|
95 dsc->wstate[session_index] = buf_tosend; |
|
96 global_write_dirty = 1; |
|
97 } |
|
98 } |
|
99 } |
|
100 |
|
101 void *dest_p = &wbuf[dsc->buf_index]; |
89 void *dest_p = &wbuf[dsc->buf_index]; |
102 void *real_value_p = NULL; |
90 void *real_value_p = NULL; |
103 char flags = 0; |
91 char flags = 0; |
104 void *visible_value_p = UnpackVar(dsc, &real_value_p, &flags); |
92 void *visible_value_p = UnpackVar(dsc, &real_value_p, &flags); |
105 |
|
106 /* if new value differs from previous one */ |
|
107 USINT sz = __get_type_enum_size(dsc->type); |
93 USINT sz = __get_type_enum_size(dsc->type); |
108 if(__Is_a_string(dsc)){ |
94 if(__Is_a_string(dsc)){ |
109 sz = ((STRING*)visible_value_p)->len + 1; |
95 sz = ((STRING*)visible_value_p)->len + 1; |
110 } |
96 } |
111 if(dsc->wstate[session_index] == buf_new /* just subscribed |
97 while(session_index < MAX_CONNECTIONS) { |
112 or already subscribed having value change */ |
98 if(dsc->wstate[session_index] == buf_set){ |
113 || (dsc->refresh_period_ms[session_index] > 0 && memcmp(dest_p, visible_value_p, sz) != 0)){ |
99 /* if being subscribed */ |
114 /* copy and flag as set */ |
100 if(dsc->refresh_period_ms[session_index]){ |
|
101 if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){ |
|
102 dsc->age_ms[session_index] += ticktime_ms; |
|
103 }else{ |
|
104 dsc->wstate[session_index] = buf_tosend; |
|
105 global_write_dirty = 1; |
|
106 } |
|
107 } |
|
108 } |
|
109 |
|
110 if(dsc->wstate[session_index] == buf_new /* just subscribed |
|
111 or already subscribed having value change */ |
|
112 || (dsc->refresh_period_ms[session_index] > 0 |
|
113 && (value_changed || (value_changed=memcmp(dest_p, visible_value_p, sz))) != 0)){ |
|
114 /* if not already marked/signaled, do it */ |
|
115 if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) { |
|
116 if(dsc->wstate[session_index] == buf_new || ticktime_ms > dsc->refresh_period_ms[session_index]){ |
|
117 dsc->wstate[session_index] = buf_tosend; |
|
118 global_write_dirty = 1; |
|
119 } else { |
|
120 dsc->wstate[session_index] = buf_set; |
|
121 } |
|
122 dsc->age_ms[session_index] = 0; |
|
123 } |
|
124 } |
|
125 |
|
126 session_index++; |
|
127 } |
|
128 /* copy value if changed (and subscribed) */ |
|
129 if(value_changed) |
115 memcpy(dest_p, visible_value_p, sz); |
130 memcpy(dest_p, visible_value_p, sz); |
116 /* if not already marked/signaled, do it */ |
|
117 if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) { |
|
118 if(dsc->wstate[session_index] == buf_new || ticktime_ms > dsc->refresh_period_ms[session_index]){ |
|
119 dsc->wstate[session_index] = buf_tosend; |
|
120 global_write_dirty = 1; |
|
121 } else { |
|
122 dsc->wstate[session_index] = buf_set; |
|
123 } |
|
124 dsc->age_ms[session_index] = 0; |
|
125 } |
|
126 } |
|
127 |
|
128 AtomicCompareExchange(&dsc->wlock, 1, 0); |
131 AtomicCompareExchange(&dsc->wlock, 1, 0); |
129 session_index++; |
|
130 } |
132 } |
131 // else ... : PLC can't wait, variable will be updated next turn |
133 // else ... : PLC can't wait, variable will be updated next turn |
132 return 0; |
134 return 0; |
133 } |
135 } |
134 |
136 |