LCOV - code coverage report
Current view: top level - src/detail - ppg_event_buffer_detail.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 103 120 85.8 %
Date: 2018-01-08 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /* Copyright 2017 noseglasses <shinynoseglasses@gmail.com>
       2             :  *
       3             :  * This program is free software: you can redistribute it and/or modify
       4             :  * it under the terms of the GNU Lesser General Public License as published by
       5             :  * the Free Software Foundation, either version 3 of the License, or
       6             :  * (at your option) any later version.
       7             :  *
       8             :  * This program is distributed in the hope that it will be useful,
       9             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      10             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      11             :  * GNU Lesser General Public License for more details.
      12             :  *
      13             :  * You should have received a copy of the GNU Lesser General Public License
      14             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      15             :  */
      16             : 
      17             : #include "detail/ppg_event_buffer_detail.h"
      18             : #include "detail/ppg_context_detail.h"
      19             : #include "detail/ppg_global_detail.h"
      20             : #include "detail/ppg_malloc_detail.h"
      21             : #include "ppg_debug.h"
      22             : #include "ppg_settings.h"
      23             : 
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <assert.h>
      27             : 
      28             : #define PPG_EB ppg_context->event_buffer
      29             : 
      30        2904 : PPG_Count ppg_event_buffer_size(void)
      31             : {
      32        2904 :    return PPG_EB.size;
      33             : }
      34             : 
      35          50 : void ppg_event_buffer_resize(PPG_Event_Buffer *event_buffer,
      36             :                              PPG_Count new_size)
      37             : {
      38          50 :    PPG_ASSERT(event_buffer);
      39             :    
      40          50 :    if(new_size <= event_buffer->max_size) { return; }
      41             :    
      42          50 :    PPG_Event_Queue_Entry *new_events
      43          50 :       = (PPG_Event_Queue_Entry*)PPG_MALLOC(sizeof(PPG_Event_Queue_Entry)*new_size);
      44             :       
      45          50 :    event_buffer->max_size = new_size;
      46             :    
      47          50 :    if(event_buffer->events && (event_buffer->size > 0)) {
      48           0 :       memcpy(new_events, event_buffer->events, 
      49           0 :              sizeof(PPG_Event_Queue_Entry)*event_buffer->size);
      50             :    }
      51             :    
      52          50 :    event_buffer->events = new_events;
      53             : }
      54             : 
      55             : // Reurns an in place version of the event
      56             : //
      57         780 : PPG_Event * ppg_event_buffer_store_event(PPG_Event *event)
      58             : {
      59             :    #if PPG_HAVE_ASSERTIONS
      60         780 :    if(PPG_EB.start > PPG_EB.end) {
      61           0 :       PPG_Count n_events = PPG_MAX_EVENTS + PPG_EB.end - PPG_EB.start;
      62           0 :       PPG_ASSERT(n_events < PPG_MAX_EVENTS - 1); // At least one left!
      63             :    }
      64             :    else {
      65         780 :       PPG_Count n_events = PPG_EB.end - PPG_EB.start;
      66         780 :       PPG_ASSERT(n_events < PPG_MAX_EVENTS - 1); // At least one left!
      67             :    }
      68             :    #endif
      69             :    
      70         780 :    PPG_Event_Buffer_Index_Type new_pos = PPG_EB.end;
      71             :    
      72         780 :    if(PPG_EB.end == PPG_MAX_EVENTS - 1) {
      73           0 :       PPG_EB.end = 0;
      74             :    }
      75             :    else {
      76         780 :       ++PPG_EB.end;
      77             :    }
      78             :    
      79        1560 :    PPG_EB.events[new_pos] = (PPG_Event_Queue_Entry) {
      80         780 :       .event = *event,
      81             :       .consumer = NULL,
      82             :       .token_state = (PPG_Token_State) {
      83             :          .state = 0,
      84             :          .changed = false
      85             :       }
      86             :    };
      87             :    
      88         780 :    ++PPG_EB.size;
      89             :    
      90         780 :    PPG_LOG("Storing event at %u\n", PPG_EB.end);
      91         780 :    PPG_LOG("   start: %u, cur: %u, end: %u, size: %u\n", 
      92             :               PPG_EB.start, PPG_EB.cur, PPG_EB.end, PPG_EB.size);
      93             :    
      94         780 :    return &PPG_EB.events[new_pos].event;
      95             : }
      96             : 
      97         321 : void ppg_event_buffer_reset(PPG_Event_Buffer *eb)
      98             : {
      99         321 :    eb->start = 0;
     100         321 :    eb->end = 0;
     101         321 :    eb->cur = 0;
     102             :    
     103         321 :    eb->size = 0;
     104             :    
     105         321 :    PPG_LOG("Event queue reset\n");
     106         321 :    PPG_LOG("   start: %u, cur: %u, end: %u, size: %u\n", 
     107             :               eb->start, eb->cur, eb->end, eb->size);
     108         321 : }
     109             : 
     110          41 : void ppg_event_buffer_init(PPG_Event_Buffer *eb)
     111             : {
     112          41 :    ppg_event_buffer_reset(eb);
     113             :    
     114          41 :    eb->max_size = 0;
     115          41 :    eb->events = NULL;
     116             :    
     117          41 :    ppg_event_buffer_resize(eb, PPG_MAX_EVENTS);
     118          41 : }
     119             : 
     120             : 
     121           9 : void ppg_event_buffer_restore(PPG_Event_Buffer *eb)
     122             : {
     123           9 :    PPG_Count safed_size = eb->max_size;
     124             :    
     125           9 :    eb->events = NULL; 
     126           9 :    eb->max_size = 0; // This forces resize 
     127             :    
     128           9 :    ppg_event_buffer_resize(eb, safed_size);
     129           9 : }
     130             : 
     131          41 : void ppg_event_buffer_free(PPG_Event_Buffer *event_buffer)
     132             : {
     133          41 :    if(!event_buffer->events) { return; }
     134             :    
     135          41 :    free(event_buffer->events);
     136             :    
     137          41 :    event_buffer->events = NULL;
     138             : }
     139             : 
     140        1452 : bool ppg_event_buffer_events_left(void)
     141             : {
     142             : //    PPG_LOG("ppg_event_buffer_events_left: %u, cur: %u, end: %u, size: %u\n", 
     143             : //               PPG_EB.start, PPG_EB.cur, PPG_EB.end, PPG_EB.size);
     144        1452 :    return   (PPG_EB.cur != PPG_EB.end);
     145             : }
     146             : 
     147         713 : void ppg_event_buffer_advance(void)
     148             : {
     149         713 :    if(PPG_EB.size == 0) { return; }
     150             :    
     151         713 :    if(PPG_EB.cur == PPG_MAX_EVENTS - 1) {
     152           0 :       PPG_EB.cur = 0;
     153             :    }
     154             :    else {
     155         713 :       ++PPG_EB.cur;
     156             :    }
     157             :    
     158             :    #if PPG_HAVE_ASSERTIONS
     159         713 :    ppg_check_event_buffer_validity();
     160             :    #endif
     161             :    
     162         713 :    PPG_LOG("Event queue advanced\n");
     163         713 :    PPG_LOG("   start: %u, cur: %u, end: %u, size: %u\n", 
     164             :               PPG_EB.start, PPG_EB.cur, PPG_EB.end, PPG_EB.size);
     165             : } 
     166             : 
     167             : #if PPG_HAVE_ASSERTIONS
     168         811 : void ppg_check_event_buffer_validity(void)
     169             : {
     170         811 :    if(PPG_EB.end > PPG_EB.start) {
     171         811 :       PPG_ASSERT(PPG_EB.cur >= PPG_EB.start);
     172         811 :       PPG_ASSERT(PPG_EB.cur <= PPG_EB.end);
     173             :    }
     174           0 :    else if(PPG_EB.end == PPG_EB.start) {
     175           0 :       PPG_ASSERT(PPG_EB.size == 0);
     176           0 :       PPG_ASSERT(PPG_EB.end == PPG_EB.cur);
     177             :    }
     178             :    else {
     179           0 :       PPG_ASSERT( !(    (PPG_EB.cur > PPG_EB.end)
     180             :                      && (PPG_EB.cur < PPG_EB.start)));
     181             :    }
     182         811 : }
     183             : #endif
     184             : 
     185          97 : static void ppg_even_buffer_recompute_size(void)
     186             : {
     187          97 :    if(PPG_EB.end > PPG_EB.start) {
     188             :       
     189           0 :       PPG_EB.size = PPG_EB.end - PPG_EB.start;
     190             :    }
     191          97 :    else if(PPG_EB.end == PPG_EB.start) {
     192          97 :       PPG_EB.size = 0;
     193             :    }
     194             :    else {
     195             :       
     196           0 :       PPG_EB.size = PPG_MAX_EVENTS + PPG_EB.end - PPG_EB.start;
     197             :    }
     198          97 : }
     199             : 
     200         437 : static void ppg_flush_non_considered_events(PPG_Event_Queue_Entry *eqe, 
     201             :                                             void *user_data)
     202             : {
     203             :    PPG_UNUSED(user_data);
     204             :    
     205         437 :    if(!(eqe->event.flags & PPG_Event_Considered)) {
     206             : 
     207             :       // Events that were not considered and are 
     208             :       // not control tags such as those used for 
     209             :       // abort input events are flushed
     210             :       //
     211          16 :       ppg_context->event_processor(&eqe->event, NULL);
     212             :    }
     213         437 : }
     214             : 
     215         102 : void ppg_event_buffer_truncate_at_front(void)
     216             : {
     217         102 :    if(PPG_EB.cur == PPG_EB.end) {
     218           5 :       ppg_event_buffer_reset(&PPG_EB);
     219             :    }
     220             :    else {
     221             :       
     222          97 :       ppg_event_buffer_advance();
     223             :       
     224             :       // Any events that were not
     225             :       // considered by the last match, e.g. intermixed deactivations 
     226             :       // of currently unrelated inputs are flushed.
     227             :       
     228             :       // Temporarily reset the end of the event buffer to
     229             :       // simplify flushing
     230             :       //
     231          97 :       PPG_Count old_end = PPG_EB.end;
     232          97 :       PPG_EB.end = PPG_EB.cur;
     233             :       
     234          97 :       ppg_event_buffer_iterate2(
     235             :          (PPG_Event_Processor_Visitor)ppg_flush_non_considered_events, 
     236             :          NULL);
     237             :       
     238          97 :       PPG_EB.end = old_end; // Revert the original end
     239             :       
     240          97 :       PPG_EB.start = PPG_EB.cur; // Truncate the front of the queue
     241             :       
     242          97 :       ppg_even_buffer_recompute_size();
     243             :       
     244             :    }
     245             : //    PPG_LOG("Event queue truncated at front\n"); 
     246             : //    PPG_LOG("   start: %u, cur: %u, end: %u, size: %u\n", 
     247             : //               PPG_EB.start, PPG_EB.cur, PPG_EB.end, PPG_EB.size);
     248             :    
     249         102 : }
     250             : 
     251             : // This method does not erase events but just changes
     252             : // the input position
     253             : //
     254          28 : void ppg_event_buffer_remove_first_event(void)
     255             : {
     256          28 :    if(PPG_EB.size == 0) { return; }
     257             :    
     258          28 :    if(PPG_EB.start < PPG_MAX_EVENTS - 1) {
     259          28 :       ++PPG_EB.start;
     260             :    }
     261             :    else {
     262           0 :       PPG_EB.start = 0;
     263             :    }
     264             :    
     265          28 :    --PPG_EB.size;
     266             :    
     267             : //    PPG_LOG("Event queue removed first event\n");
     268             : //    PPG_LOG("   start: %u, cur: %u, end: %u, size: %u\n", 
     269             : //               PPG_EB.start, PPG_EB.cur, PPG_EB.end, PPG_EB.size);
     270             :    
     271             : }
     272             : 
     273          42 : void ppg_even_buffer_flush_and_remove_first_event(bool on_success)
     274             : {
     275             :    PPG_UNUSED(on_success);
     276             :    
     277             : //    PPG_LOG("Flushing and removing first event\n");
     278             :    
     279          42 :    ppg_context->event_processor(&PPG_EB.events[PPG_EB.start].event, NULL);
     280             :    
     281          42 :    if(PPG_EB.size > 1) {
     282          28 :       ppg_event_buffer_remove_first_event();
     283             :    }
     284             :    else {
     285          14 :       ppg_event_buffer_reset(&PPG_EB);
     286             :    }
     287          42 : }
     288             : 
     289         102 : void ppg_event_buffer_on_match_success(void)
     290             : {
     291         102 :    PPG_LOG("Prp. evt bffr on suc.\n");
     292             :             
     293         102 :    ppg_active_tokens_update();
     294             :    
     295             :    // Even though the pattern matches, it is possible that not
     296             :    // all events were considered as there might have been a
     297             :    // a tree furcation traverse involved. This might leave events
     298             :    // after the current event that might be part of
     299             :    // a future match.
     300             :    //
     301             :    // Thus, we remove all events up to the current one and leave the
     302             :    // rest.
     303             :    //
     304         102 :    ppg_event_buffer_truncate_at_front();
     305         102 : }
     306             : 
     307         673 : void ppg_event_buffer_iterate2(
     308             :                         PPG_Event_Processor_Visitor visitor,
     309             :                         void *user_data)
     310             : {
     311         673 :    if(ppg_event_buffer_size() == 0) { return; }
     312             :    
     313         438 :    if(PPG_EB.size == 0) { return; }
     314             :    
     315         438 :    if(PPG_EB.start > PPG_EB.end) {
     316             :       
     317           0 :       for(PPG_Count i = PPG_EB.start; i < PPG_MAX_EVENTS; ++i) {
     318             :       
     319           0 :          visitor(&PPG_EB.events[i], user_data);
     320             :       }
     321           0 :       for(PPG_Count i = 0; i < PPG_EB.end; ++i) {
     322             :          
     323           0 :          visitor(&PPG_EB.events[i], user_data);
     324             :       }
     325             :    }
     326             :    else {
     327        1629 :       for(PPG_Count i = PPG_EB.start; i < PPG_EB.end; ++i) {
     328             :       
     329        1191 :          visitor(&PPG_EB.events[i], user_data);
     330             :       }
     331             :    }
     332             : }

Generated by: LCOV version 1.10