2011年11月2日 星期三

神奇的選單

如何寫一個容易維護的選單程式,當初只會寫了一堆if then else, 或者是switch case……


維護的好辛苦,今天寫了一個神奇的選單程式,維護上就簡單多了


VBITS_16 Menu_Flag_All,
         Menu_Flag_0,
         Menu_Flag_1,
         Menu_Flag_2,
         Menu_Flag_3,
         Menu_Flag_4;



void Null_Menu(void)
{
   ;
}


void Task_Menu_0(void)
{
    Menu_Flag_0.word = 0x0002;
    Menu_Service(&Menu_Flag_0, Menu_Table_0);
}


void Task_Menu_1(void)
{
    Menu_Flag_1.word = 0x0002;
    Menu_Service(&Menu_Flag_1, Menu_Table_1);
}


void Task_Menu_2(void)
{
    Menu_Flag_2.word = 0x0002;
    Menu_Service(&Menu_Flag_2, Menu_Table_2);
}


void Task_Menu_3(void)
{
    Menu_Flag_3.word = 0x0001;
    Menu_Service(&Menu_Flag_3, Menu_Table_3);
}


void Task_Menu_4(void)
{
    Menu_Flag_4.word = 0x0001;
    Menu_Service(&Menu_Flag_4, Menu_Table_4);
}


void test(void)
{
   ;
}


const FUNCT_PTR_V_V Menu_Table_0[16] =
{
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
};


const FUNCT_PTR_V_V Menu_Table_1[16] =
{
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
};
const FUNCT_PTR_V_V Menu_Table_2[16] =
{
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
};
const FUNCT_PTR_V_V Menu_Table_3[16] =
{
    test, //test
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
};
const FUNCT_PTR_V_V Menu_Table_4[16] =
{
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
};


const FUNCT_PTR_V_V Menu_Table_All[16] =
{
    Task_Menu_0,
    Task_Menu_1,
    Task_Menu_2,
    Task_Menu_3,
    Task_Menu_4,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
    Null_Menu,
};


 


void Menu_Service(VBITS_16 *service_flags, const FUNCT_PTR_V_V *service_table)
{


    WORD flags;
    int index = 0;
    if ( 0 == service_flags->word) return;
    flags = service_flags->word;
    while((flags & 1) == 0)
    {
       flags >>= 1;
       index++;
    }


    service_flags->word &= ~(1<<index);  /* Clear service request. */


    (*service_table[index])();              /* Dispatch to service handler. */


}


 


使用上也不複雜


  Menu_Flag_All.word = 0x0008;
  Menu_Service(&Menu_Flag_All, Menu_Table_All);


一樣也是call 副程式來使用,應該還可以寫得更好才對。


 


今天就先這樣吧!


沒有留言:

張貼留言