c – 在当前结束后启动用户定义的function

我正在创建的游戏在开始之前显示一个菜单,用户可以select开始游戏,或者做一些事情。 当用户select一个选项时,我需要调用另一个实际执行选项的函数(启动游戏,configuration等),问题是因为我从菜单函数调用了该函数,所有的variables菜单留在内存中。 所以我想完成菜单function,并从内存中删除所有的内容,然后启动与select的选项对应的function,如果用户返回菜单,则再次加载所有内容,完成后卸载。 问题是我没有办法(我知道)告诉菜单function完成后调用哪个函数。

我虽然关于启动与另一个线程中select的选项相对应的function,而菜单function完成(可能会出错…),如下所示:

int menu() { Load_menu_stuff_to_memory(); int quit = 1; while(quit) { if(option_a_selected) { //the new function will be started in a new thread while the menu one finishes quit = 0; start_option_a_in_new_thread(); }else if(option_b_selected) { //the new function will be started in a new thread while the menu one finishes quit = 0; start_option_b_in_new_thread(); } } Deallocate_menu_stuff(); } 

但是,我不确定新菜单是否会在菜单function结束时结束,或者被保留在空闲状态等等。

另外我不确定菜单function何时结束,程序会到达main menu (不要与menu混淆)

所以:我的方法会工作吗?

如果不:

我怎么可以调用一个随机函数,但只有在调用者函数完成后?

首先,直接问题的答案是线程在main()线程结束时是否继续运行,可以在这个Stack Overflow答案中find:

https://stackoverflow.com/a/4667273/377922

当主线程(即运行main()函数的线程)终止时,进程终止,所有其他线程停止。

所以,只要你继续运行主游戏循环,其他线程将继续运行,直到它们结束。 这可能需要对你的循环进行一些重构,因为你正在跳出来并退出整个游戏。

但是,我强烈劝阻你这样做,因为使用multithreading没有真正的理由会增加复杂性的一个额外的维度。 在相同的数据上debugging多个线程最多可能会非常棘手,并且可能会通过尝试避免写入数据而导致性能问题。

我会建议使用状态机来控制你的状态转换。 我不熟悉C,所以我会给你一些(面向对象的)伪代码:

 while (quit == false) { currentState->update(); // Returns an enum of the state type. enum StateType newState = currentState->getNewState(); if (currentState != newState) { currentState->cleanUp(); // Creates the appropriate state from the given enum value. currentState = createStateObject(newState); currentState->initialise(); } currentState->render(); } 

getNewState()您应该根据update()函数中的用户input返回一个枚举值,您想要转换为的状态。 我建议使用枚举值而不是原始函数指针来保持文件和include语句有点整齐。

在你的特定的例子中, initialise()Load_menu_stuff_to_memory()的内容, update()将包含if...else子句, cleanUp()将包含Deallocate_menu_stuff()的内容。 当然在C语言中,每个状态都有一组普通的函数,例如main_menu_update()main_menu_render()

最后一件事是可以使currentState成为一堆状态,每个状态都有渲染和input标志,以便将来可以叠加堆栈,暂停菜单或以“演示模式”运行游戏,主菜单位于顶部。

您可以使用“事件/任务缓冲区/队列”来产生这种行为。

tl; dr:想到一个主循环和一个任务数组; 第一个任务是初始化菜单,这又将允许用户激活初始化游戏的任务。 当一个任务结束时,你返回到这个主循环,这样任务所使用的所有资源就可以被安全地销毁并从内存中释放出来。 新的任务在菜单被销毁之前由菜单排队,然后在返回到主循环时启动。 如果您将来需要同时运行菜单和游戏,您也可以使用线程。

在main()分配“事件缓冲区/任务队列”并且触发启动事件init_menu ,然后进入主循环“将检查是否有挂起或当前活动的事件,如果没有,则结束循环和因为有一个init_menu事件,循环调用init_menu_func ,菜单启动,现在你正在自己的线程或主线程中运行菜单;当有人select一个选项时,菜单添加正确的事件/任务到这个缓冲区,在这种情况下是init_game 。菜单任务将自己从活动事件缓冲区中删除,退出循环并终止,释放所有的资源。

主循环现在处于活动状态,它会像往常一样检查是否有未决事件,然后激活init_game事件并开始游戏。

 #include stdio.h //Author: Coty Embry /* Program Comment: first and foremost im assuming you know how to code in c (to an extent): I would say to go at it like a showmenu that is a subprogram (think boolean value) which will show the menu, do what you need, then release the memory. Once it accomplishes what you need it to then send back the info you need then release the memory <2 Timothy 2:15> */ //I know im going a little different direction than you did in your example by using a switch statement, but anyways lets get to it: int menu(int); //this declares that there is going to be a menu int main(void) { select = showmenu(); switch(select) { //here the program switches to select (which is what the menu function will return) - hopefully you follow what i mean case 1: //if menu returns an int that == 1 //TODO (ie write your code!! lol) - case 2: //TODO //so on and so forth } //this is the subprogram int showmenu(void) { //here is where the magic happens (im answering you question - hopefully) /* so to resolve you're issue I think the best thing to do here is to declare a variable then assign what you need to, free the memory, THEN return what you need */ int whatyouneed; //sorry, but the variable name felt appropriate lol //TODO //printf("enter what you need and press enter\n"); scanf("%d", & whatyouneed); //check to make sure syntax is correct //now free your memory or whatever you need to do Deallocate_Menu_stuff(); //honestly not sure if you even need to free your memory - this function shouldn't //take much memory...but to make the program better i guess it could help in the overall scheme. im not sure to be honest, just speculating return whatyouneed; //returns the data you wanted and exits the menu subprogram //doing this basically makes it where the only "memory" that is used is the memory used to store that one variable }