├── .gitignore ├── Makefile ├── README.md ├── example ├── Makefile ├── book │ ├── Makefile │ ├── ai │ │ ├── Makefile │ │ └── main.cpp │ ├── count │ │ ├── Makefile │ │ └── main.cpp │ ├── count_client │ │ ├── Makefile │ │ ├── main.cpp │ │ └── php │ │ │ └── test.php │ ├── log │ │ ├── Makefile │ │ └── src │ │ │ └── main.cpp │ ├── lua │ │ ├── Makefile │ │ ├── src │ │ │ └── main.cpp │ │ └── test.lua │ ├── rpc │ │ ├── Makefile │ │ └── main.cpp │ ├── sqlite │ │ ├── Makefile │ │ └── main.cpp │ ├── task_queue │ │ ├── Makefile │ │ └── src │ │ │ └── main.cpp │ └── xml │ │ ├── Makefile │ │ ├── main.cpp │ │ └── test.xml ├── broker │ ├── Makefile │ └── src │ │ └── main.cpp ├── codefmt.md ├── cqrs │ ├── Makefile │ ├── command │ │ └── task_command.h │ ├── cqrs │ │ ├── aggregate_root_i.h │ │ ├── bus_i.h │ │ ├── command_handler_i.h │ │ ├── command_i.h │ │ ├── event_i.h │ │ └── type_i.h │ ├── main.cpp │ ├── task │ │ ├── event_def.h │ │ ├── task_service.cpp │ │ ├── task_service.h │ │ ├── test_task.h │ │ ├── user_task.cpp │ │ └── user_task.h │ └── user │ │ ├── user.h │ │ └── user_mgr.h ├── echo_client │ ├── Makefile │ ├── include │ │ └── msg_def.h │ └── src │ │ └── main.cpp ├── echo_server │ ├── Makefile │ ├── include │ │ └── msg_def.h │ └── src │ │ └── main.cpp ├── event_store │ ├── Makefile │ ├── include │ │ ├── entity.h │ │ ├── event.h │ │ ├── event_store.h │ │ ├── impl │ │ │ ├── entity_user.h │ │ │ ├── event_def.h │ │ │ └── event_store_mem.h │ │ └── serializer.h │ └── src │ │ ├── entity_user.cpp │ │ ├── event_store_mem.cpp │ │ └── main.cpp ├── ff_performance │ ├── Makefile │ └── src │ │ └── main.cpp ├── game_framework │ ├── Makefile │ ├── client │ │ ├── Makefile │ │ └── src │ │ │ └── main.cpp │ ├── common_include │ │ ├── common_msg_def.h │ │ └── logic_msg_def.h │ ├── gateway │ │ ├── Makefile │ │ ├── include │ │ │ └── gateway_service.h │ │ ├── perf.txt │ │ └── src │ │ │ ├── gateway_service.cpp │ │ │ └── main.cpp │ ├── logic │ │ ├── Makefile │ │ ├── impl │ │ │ ├── command │ │ │ │ └── task_command.h │ │ │ ├── task │ │ │ │ ├── event_def.h │ │ │ │ ├── task_service.cpp │ │ │ │ ├── task_service.h │ │ │ │ ├── test_task.h │ │ │ │ ├── user_task.cpp │ │ │ │ └── user_task.h │ │ │ └── user │ │ │ │ ├── user.h │ │ │ │ └── user_mgr.h │ │ ├── include │ │ │ └── logic_service.h │ │ └── src │ │ │ ├── logic_service.cpp │ │ │ └── main.cpp │ └── manager │ │ ├── Makefile │ │ ├── include │ │ └── manager_service.h │ │ └── src │ │ ├── main.cpp │ │ └── manager_service.cpp ├── perf │ ├── Makefile │ └── src │ │ └── main.cpp ├── plugin_msg_broker │ ├── Makefile │ ├── include │ │ ├── channel.h │ │ ├── log_module.h │ │ ├── msg_broker_service.h │ │ ├── plugin_factory.h │ │ ├── plugin_i.h │ │ └── plugin_impl │ │ │ ├── plugin_dll.h │ │ │ ├── plugin_lua.h │ │ │ ├── plugin_python.h │ │ │ └── pyext.h │ ├── plugin │ │ ├── include │ │ │ └── msg_broker_iterface.h │ │ ├── plugin_echo_dll │ │ │ ├── gen_dll.sh │ │ │ └── plugin_echo_dll.cpp │ │ ├── plugin_echo_lua │ │ │ └── echo.lua │ │ └── plugin_echo_py │ │ │ └── echo.py │ └── src │ │ ├── channel.cpp │ │ ├── main.cpp │ │ ├── msg_broker_service.cpp │ │ ├── plugin_factory.cpp │ │ └── plugin_impl │ │ ├── plugin_dll.cpp │ │ ├── plugin_lua.cpp │ │ └── plugin_python.cpp ├── ranklist │ ├── Makefile │ ├── include │ │ ├── rank_obj.h │ │ ├── rank_obj_mgr.h │ │ ├── rank_system.h │ │ └── ranklist.h │ └── src │ │ ├── main.cpp │ │ ├── rank_system.cpp │ │ └── ranklist.cpp ├── rpc │ ├── Makefile │ ├── include │ │ └── msg_def.h │ └── src │ │ └── main.cpp └── tutorial │ ├── Makefile │ ├── msg_def.h │ └── tutorial.cpp └── fflib ├── ai └── ffai.h ├── base ├── arg_helper.h ├── atomic_op.h ├── daemon_tool.h ├── fftype.h ├── lock.cpp ├── lock.h ├── log.cpp ├── log.h ├── os_tool.h ├── performance_daemon.cpp ├── performance_daemon.h ├── signal_helper.h ├── singleton.h ├── smart_ptr.h ├── strtool.h ├── task_queue_i.h ├── task_queue_impl.h ├── thread.cpp ├── thread.h ├── time_tool.h └── timer_service.h ├── count └── ffcount.h ├── cqrs ├── aggregate_root_i.h ├── bus_i.h ├── command_handler_i.h ├── command_i.h └── event_i.h ├── db ├── db_ops.h ├── ffcrud.h ├── ffdb.cpp ├── ffdb.h ├── mysql_ops.cpp ├── mysql_ops.h ├── sqlite3.c ├── sqlite3.h ├── sqlite3ext.h ├── sqlite_ops.cpp └── sqlite_ops.h ├── ext ├── algorithm │ ├── astar │ │ ├── astar.cpp │ │ ├── astar.h │ │ └── astar_element.h │ └── astar2 │ │ ├── astar.cpp │ │ └── astar.h ├── generator │ ├── README.txt │ ├── example.idl │ ├── idl_generator.py │ ├── json_instream.cpp │ ├── json_instream.h │ ├── json_outstream.cpp │ ├── json_outstream.h │ ├── main.cc │ ├── pylib │ │ ├── __init__.py │ │ ├── code_generator.py │ │ ├── inc.py │ │ └── src_parser.py │ ├── rapidjson │ │ ├── allocators.h │ │ ├── document.h │ │ ├── encodedstream.h │ │ ├── encodings.h │ │ ├── filereadstream.h │ │ ├── filestream.h │ │ ├── filewritestream.h │ │ ├── internal │ │ │ ├── pow10.h │ │ │ ├── stack.h │ │ │ └── strfunc.h │ │ ├── prettywriter.h │ │ ├── rapidjson.h │ │ ├── reader.h │ │ ├── stringbuffer.h │ │ └── writer.h │ ├── run.sh │ └── smart_ptr │ │ ├── ref_count.h │ │ └── shared_ptr.h ├── log │ └── log.h ├── rapidjson │ ├── allocators.h │ ├── document.h │ ├── encodedstream.h │ ├── encodings.h │ ├── filereadstream.h │ ├── filestream.h │ ├── filewritestream.h │ ├── internal │ │ ├── pow10.h │ │ ├── stack.h │ │ └── strfunc.h │ ├── prettywriter.h │ ├── rapidjson.h │ ├── reader.h │ ├── stringbuffer.h │ └── writer.h └── smart_ptr │ └── shared_ptr.h ├── gtest ├── include │ └── gtest │ │ ├── gtest-death-test.h │ │ ├── gtest-message.h │ │ ├── gtest-param-test.h │ │ ├── gtest-param-test.h.pump │ │ ├── gtest-printers.h │ │ ├── gtest-spi.h │ │ ├── gtest-test-part.h │ │ ├── gtest-typed-test.h │ │ ├── gtest.h │ │ ├── gtest_pred_impl.h │ │ ├── gtest_prod.h │ │ └── internal │ │ ├── gtest-death-test-internal.h │ │ ├── gtest-filepath.h │ │ ├── gtest-internal.h │ │ ├── gtest-linked_ptr.h │ │ ├── gtest-param-util-generated.h │ │ ├── gtest-param-util-generated.h.pump │ │ ├── gtest-param-util.h │ │ ├── gtest-port.h │ │ ├── gtest-string.h │ │ ├── gtest-tuple.h │ │ ├── gtest-tuple.h.pump │ │ ├── gtest-type-util.h │ │ └── gtest-type-util.h.pump └── src │ ├── gtest-all.cc │ ├── gtest-all.cpp │ ├── gtest-death-test.cc │ ├── gtest-filepath.cc │ ├── gtest-internal-inl.h │ ├── gtest-port.cc │ ├── gtest-printers.cc │ ├── gtest-test-part.cc │ ├── gtest-typed-test.cc │ ├── gtest.cc │ └── gtest_main.cc ├── lua ├── fflua.h ├── fflua_register.h └── fflua_type.h ├── net ├── acceptor_i.h ├── acceptor_impl.cpp ├── acceptor_impl.h ├── base_heartbeat.h ├── codec.h ├── common_socket_controller.cpp ├── common_socket_controller.h ├── connector.h ├── epoll_i.h ├── epoll_impl.cpp ├── epoll_impl.h ├── gateway_acceptor.cpp ├── gateway_acceptor.h ├── gateway_socket_controller.cpp ├── gateway_socket_controller.h ├── http_acceptor.cpp ├── http_acceptor.h ├── message.h ├── msg_handler_i.h ├── msg_sender.h ├── net_factory.h ├── net_stat.cpp ├── net_stat.h ├── netbase.h ├── socket_controller_i.h ├── socket_i.h ├── socket_impl.cpp ├── socket_impl.h ├── socket_op.h ├── text_socket_controller_impl.cpp └── text_socket_controller_impl.h ├── rpc ├── broker_application.h ├── broker_service.cpp ├── broker_service.h ├── ffrpc.cpp ├── ffrpc.h ├── gateway_service_i.h ├── rpc_callback.h ├── rpc_future.h ├── rpc_reg.h ├── rpc_service.cpp ├── rpc_service.h ├── rpc_service_group.cpp └── rpc_service_group.h └── xml ├── ffxml.cpp ├── ffxml.h ├── tinystr.cpp ├── tinystr.h ├── tinyxml.cpp ├── tinyxml.h ├── tinyxmlerror.cpp └── tinyxmlparser.cpp /Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY:all 3 | 4 | all: 5 | make -C example 6 | 7 | clean: 8 | make clean -C example/ 9 | -------------------------------------------------------------------------------- /example/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY:all 3 | 4 | all: 5 | make -C book && make -C broker && make -C cqrs && make -C echo_client && make -C echo_server && make -C event_store && make -C ff_performance && make -C game_framework && make -C ranklist && make -C rpc && make -C tutorial 6 | 7 | clean: 8 | make clean -C book 9 | make clean -C broker 10 | make clean -C cqrs 11 | make clean -C echo_client 12 | make clean -C echo_server 13 | make clean -C event_store 14 | make clean -C ff_performance 15 | make clean -C game_framework 16 | #make clean -C plugin_msg_broker 17 | make clean -C ranklist 18 | make clean -C rpc 19 | make clean -C tutorial 20 | -------------------------------------------------------------------------------- /example/book/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY:all 3 | 4 | all: 5 | make -C log && make -C lua &&make -C task_queue && make -C sqlite && make -C count && make -C count_client 6 | 7 | clean: 8 | make clean -C log 9 | make clean -C lua 10 | make clean -C task_queue 11 | make clean -C sqlite 12 | make clean -C count 13 | make clean -C count_client 14 | -------------------------------------------------------------------------------- /example/book/ai/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_ai 16 | 17 | #源文件目录 18 | SrcDir= . ../../../fflib/base 19 | #头文件目录 20 | IncDir= ../../../fflib/ 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/book/count/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_count 16 | 17 | #源文件目录 18 | SrcDir= . ../../../fflib/db ../../../fflib/base ../../../fflib/net ../../../fflib/rpc 19 | #头文件目录 20 | IncDir= ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=gcc 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | gcc -c ../../../fflib/db/sqlite3.c -o sqlite3.o 37 | g++ -o $(BIN) $(OBJS) sqlite3.o $(LDFLAGS) 38 | @echo -e " OK!\tComplie $@ " 39 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 40 | 41 | %.o:%.cpp 42 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 43 | @$(CC) $(CFLAGS) -c $< -o $@ 44 | 45 | .PHONY: clean 46 | clean: 47 | @echo -e "[$(ARCH)] \tCleaning files..." 48 | @$(RM) $(OBJS) $(BIN) sqlite3.o 49 | -------------------------------------------------------------------------------- /example/book/count/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "count/ffcount.h" 3 | #include "rpc/broker_application.h" 4 | #include "base/daemon_tool.h" 5 | #include "base/arg_helper.h" 6 | 7 | using namespace ff; 8 | #include 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | if (argc == 1) 13 | { 14 | printf("usage: app -l tcp://127.0.0.1:10241 -http tcp://127.0.0.1:8080\n"); 15 | return 1; 16 | } 17 | arg_helper_t arg_helper(argc, argv); 18 | broker_application_t::run(argc, argv); 19 | 20 | ffrpc_t ffrpc; 21 | assert(0 == ffrpc.open(arg_helper.get_option_value("-l")) && "can't connnect to broker"); 22 | if (arg_helper.is_enable_option("-d")) 23 | { 24 | daemon_tool_t::daemon(); 25 | } 26 | 27 | ffcount_service_t ffcount_service; 28 | ffcount_service.start(); 29 | 30 | ffrpc.create_service("event_log_service", 0) 31 | .bind_service(&ffcount_service) 32 | .reg(&ffcount_service_t::save_event) 33 | .reg(&ffcount_service_t::query); 34 | 35 | acceptor_i* p_http = NULL; 36 | if (arg_helper.is_enable_option("-http")) 37 | { 38 | p_http = net_factory_t::http_listen(arg_helper.get_option_value("-http"), &ffcount_service); 39 | } 40 | 41 | signal_helper_t::wait(); 42 | ffrpc.close(); 43 | ffcount_service.stop(); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /example/book/count_client/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_client 16 | 17 | #源文件目录 18 | SrcDir= . ../../../fflib/db ../../../fflib/base ../../../fflib/net ../../../fflib/rpc 19 | #头文件目录 20 | IncDir= ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=gcc 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | gcc -c ../../../fflib/db/sqlite3.c -o sqlite3.o 37 | g++ -o $(BIN) $(OBJS) sqlite3.o $(LDFLAGS) 38 | @echo -e " OK!\tComplie $@ " 39 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 40 | 41 | %.o:%.cpp 42 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 43 | @$(CC) $(CFLAGS) -c $< -o $@ 44 | 45 | .PHONY: clean 46 | clean: 47 | @echo -e "[$(ARCH)] \tCleaning files..." 48 | @$(RM) $(OBJS) $(BIN) sqlite3.o 49 | -------------------------------------------------------------------------------- /example/book/count_client/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "count/ffcount.h" 3 | #include "rpc/broker_application.h" 4 | #include "base/daemon_tool.h" 5 | #include "base/arg_helper.h" 6 | 7 | using namespace ff; 8 | #include 9 | 10 | #define NUM 0 11 | ffrpc_t* g_ffrpc = NULL; 12 | int main(int argc, char* argv[]) 13 | { 14 | arg_helper_t arg_helper(argc, argv); 15 | if (false == arg_helper.is_enable_option("-l")) 16 | { 17 | printf("usage: app -l tcp://127.0.0.1:10241\n"); 18 | return 1; 19 | } 20 | 21 | ffrpc_t ffrpc; 22 | g_ffrpc = &ffrpc; 23 | assert(0 == ffrpc.open(arg_helper.get_option_value("-l")) && "can't connnect to broker"); 24 | 25 | assert(ffrpc.get_service("event_log_service", 0) && "event_log_service 0 not exist"); 26 | 27 | event_log_t el("test"/*dbname*/,"dumy"/*tablename*/, "A,B,C"/*fields name*/);el.def(100, "p\"T'p", 5.4); 28 | ffrpc.async_call("event_log_service", 0, el); 29 | 30 | event_queryt_t::in_t in_msg; 31 | in_msg.db_name = "test"; 32 | in_msg.sql = "select * from dumy limit 10"; 33 | 34 | struct lambda_t 35 | { 36 | static void async_callback(event_queryt_t::out_t& msg_) 37 | { 38 | printf("=====>>>>> async_callback dump data [%s]<<<<<<=======\n", msg_.err_msg.c_str()); 39 | ffdb_t::dump(msg_.ret_data, msg_.col_names); 40 | } 41 | }; 42 | 43 | ffrpc.async_call("event_log_service", 0, in_msg, &lambda_t::async_callback); 44 | 45 | while (true) 46 | { 47 | event_log_t el("test", "dumy", "A,B,C");el.def(100, "p\"T'p", 5.4); 48 | g_ffrpc->async_call("event_log_service", 0, el); 49 | sleep(1); 50 | event_queryt_t::in_t in_msg; 51 | //in_msg.str_time = "2013/2";//! 查询1月的数据 52 | in_msg.db_name = "test"; 53 | in_msg.sql = "select * from dumy order by autoid desc limit 5"; 54 | event_queryt_t::out_t msg_; 55 | ffrpc.call("event_log_service", 0, in_msg, msg_); 56 | printf("=====>>>>> sync callback dump data [%s]<<<<<<=======\n", msg_.err_msg.c_str()); 57 | ffdb_t::dump(msg_.ret_data, msg_.col_names); 58 | } 59 | signal_helper_t::wait(); 60 | ffrpc.close(); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /example/book/count_client/php/test.php: -------------------------------------------------------------------------------- 1 | 2 | "http request failed by curl", "col_names"=>array(), "ret_data"=>array()); 15 | } 16 | else 17 | { 18 | $ret = json_decode($output); 19 | if (!$ret) 20 | { 21 | $ret = array("err_msg" =>$output, "col_names"=>array(), "ret_data"=>array()); 22 | } 23 | } 24 | return $ret; 25 | } 26 | 27 | function ffcount_query($host, $port, $str_time, $db_name, $sql) 28 | { 29 | $ch = curl_init(); 30 | $url = "http://".$host.":".$port."/".$str_time."/".$db_name."/".rawurlencode($sql); 31 | curl_setopt($ch, CURLOPT_URL, $url); 32 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 33 | curl_setopt($ch, CURLOPT_HEADER, 0); 34 | $output = curl_exec($ch); 35 | curl_close($ch); 36 | if ($output === FALSE) { 37 | $ret = array("err_msg" =>"http request failed by curl", "col_names"=>array(), "ret_data"=>array()); 38 | } 39 | else 40 | { 41 | $ret = json_decode($output); 42 | if (!$ret) 43 | { 44 | $ret = array("err_msg" =>$output, "col_names"=>array(), "ret_data"=>array()); 45 | } 46 | } 47 | return $ret; 48 | } 49 | 50 | $host = "127.0.0.1"; 51 | $port = 8080; 52 | $str_time = "2013/2"; 53 | $db_name = "test"; 54 | $sql = "select * from dumy"; 55 | $ret = ffcount_dbinfo($host, $port); 56 | print_r($ret); 57 | $ret = ffcount_query($host, $port, $str_time, $db_name, $sql); 58 | print_r($ret); 59 | ?> 60 | 61 | -------------------------------------------------------------------------------- /example/book/log/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_log 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/book/log/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #include "base/task_queue_impl.h" 6 | #include "base/thread.h" 7 | #include "base/log.h" 8 | 9 | using namespace ff; 10 | 11 | int main(int argc, char* argv[]) 12 | { 13 | 14 | LOG.start("-log_path ./log -log_filename log -log_class FF,XX -log_print_screen true -log_print_file true -log_level 6"); 15 | LOGDEBUG(("XX", "FFFFF")); 16 | LOGTRACE(("XX", "FFFFF")); 17 | LOGINFO(("XX", "FFFFF")); 18 | LOGWARN(("XX", "FFFFF")); 19 | LOGERROR(("XX", "FFFFF")); 20 | LOGFATAL(("XX", "FFFFF")); 21 | LOG.mod_class("TT", true); 22 | 23 | sleep(1); 24 | LOGFATAL(("TT", "FFFFF")); 25 | 26 | LOGFATAL(("FF", "DSDFFFFF%s", string("SFWEGGGGGGGGG"))); 27 | 28 | LOG.stop(); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /example/book/lua/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_lua 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../../fflib/ ../../../fflib/include/lua/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/book/lua/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #include "lua/fflua.h" 6 | 7 | using namespace ff; 8 | 9 | class base_t 10 | { 11 | public: 12 | void dump() 13 | { 14 | printf("in %s a:%d\n", __FUNCTION__, v); 15 | } 16 | int v; 17 | }; 18 | class foo_t: public base_t 19 | { 20 | public: 21 | foo_t(int b) 22 | { 23 | printf("in %s b:%d this=%p\n", __FUNCTION__, b, this); 24 | } 25 | ~foo_t() 26 | { 27 | printf("in %s\n", __FUNCTION__); 28 | } 29 | void print(int64_t a, base_t* p) const 30 | { 31 | printf("in foo_t::print a:%ld p:%p\n", (long)a, p); 32 | } 33 | 34 | static void dumy() 35 | { 36 | printf("in %s\n", __FUNCTION__); 37 | } 38 | int a; 39 | }; 40 | 41 | void dumy(map ret, vector a, list b, set c) 42 | { 43 | for (map::iterator it = ret.begin(); it != ret.end(); ++it) 44 | { 45 | printf("i:%s, val:%s:\n", it->first.c_str(), it->second.c_str()); 46 | } 47 | printf("in %s\n", __FUNCTION__); 48 | } 49 | 50 | void lua_reg(lua_State* ls) 51 | { 52 | fflua_register_t(ls, "base_t") 53 | .def(&base_t::dump, "dump") 54 | .def(&base_t::v, "v"); 55 | 56 | 57 | fflua_register_t(ls, "foo_t", "base_t") 58 | .def(&foo_t::print, "print") 59 | .def(&foo_t::a, "a"); 60 | fflua_register_t<>(ls) 61 | .def(&dumy, "dumy"); 62 | } 63 | int main(int argc, char* argv[]) 64 | { 65 | 66 | fflua_t fflua; 67 | fflua.load_file("test.lua"); 68 | fflua.reg(lua_reg); 69 | vector vt;vt.push_back(1); 70 | map mp;mp["ok"]="nice"; 71 | map ret ; 72 | fflua.call >("foo", 1, vt, mp, list(), set()); 73 | 74 | for (map::iterator it = ret.begin(); it != ret.end(); ++it) 75 | { 76 | printf("i:%s, val:%s:\n", it->first.c_str(), it->second.c_str()); 77 | } 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /example/book/lua/test.lua: -------------------------------------------------------------------------------- 1 | 2 | function foo(a, vt, tb) 3 | print(tb) 4 | table.insert(tb, 2) 5 | table.insert(tb, 3) 6 | for k, v in pairs(tb) 7 | do 8 | print(k, v) 9 | end 10 | 11 | base = base_t:new() 12 | --base:dump() 13 | foo = foo_t:new(1234567) 14 | print("foooooo....:", foo, foo:get_pointer()) 15 | foo:print(1, foo) 16 | --foo:delete() 17 | dumy(tb) 18 | foo.v = 12345 19 | foo:dump() 20 | return tb 21 | end 22 | 23 | -------------------------------------------------------------------------------- /example/book/rpc/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_rpc 16 | 17 | #源文件目录 18 | SrcDir= . ../../../fflib/db ../../../fflib/base ../../../fflib/net ../../../fflib/rpc 19 | #头文件目录 20 | IncDir= ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=gcc 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | gcc -c ../../../fflib/db/sqlite3.c -o sqlite3.o 37 | g++ -o $(BIN) $(OBJS) $(LDFLAGS) sqlite3.o 38 | @echo -e " OK!\tComplie $@ " 39 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 40 | 41 | %.o:%.cpp 42 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 43 | @$(CC) $(CFLAGS) -c $< -o $@ 44 | 45 | .PHONY: clean 46 | clean: 47 | @echo -e "[$(ARCH)] \tCleaning files..." 48 | @$(RM) $(OBJS) $(BIN) sqlite3.o 49 | -------------------------------------------------------------------------------- /example/book/sqlite/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_sqlite 16 | 17 | #源文件目录 18 | SrcDir= . ../../../fflib/db 19 | #头文件目录 20 | IncDir= ../../../fflib/ 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=gcc 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | gcc -c ../../../fflib/db/sqlite3.c -o sqlite3.o 37 | g++ -o $(BIN) $(OBJS) sqlite3.o $(LDFLAGS) 38 | @echo -e " OK!\tComplie $@ " 39 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 40 | 41 | %.o:%.cpp 42 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 43 | @$(CC) $(CFLAGS) -c $< -o $@ 44 | 45 | .PHONY: clean 46 | clean: 47 | @echo -e "[$(ARCH)] \tCleaning files..." 48 | @$(RM) $(OBJS) $(BIN) sqlite3.o 49 | -------------------------------------------------------------------------------- /example/book/task_queue/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_task_queue 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/book/xml/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread -llua -ldl 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_xml 16 | 17 | #源文件目录 18 | SrcDir= . ../../../fflib/xml 19 | #头文件目录 20 | IncDir= ../../../fflib/ 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/book/xml/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "xml/ffxml.h" 3 | using namespace ff; 4 | 5 | 6 | // 7 | // happly 8 | // 9 | // OhNice 10 | // 99 11 | // 12 | // 13 | 14 | int main(int argc, char* argv[]) 15 | { 16 | ffxml_t ffxml; 17 | 18 | //! 载入test.xml 19 | if (ffxml.load("test.xml")) 20 | { 21 | printf("test.xml 载入失败\n"); 22 | return 1; 23 | } 24 | 25 | printf("获取字段 game.scene: %s\n", ffxml.get("game.scene")); 26 | printf("获取字段 game.role.name: %s\n", ffxml.get("game.role.name")); 27 | printf("获取字段 game.role.num: %s\n", ffxml.get("game.role.num")); 28 | 29 | printf("获取属性 game.{type}: %s\n", ffxml.get("game.{type}")); 30 | printf("获取属性 game.role.{ID}: %s\n", ffxml.get("game.role.{ID}")); 31 | 32 | printf("获取标记数量 game: %u\n", ffxml.size("game")); 33 | printf("获取标记数量 game.role: %u\n", ffxml.size("game.role")); 34 | 35 | printf("获取属性数量 game: %u\n", ffxml.size("game.{}")); 36 | printf("获取属性数量 game.role: %u\n", ffxml.size("game.role.{}")); 37 | 38 | //! 遍历子节点 39 | char arg_key[128]; 40 | char arg_val[128]; 41 | for (size_t i = 0; i < ffxml.size("game.role"); ++i) 42 | { 43 | sprintf(arg_key, "game.role.&%u", i); 44 | sprintf(arg_val, "game.role.@%u", i); 45 | printf("遍历子节点 game.role: %s->%s\n", ffxml.get(arg_key), ffxml.get(arg_val)); 46 | } 47 | 48 | //! 遍历属性节点 49 | for (size_t i = 0; i < ffxml.size("game.role"); ++i) 50 | { 51 | sprintf(arg_key, "game.role.{&%u}", i); 52 | sprintf(arg_val, "game.role.{@%u}", i); 53 | printf("遍历属性 game.role: %s->%s\n", ffxml.get(arg_key), ffxml.get(arg_val)); 54 | } 55 | 56 | 57 | printf("组合 game.role.@1.{@nick} %s\n", ffxml.get("game.role.@0.{@nick}")); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /example/book/xml/test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | happly 4 | 5 | OhNice 6 | 99 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/broker/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_broker 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompiling $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/broker/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "rpc/broker_service.h" 5 | #include "net/net_factory.h" 6 | 7 | #include "rpc/broker_application.h" 8 | using namespace ff; 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | broker_application_t::run(argc, argv); 13 | 14 | signal_helper_t::wait(); 15 | cout << "\noh end\n"; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /example/codefmt.md: -------------------------------------------------------------------------------- 1 | # C++ 代码规范工作流 2 | 3 | 为了规范工作流程,提高工作效率,这里根据 Google 提出的 C++ 编码风格,配合若干检查、自动修改工具,制定了一套代码规范工作流。 4 | 5 | ## Google C++ Style Guide 6 | 7 | Google 代码规范的详情,请参考 8 | 9 | 10 | 11 | ## 自动化检查纠正工具 12 | 13 | 下面介绍几个会用到的自动化工具。 14 | 15 | #### ClangFormat 16 | 17 | 18 | 19 | 可以自动格式化代码,使其符合 Google 代码规范,不包括: 20 | 21 | - 语法的修改 22 | - 命名修改 23 | 24 | #### Cpplint 25 | 26 | 27 | 28 | 可以检查代码是否符合 Google 代码规范,极其严格,但不包括: 29 | 30 | - 语法特性的规范 31 | 32 | #### Clang-Tidy 33 | 34 | 35 | 36 | 可以从语法层面来对代码进行检查,可以做到,检查是否使用了某个禁用的语法特性。 37 | 38 | ## 基于 Git 的工作流程 39 | 40 | 1. **编辑阶段**:使用编辑器编辑代码文件,保存前可以依次进行下面的操作和检查: 41 | 1. 使用 **CLangFormat** 自动修改当前代码文件成 Google 建议的风格(**命名风格** 并不会被纠正)。 42 | 2. 使用 **Cpplint** 检查当前保存的文件是否符合 Google 建议的风格 43 | 3. 使用 **Clang-Tidy** 检查当前保存的文件是否符合要求的编码规范 44 | 2. **编译阶段**:代码保存成功后,执行 `make` 编译代码,这里可以配置 CMakeLists.txt,确保每次编译文件时,都会进行一下检查: 45 | 1. 使用 **Cpplint** 检查当前编译的文件是否符合 Google 建议的风格 46 | 2. 使用 **Clang-Tidy** 检查当前编译的文件是否符合要求的编码规范 47 | 3. **提交阶段**:代码保存成功后,执行 `git commint` 提交代码,这里可以配置 **git pre-commit hook** 来触发下面的检查操作,通过则提交成功,否则驳回 48 | 1. 使用 **Cpplint** 检查本次提交的文件是否符合 Google 建议的风格 49 | 2. 使用 **Clang-Tidy** 检查本次提交的文件是否符合要求的编码规范 50 | 4. **上传阶段(服务器端)**:`git commit` 执行成功后,执行 `git push` 推送代码至远程服务器,这边可以配置 **git pre-receive hook** 来出发下面的检查操作,通过则 push 成功,否则驳回 51 | 1. 使用 **Cpplint** 检查本次 push 的文件是否符合 Google 建议的风格 52 | 2. 使用 **Clang-Tidy** 检查本次 push 的文件是否符合要求的编码规范 53 | 54 | ## 基于 SVN 的工作流 55 | 56 | 1. **编辑阶段**:使用编辑器编辑代码文件,保存前可以依次进行下面的操作和检查: 57 | 1. 使用 **CLangFormat** 自动修改当前代码文件成 Google 建议的风格(**命名风格** 并不会被纠正)。 58 | 2. 使用 **Cpplint** 检查当前保存的文件是否符合 Google 建议的风格 59 | 3. 使用 **Clang-Tidy** 检查当前保存的文件是否符合要求的编码规范 60 | 2. **编译阶段**:代码保存成功后,执行 `make` 编译代码,这里可以配置 CMakeLists.txt,确保每次编译文件时,都会进行一下检查: 61 | 1. 使用 **Cpplint** 检查当前编译的文件是否符合 Google 建议的风格 62 | 2. 使用 **Clang-Tidy** 检查当前编译的文件是否符合要求的编码规范 63 | 3. **提交阶段**:代码保存成功后,执行 `svn commit` 提交代码,这里可以配置 **svn pre-commit hook** 来触发下面的检查操作,通过则提交成功,否则驳回 64 | 1. 使用 **Cpplint** 检查本次提交的文件是否符合 Google 建议的风格 65 | 2. 使用 **Clang-Tidy** 检查本次提交的文件是否符合要求的编码规范 66 | 67 | ## 开发环境配置 68 | 69 | Todo. -------------------------------------------------------------------------------- /example/cqrs/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_cqrs 16 | 17 | #源文件目录 18 | SrcDir= . task ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs ../../fflib/gtest/src 19 | #头文件目录 20 | IncDir= . ./cqrs ./include ../../fflib/ ../../fflib/ext ../../fflib/gtest ../../fflib/gtest/include 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $< $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/cqrs/command/task_command.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_TASK_COMMAND_H_ 3 | #define _FF_TASK_COMMAND_H_ 4 | 5 | #include "command_i.h" 6 | 7 | namespace ff 8 | { 9 | 10 | class accept_task_cmd_t: public user_command_t 11 | { 12 | public: 13 | virtual void enc() 14 | { 15 | encoder() << tid; 16 | } 17 | virtual void dec() 18 | { 19 | decoder() >> tid; 20 | } 21 | 22 | uint32_t tid; 23 | }; 24 | 25 | class complete_task_cmd_t: public user_command_t 26 | { 27 | public: 28 | virtual void enc() 29 | { 30 | encoder() << tid; 31 | } 32 | virtual void dec() 33 | { 34 | decoder() >> tid; 35 | } 36 | 37 | uint32_t tid; 38 | }; 39 | 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /example/cqrs/cqrs/aggregate_root_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_AGGREGATE_ROOT_I_ 3 | #define _FF_AGGREGATE_ROOT_I_ 4 | 5 | #include 6 | using namespace std; 7 | 8 | #include 9 | 10 | namespace ff 11 | { 12 | 13 | typedef long guid_t; 14 | 15 | class aggregate_root_i: public type_i 16 | { 17 | typedef list event_list_t; 18 | public: 19 | aggregate_root_i():m_id(0){} 20 | virtual ~aggregate_root_i(){} 21 | 22 | virtual guid_t get_id() const { return m_id; } 23 | virtual void set_id(guid_t id_) { m_id = id_; } 24 | 25 | void add_event(event_i* e_) {m_events.push_back(e_);} 26 | const event_list_t& get_events() const { return m_events; } 27 | void clear_event() 28 | { 29 | for (event_list_t::iterator it = m_events.begin(); it != m_events.end(); ++it) 30 | { 31 | delete *it; 32 | } 33 | m_events.clear(); 34 | } 35 | 36 | template 37 | void add_event(const T& event_) 38 | { 39 | this->add_event(new T(event_)); 40 | } 41 | protected: 42 | guid_t m_id; 43 | event_list_t m_events; 44 | }; 45 | 46 | template 47 | class aggregate_root_t: public auto_type_t 48 | { 49 | public: 50 | virtual ~ aggregate_root_t(){} 51 | }; 52 | 53 | #define AR aggregate_root_t 54 | } 55 | #endif 56 | -------------------------------------------------------------------------------- /example/cqrs/cqrs/command_handler_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_COMMAD_HANDLER_I_ 3 | #define _FF_COMMAD_HANDLER_I_ 4 | 5 | namespace ff 6 | { 7 | 8 | class command_handler_i: public type_i 9 | { 10 | public: 11 | virtual ~command_handler_i(){} 12 | }; 13 | 14 | template 15 | class command_handler_t: public auto_type_t 16 | { 17 | public: 18 | virtual ~command_handler_t(){} 19 | }; 20 | 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /example/cqrs/cqrs/command_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_COMMAD_I_ 3 | #define _FF_COMMAD_I_ 4 | 5 | #include "base/fftype.h" 6 | #include "net/codec.h" 7 | 8 | namespace ff 9 | { 10 | 11 | class command_i: public type_i 12 | { 13 | public: 14 | virtual ~command_i(){} 15 | }; 16 | 17 | template 18 | class command_t: public auto_type_t 19 | { 20 | public: 21 | virtual ~command_t(){} 22 | bin_decoder_t& decoder() { return m_decoder; } 23 | bin_encoder_t& encoder() { return m_encoder; } 24 | virtual string encode() 25 | { 26 | enc(); 27 | return encoder().get_buff(); 28 | } 29 | virtual void decode(const string& src_buff_) 30 | { 31 | decoder().init(src_buff_); 32 | dec(); 33 | } 34 | virtual void enc() = 0; 35 | virtual void dec() = 0; 36 | 37 | private: 38 | bin_decoder_t m_decoder; 39 | bin_encoder_t m_encoder; 40 | }; 41 | 42 | 43 | template 44 | class user_command_t: public auto_type_t 45 | { 46 | public: 47 | user_command_t():uid(0){} 48 | virtual ~user_command_t(){} 49 | bin_decoder_t& decoder() { return m_decoder; } 50 | bin_encoder_t& encoder() { return m_encoder; } 51 | virtual string encode() 52 | { 53 | encoder() << uid; 54 | enc(); 55 | return encoder().get_buff(); 56 | } 57 | virtual void decode(const string& src_buff_) 58 | { 59 | decoder().init(src_buff_) >> uid; 60 | dec(); 61 | } 62 | virtual void enc() = 0; 63 | virtual void dec() = 0; 64 | 65 | int64_t get_id() const { return uid; } 66 | void set_id(int64_t id_) { uid = id_; } 67 | private: 68 | bin_decoder_t m_decoder; 69 | bin_encoder_t m_encoder; 70 | public: 71 | int64_t uid; 72 | }; 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /example/cqrs/cqrs/event_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_EVENT_I_ 3 | #define _FF_EVENT_I_ 4 | 5 | #include "base/fftype.h" 6 | 7 | namespace ff 8 | { 9 | 10 | class event_i: public type_i 11 | { 12 | public: 13 | virtual ~event_i(){} 14 | }; 15 | 16 | template 17 | class event_t: public auto_type_t 18 | { 19 | public: 20 | virtual ~event_t(){} 21 | }; 22 | 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /example/cqrs/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | #include "cqrs/bus_i.h" 6 | #include "user/user_mgr.h" 7 | #include "command/task_command.h" 8 | #include "task/task_service.h" 9 | #include "task/test_task.h" 10 | #include "base/fftype.h" 11 | using namespace ff; 12 | 13 | #include "gtest/gtest.h" 14 | 15 | int main(int argc, char* argv[]) 16 | { 17 | TASK_SERVICE.start(); 18 | 19 | testing::InitGoogleTest(&argc, argv); 20 | return RUN_ALL_TESTS(); 21 | return 0; 22 | } 23 | 24 | /* 25 | class monster_t 26 | { 27 | protected: 28 | player_t* m_attack; 29 | 30 | public: 31 | void handle_ai() 32 | { 33 | if (m_attack) 34 | { 35 | int x = m_attack->get_x(); 36 | } 37 | } 38 | } 39 | 40 | class monster_t 41 | { 42 | protected: 43 | long m_attack_id; 44 | 45 | public: 46 | void handle_ai() 47 | { 48 | player_t* attack = obj_mgr.get(m_attack_id); 49 | if (attack) 50 | { 51 | int x = attack->get_x(); 52 | } 53 | } 54 | } 55 | 56 | 57 | class monster_t 58 | { 59 | protected: 60 | player_t* m_attack; 61 | 62 | public: 63 | void handle_ai() 64 | { 65 | if (obj_mgr.is_exist(m_attack)) 66 | { 67 | int x = m_attack->get_x(); 68 | } 69 | } 70 | } 71 | 72 | 73 | 74 | class monster_t 75 | { 76 | protected: 77 | weak_ptr m_attack; 78 | shared_ptr get_attack() 79 | { 80 | return shared_ptr(m_attack); 81 | } 82 | public: 83 | void handle_ai() 84 | { 85 | shared_ptr attack = get_attack(); 86 | if (attack) 87 | { 88 | int x = attack->get_x(); 89 | } 90 | } 91 | } 92 | */ 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /example/cqrs/task/event_def.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EVENT_DEF_I_ 3 | #define _EVENT_DEF_I_ 4 | 5 | #include "event_i.h" 6 | 7 | namespace ff 8 | { 9 | 10 | class task_accepted_t: public event_t 11 | { 12 | public: 13 | task_accepted_t(int task_id_ =0, int dest_value_ = 0): 14 | task_id(task_id_), 15 | dest_value(dest_value_) 16 | {} 17 | int task_id; 18 | int dest_value; 19 | }; 20 | 21 | class task_completed_t: public event_t 22 | { 23 | public: 24 | task_completed_t(int tid_): 25 | task_id(tid_) 26 | {} 27 | int task_id; 28 | }; 29 | 30 | class task_modified_t: public event_t 31 | { 32 | public: 33 | task_modified_t(int tid_, int value_): 34 | task_id(tid_), 35 | value(value_) 36 | {} 37 | int task_id; 38 | int value; 39 | }; 40 | 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /example/cqrs/task/task_service.cpp: -------------------------------------------------------------------------------- 1 | #include "task_service.h" 2 | #include "command/task_command.h" 3 | #include "bus_i.h" 4 | 5 | #include "user/user_mgr.h" 6 | using namespace ff; 7 | 8 | #include 9 | using namespace std; 10 | 11 | task_service_t::task_service_t() 12 | { 13 | } 14 | 15 | task_service_t::~task_service_t() 16 | { 17 | } 18 | 19 | int task_service_t::start() 20 | { 21 | subscriber_t subscriber; 22 | subscriber.reg(this) 23 | .reg(this); 24 | BUS.subscribe(subscriber); 25 | return 0; 26 | } 27 | 28 | int task_service_t::stop() 29 | { 30 | return 0; 31 | } 32 | 33 | void task_service_t::handle(const accept_task_cmd_t& cmd_) 34 | { 35 | cout <<"accept_task_cmd_t " << cmd_.tid << " xx\n"; 36 | USER_MGR.get_user(cmd_.uid).get_tasks().accet_task(cmd_.tid); 37 | } 38 | 39 | void task_service_t::handle(const complete_task_cmd_t& cmd_) 40 | { 41 | USER_MGR.get_user(cmd_.uid).get_tasks().complete_task(cmd_.tid); 42 | } 43 | -------------------------------------------------------------------------------- /example/cqrs/task/task_service.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_TASK_SERVICE_H_ 3 | #define _FF_TASK_SERVICE_H_ 4 | 5 | #include "base/singleton.h" 6 | 7 | namespace ff 8 | { 9 | class accept_task_cmd_t; 10 | class complete_task_cmd_t; 11 | 12 | class task_service_t 13 | { 14 | public: 15 | task_service_t(); 16 | ~task_service_t(); 17 | 18 | int start(); 19 | int stop(); 20 | 21 | void handle(const accept_task_cmd_t& cmd_); 22 | void handle(const complete_task_cmd_t& cmd_); 23 | }; 24 | 25 | #define TASK_SERVICE singleton_t::instance() 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /example/cqrs/task/test_task.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanchy/fflib/ee6a1ba918b444ceb5e86a25dbf7c4a236494709/example/cqrs/task/test_task.h -------------------------------------------------------------------------------- /example/cqrs/task/user_task.cpp: -------------------------------------------------------------------------------- 1 | #include "user_task.h" 2 | #include "event_def.h" 3 | 4 | using namespace ff; 5 | #include 6 | using namespace std; 7 | 8 | user_tasks_t::user_tasks_t() 9 | {} 10 | 11 | user_tasks_t::~user_tasks_t() 12 | {} 13 | 14 | void user_tasks_t::accet_task(int task_id_) 15 | { 16 | if (m_tasks.find(task_id_) != m_tasks.end()) throw task_exception_t("tid exist"); 17 | apply_change(task_accepted_t(task_id_, 100)); 18 | } 19 | 20 | void user_tasks_t::complete_task(int task_id_) 21 | { 22 | task_set_t::iterator it = m_tasks.find(task_id_); 23 | 24 | if (it == m_tasks.end()) throw task_exception_t("tid not exist"); 25 | if (it->second.current_value < it->second.dest_value) throw task_exception_t("not completed"); 26 | 27 | apply_change(task_completed_t(task_id_)); 28 | } 29 | 30 | void user_tasks_t::modify_task(int task_id_, int value_) 31 | { 32 | task_set_t::iterator it = m_tasks.find(task_id_); 33 | 34 | if (it == m_tasks.end()) throw task_exception_t("tid not exist"); 35 | if (it->second.status != TASK_ACCEPTED) throw task_exception_t("status invalid"); 36 | 37 | apply_change(task_modified_t(task_id_, value_)); 38 | } 39 | 40 | void user_tasks_t::apply(const task_accepted_t& event_) 41 | { 42 | task_ino_t task_info(event_.task_id, event_.dest_value, TASK_ACCEPTED); 43 | m_tasks.insert(make_pair(event_.task_id, task_info)); 44 | } 45 | 46 | void user_tasks_t::apply(const task_completed_t& event_) 47 | { 48 | m_tasks[event_.task_id].status = TASK_COMPLETED; 49 | } 50 | 51 | void user_tasks_t::apply(const task_modified_t& event_) 52 | { 53 | m_tasks[event_.task_id].current_value += event_.value; 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /example/cqrs/task/user_task.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _USER_TASKS_I_ 3 | #define _USER_TASKS_I_ 4 | 5 | #include "aggregate_root_i.h" 6 | #include "bus_i.h" 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | namespace ff 13 | { 14 | 15 | class task_accepted_t; 16 | class task_completed_t; 17 | class task_modified_t; 18 | 19 | class user_tasks_t: public aggregate_root_i 20 | { 21 | public: 22 | typedef runtime_error task_exception_t; 23 | enum task_status_e 24 | { 25 | TASK_UNACCEPTED, 26 | TASK_ACCEPTED, 27 | TASK_COMPLETED, 28 | }; 29 | struct task_ino_t 30 | { 31 | task_ino_t(int tid = 0, int dest_value_ = 0, int status_ = TASK_UNACCEPTED): 32 | task_id(tid), 33 | status(status_), 34 | current_value(0), 35 | dest_value(dest_value_) 36 | {} 37 | 38 | int task_id; 39 | int status; 40 | int current_value; 41 | int dest_value; 42 | }; 43 | typedef map task_set_t; 44 | public: 45 | user_tasks_t(); 46 | ~user_tasks_t(); 47 | 48 | void accet_task(int task_id_); 49 | void complete_task(int task_id_); 50 | void modify_task(int task_id_, int value_); 51 | 52 | template 53 | void apply_change(const T& event_, bool new_change_ = true) 54 | { 55 | apply(event_); 56 | if (new_change_) 57 | { 58 | BUS.publish(event_); 59 | } 60 | } 61 | 62 | void apply(const task_accepted_t& event_); 63 | void apply(const task_completed_t& event_); 64 | void apply(const task_modified_t& event_); 65 | 66 | protected: 67 | task_set_t m_tasks; 68 | 69 | }; 70 | 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /example/cqrs/user/user.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_USER_H_ 3 | #define _FF_USER_H_ 4 | 5 | #include "task/user_task.h" 6 | 7 | namespace ff 8 | { 9 | class user_t 10 | { 11 | public: 12 | user_t(int64_t id_):m_uid(id_){} 13 | 14 | int64_t get_id() { return m_uid;} 15 | 16 | user_tasks_t& get_tasks() { return m_tasks; } 17 | private: 18 | int64_t m_uid; 19 | user_tasks_t m_tasks; 20 | }; 21 | 22 | }; 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /example/cqrs/user/user_mgr.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_USER_MGR_H_ 3 | #define _FF_USER_MGR_H_ 4 | 5 | #include "user/user.h" 6 | #include "base/singleton.h" 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | namespace ff 13 | { 14 | class user_mgr_t 15 | { 16 | public: 17 | user_t& get_user(int64_t id_) 18 | { 19 | map::iterator it = m_users.find(id_); 20 | if (it == m_users.end()) 21 | { 22 | throw runtime_error("none user"); 23 | } 24 | return *(it->second); 25 | } 26 | 27 | void add_user(user_t* user_) 28 | { 29 | m_users[user_->get_id()] = user_; 30 | } 31 | 32 | private: 33 | map m_users; 34 | }; 35 | 36 | 37 | #define USER_MGR singleton_t::instance() 38 | }; 39 | 40 | #endif 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /example/echo_client/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_echo_client 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/echo_client/include/msg_def.h: -------------------------------------------------------------------------------- 1 | //! 消息定义 2 | #ifndef _MSG_DEF_H_ 3 | #define _MSG_DEF_H_ 4 | 5 | #include "net/codec.h" 6 | 7 | using namespace ff; 8 | 9 | struct echo_t 10 | { 11 | struct in_t: public msg_i 12 | { 13 | in_t(): 14 | msg_i("echo_t::in_t") 15 | {} 16 | virtual string encode() 17 | { 18 | return (init_encoder() << value).get_buff(); 19 | } 20 | virtual void decode(const string& src_buff_) 21 | { 22 | init_decoder(src_buff_) >> value; 23 | } 24 | 25 | string value; 26 | }; 27 | struct out_t: public msg_i 28 | { 29 | out_t(): 30 | msg_i("echo_t::out_t") 31 | {} 32 | virtual string encode() 33 | { 34 | return (init_encoder() << value).get_buff(); 35 | } 36 | virtual void decode(const string& src_buff_) 37 | { 38 | init_decoder(src_buff_) >> value; 39 | } 40 | 41 | string value; 42 | }; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /example/echo_client/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "msg_def.h" 5 | #include "rpc/ffrpc.h" 6 | #include "log/log.h" 7 | 8 | using namespace ff; 9 | 10 | int g_count = 0; 11 | int g_index = 1; 12 | 13 | int main(int argc, char* argv[]) 14 | {/* 15 | map src;src[13] = "qqq";src[14] = "eee"; 16 | map dest; 17 | bin_encoder_t enc; 18 | bin_decoder_t dec; 19 | 20 | string str = (enc.init(100) << src).get_buff(); 21 | dec.init(str.substr(8)) >>dest; 22 | cout << dest.size() <<" " << dest[13] << " " << dest[14] << "\n"; 23 | return 0; 24 | */ 25 | if (argc > 1) 26 | { 27 | g_index = atoi(argv[1]); 28 | } 29 | char buff[128]; 30 | snprintf(buff, sizeof(buff), "tcp://%s:%s", "127.0.0.1", "10241"); 31 | 32 | assert(0 == singleton_t::instance().open(buff)); 33 | 34 | assert(singleton_t::instance().get_service_group("echo") && "echo service group not exist"); 35 | 36 | assert(singleton_t::instance().get_service_group("echo")->get_service(g_index) && "echo servie 1 not exist"); 37 | 38 | sleep(1); 39 | 40 | struct lambda_t 41 | { 42 | static void callback(echo_t::out_t& msg_) 43 | { 44 | if (g_count % 5000 == 0) 45 | { 46 | logwarn((FF, "%d, index[%d] echo callback msg value<%s>", g_index, g_count, msg_.value.c_str())); 47 | } 48 | 49 | if (++g_count > 500000) { 50 | //return; 51 | } 52 | 53 | echo_t::in_t in; 54 | in.value = "XXX_echo_test_XXX"; 55 | 56 | singleton_t::instance().get_service_group("echo")->get_service(g_index)->async_call(in, &lambda_t::callback); 57 | } 58 | 59 | }; 60 | 61 | for (int i = 0; i < 1; ++i) 62 | { 63 | echo_t::in_t in; 64 | in.value = "XXX_echo_test_XXX"; 65 | singleton_t::instance().get_service_group("echo")->get_service(g_index)->async_call(in, &lambda_t::callback); 66 | } 67 | 68 | signal_helper_t::wait(); 69 | singleton_t::instance().close(); 70 | cout <<"\noh end\n"; 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /example/echo_server/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_echo_server 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/echo_server/include/msg_def.h: -------------------------------------------------------------------------------- 1 | //! 消息定义 2 | #ifndef _MSG_DEF_H_ 3 | #define _MSG_DEF_H_ 4 | 5 | #include "net/codec.h" 6 | 7 | using namespace ff; 8 | 9 | struct echo_t 10 | { 11 | struct in_t: public msg_i 12 | { 13 | in_t(): 14 | msg_i("echo_t::in_t") 15 | {} 16 | virtual string encode() 17 | { 18 | return (init_encoder() << value).get_buff(); 19 | } 20 | virtual void decode(const string& src_buff_) 21 | { 22 | init_decoder(src_buff_) >> value; 23 | } 24 | 25 | string value; 26 | }; 27 | struct out_t: public msg_i 28 | { 29 | out_t(): 30 | msg_i("echo_t::out_t") 31 | {} 32 | virtual string encode() 33 | { 34 | return (init_encoder() << value).get_buff(); 35 | } 36 | virtual void decode(const string& src_buff_) 37 | { 38 | init_decoder(src_buff_) >> value; 39 | } 40 | 41 | string value; 42 | }; 43 | }; 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /example/echo_server/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "msg_def.h" 5 | #include "rpc/ffrpc.h" 6 | #include "log/log.h" 7 | 8 | using namespace ff; 9 | 10 | struct echo_service_t 11 | { 12 | public: 13 | void echo(echo_t::in_t& in_msg_, rpc_callcack_t& cb_) 14 | { 15 | logtrace((FF, "echo_service_t::echo done value<%s>", in_msg_.value.c_str())); 16 | echo_t::out_t out; 17 | out.value = in_msg_.value; 18 | cb_(out); 19 | } 20 | }; 21 | 22 | rpc_service_t* g_rpc_service = NULL; 23 | int main(int argc, char* argv[]) 24 | { 25 | int g_index = 1; 26 | if (argc > 1) 27 | { 28 | g_index = atoi(argv[1]); 29 | } 30 | char buff[128]; 31 | snprintf(buff, sizeof(buff), "tcp://%s:%s", "127.0.0.1", "10241"); 32 | 33 | ffrpc_t msg_bus; 34 | assert(0 == singleton_t::instance().open("tcp://127.0.0.1:10241") && "can't connnect to broker"); 35 | 36 | echo_service_t f; 37 | 38 | singleton_t::instance().create_service_group("echo"); 39 | singleton_t::instance().create_service("echo", g_index) 40 | .bind_service(&f) 41 | .reg(&echo_service_t::echo); 42 | 43 | signal_helper_t::wait(); 44 | 45 | singleton_t::instance().close(); 46 | //usleep(1000); 47 | cout <<"\noh end\n"; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /example/event_store/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_event_store 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/ext/generator ../../fflib/ext/algorithm/astar2 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext ../../fflib/ext/algorithm 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/event_store/include/entity.h: -------------------------------------------------------------------------------- 1 | #ifndef _ENTITY_I_H_ 2 | #define _ENTITY_I_H_ 3 | 4 | #include 5 | #include "serializer.h" 6 | 7 | class entity_i: public serializer_i 8 | { 9 | public: 10 | entity_i(uint64_t id_): 11 | m_id(id_) 12 | {} 13 | virtual ~entity_i(){} 14 | uint64_t id() const { return m_id; } 15 | 16 | protected: 17 | uint64_t m_id; 18 | }; 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /example/event_store/include/event.h: -------------------------------------------------------------------------------- 1 | #ifndef _EVENT_I_H_ 2 | #define _EVENT_I_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "serializer.h" 8 | 9 | class event_i: public serializer_i 10 | { 11 | public: 12 | virtual ~event_i(){} 13 | }; 14 | 15 | class event_dispather_i 16 | { 17 | public: 18 | ~event_dispather_i(){} 19 | virtual int dispath(const string& json_) = 0; 20 | }; 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /example/event_store/include/event_store.h: -------------------------------------------------------------------------------- 1 | #ifndef _EVENT_STORE_I_H_ 2 | #define _EVENT_STORE_I_H_ 3 | 4 | #include 5 | 6 | #include "event.h" 7 | #include "entity.h" 8 | 9 | class event_store_i 10 | { 11 | public: 12 | virtual ~event_store_i(){} 13 | 14 | virtual int save_event(uint64_t entity_id_, const event_i& event_) = 0; 15 | virtual int snapshot_entity(const entity_i& entity_) = 0; 16 | virtual int constuct_snapshot_last(entity_i& entity_, event_dispather_i& event_dispacher_, int version_ = 1) = 0; 17 | }; 18 | #endif 19 | 20 | 21 | -------------------------------------------------------------------------------- /example/event_store/include/impl/entity_user.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _ENTITY_USER_H 3 | #define _ENTITY_USER_H 4 | 5 | #include "entity.h" 6 | #include "impl/event_def.h" 7 | #include "event_store.h" 8 | 9 | class entity_user_t: public entity_i 10 | { 11 | public: 12 | entity_user_t(uint64_t id_, event_store_i* event_store_); 13 | int inc_gold(int32_t gold_); 14 | int inc_level(int32_t level_); 15 | 16 | virtual int decode(const json_value_t& jval_); 17 | virtual string encode() const; 18 | public: 19 | void apply(const inc_gold_event_t& event_); 20 | void apply(const inc_level_event_t& event_); 21 | private: 22 | int32_t m_gold; 23 | int32_t m_level; 24 | event_store_i* m_event_store; 25 | }; 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /example/event_store/include/impl/event_store_mem.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EVENT_STORE_MEM_H_ 3 | #define _EVENT_STORE_MEM_H_ 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #include "event_store.h" 10 | 11 | class event_store_mem_t: public event_store_i 12 | { 13 | typedef vector event_record_t; 14 | typedef map entity_event_map_t; 15 | 16 | struct snapshot_info_t 17 | { 18 | long event_version; 19 | string data; 20 | }; 21 | typedef vector entity_record_t; 22 | typedef mapentity_snapshot_map_t; 23 | public: 24 | event_store_mem_t(); 25 | ~ event_store_mem_t(); 26 | 27 | int save_event(uint64_t entity_id_, const event_i& event_); 28 | int snapshot_entity(const entity_i& entity_); 29 | int constuct_snapshot_last(entity_i& entity_, event_dispather_i& event_dispacher_, int version_ = 1); 30 | 31 | private: 32 | entity_event_map_t m_entity_events; 33 | entity_snapshot_map_t m_entity_snapshot; 34 | }; 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /example/event_store/include/serializer.h: -------------------------------------------------------------------------------- 1 | #ifndef _SERIALIZER_I_H_ 2 | #define _SERIALIZER_I_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "rapidjson/document.h" // rapidjson's DOM-style API 8 | #include "rapidjson/prettywriter.h" // for stringify JSON 9 | #include "rapidjson/filestream.h" // wrapper of C stream for prettywriter as output 10 | #include "rapidjson/stringbuffer.h" 11 | #include "generator/json_instream.h" 12 | #include "generator/json_outstream.h" 13 | 14 | typedef runtime_error msg_exception_t; 15 | typedef rapidjson::Document json_dom_t; 16 | typedef rapidjson::Value json_value_t; 17 | class serializer_i 18 | { 19 | public: 20 | virtual ~serializer_i(){} 21 | virtual int decode(const json_value_t& jval_) = 0; 22 | virtual string encode() const = 0; 23 | }; 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /example/event_store/src/entity_user.cpp: -------------------------------------------------------------------------------- 1 | #include "impl/entity_user.h" 2 | 3 | entity_user_t::entity_user_t(uint64_t id_, event_store_i* e_): 4 | entity_i(id_), 5 | m_gold(0), 6 | m_level(0), 7 | m_event_store(e_) 8 | { 9 | event_dispather_t event_dispacher(*this); 10 | m_event_store->constuct_snapshot_last(*this, event_dispacher); 11 | } 12 | 13 | int entity_user_t::inc_gold(int32_t gold_) 14 | { 15 | if (gold_ <= 0) 16 | return -1; 17 | inc_gold_event_t event(gold_); 18 | apply(event); 19 | m_event_store->save_event(this->id(), event); 20 | return 0; 21 | } 22 | 23 | int entity_user_t::inc_level(int32_t level_) 24 | { 25 | if (level_ <= 0) 26 | return -1; 27 | inc_level_event_t event(level_); 28 | apply(event); 29 | m_event_store->save_event(this->id(), event); 30 | m_event_store->snapshot_entity(*this); 31 | return 0; 32 | } 33 | 34 | int entity_user_t::decode(const json_value_t& jval_) 35 | { 36 | json_instream_t in("inc_gold_event_t"); 37 | in.decode("m_gold", jval_["m_gold"], m_gold).decode("m_level", jval_["m_level"], m_level); 38 | return 0; 39 | } 40 | 41 | string entity_user_t::encode() const 42 | { 43 | rapidjson::Document::AllocatorType allocator; 44 | rapidjson::StringBuffer str_buff; 45 | json_value_t ibj_json(rapidjson::kObjectType); 46 | json_value_t ret_json(rapidjson::kObjectType); 47 | 48 | json_outstream_t out(allocator); 49 | out.encode("m_gold", ibj_json, m_gold).encode("m_level", ibj_json, m_level); 50 | ret_json.AddMember("entity_user_t", ibj_json, allocator); 51 | 52 | rapidjson::Writer writer(str_buff, &allocator); 53 | ret_json.Accept(writer); 54 | string output(str_buff.GetString(), str_buff.GetSize()); 55 | return output; 56 | } 57 | 58 | void entity_user_t::apply(const inc_gold_event_t& event_) 59 | { 60 | m_gold += event_.gold; 61 | } 62 | 63 | void entity_user_t::apply(const inc_level_event_t& event_) 64 | { 65 | m_level += event_.level; 66 | } 67 | -------------------------------------------------------------------------------- /example/event_store/src/event_store_mem.cpp: -------------------------------------------------------------------------------- 1 | #include "impl/event_store_mem.h" 2 | 3 | event_store_mem_t::event_store_mem_t() 4 | { 5 | 6 | } 7 | 8 | event_store_mem_t::~event_store_mem_t() 9 | { 10 | 11 | } 12 | 13 | int event_store_mem_t::save_event(uint64_t entity_id_, const event_i& event_) 14 | { 15 | m_entity_events[entity_id_].push_back(event_.encode()); 16 | return 0; 17 | } 18 | 19 | int event_store_mem_t::snapshot_entity(const entity_i& entity_) 20 | { 21 | snapshot_info_t info; 22 | info.event_version = m_entity_events[entity_.id()].size(); 23 | info.data = entity_.encode(); 24 | m_entity_snapshot[entity_.id()].push_back(info); 25 | return 0; 26 | } 27 | 28 | int event_store_mem_t::constuct_snapshot_last(entity_i& entity_, event_dispather_i& event_dispacher_, int version_) 29 | { 30 | int index = m_entity_snapshot.size() - version_; 31 | if (index >=0 && index < (int)m_entity_snapshot.size()) 32 | { 33 | snapshot_info_t& info = m_entity_snapshot[entity_.id()][index]; 34 | 35 | json_dom_t document; 36 | if (document.Parse<0>(info.data.c_str()).HasParseError()) 37 | { 38 | throw msg_exception_t("json format not right"); 39 | } 40 | if (false == document.IsObject() && false == document.Empty()) 41 | { 42 | throw msg_exception_t("json must has one field"); 43 | } 44 | 45 | entity_.decode(document.MemberBegin()->value); 46 | 47 | for (size_t i = info.event_version; i < m_entity_events[entity_.id()].size(); ++i) 48 | { 49 | event_dispacher_.dispath(m_entity_events[entity_.id()][i]); 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /example/event_store/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "impl/entity_user.h" 5 | #include "impl/event_store_mem.h" 6 | 7 | int main(int argc, char* argv[]) 8 | { 9 | event_store_mem_t event_store; 10 | { 11 | entity_user_t entity_user(1122334, &event_store); 12 | entity_user.inc_gold(100); 13 | entity_user.inc_level(100); 14 | cout <<"user 1:" << entity_user.encode() <<"\n"; 15 | } 16 | { 17 | entity_user_t entity_user(1122334, &event_store); 18 | cout <<"user 2:" << entity_user.encode() <<"\n"; 19 | entity_user.inc_gold(100); 20 | entity_user.inc_level(100); 21 | cout <<"user 3:" << entity_user.encode() <<"\n"; 22 | } 23 | entity_user_t entity_user(1122334, &event_store); 24 | cout <<"user 4:" << entity_user.encode() <<"\n"; 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /example/ff_performance/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_perf 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/game_framework/Makefile: -------------------------------------------------------------------------------- 1 | 2 | .PHONY:all 3 | 4 | all: 5 | make -C client && make -C gateway &&make -C logic &&make -C manager 6 | 7 | clean: 8 | make clean -C client 9 | make clean -C gateway 10 | make clean -C logic 11 | make clean -C manager 12 | -------------------------------------------------------------------------------- /example/game_framework/client/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_client 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ../common_include ./include ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/game_framework/client/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "logic_msg_def.h" 5 | #include "rpc/ffrpc.h" 6 | #include "log/log.h" 7 | 8 | using namespace ff; 9 | 10 | struct login_t 11 | { 12 | struct in_t: public client_msg_i 13 | { 14 | in_t(): 15 | client_msg_i("login_t::in_t") 16 | {} 17 | virtual string encode() 18 | { 19 | return (init_encoder() << uid << passwd).get_buff(); 20 | } 21 | virtual void decode(const string& src_buff_) 22 | { 23 | init_decoder(src_buff_) >> uid >> passwd; 24 | } 25 | 26 | long uid; 27 | string passwd; 28 | }; 29 | struct out_t: public client_msg_i 30 | { 31 | out_t(): 32 | client_msg_i("login_t::out_t") 33 | {} 34 | virtual string encode() 35 | { 36 | return (init_encoder() << uid).get_buff(); 37 | } 38 | virtual void decode(const string& src_buff_) 39 | { 40 | init_decoder(src_buff_) >> uid; 41 | } 42 | 43 | long uid; 44 | }; 45 | }; 46 | 47 | class client_service_t: public msg_handler_i 48 | { 49 | int handle_broken(socket_ptr_t sock_) 50 | { 51 | cout <<"client_service_t::handle_broken\n"; 52 | return 0; 53 | } 54 | int handle_msg(const message_t& msg_, socket_ptr_t sock_) 55 | { 56 | cout <<"client_service_t::handle_msg\n"; 57 | return 0; 58 | } 59 | 60 | }; 61 | 62 | int main(int argc, char* argv[]) 63 | { 64 | char buff[128]; 65 | snprintf(buff, sizeof(buff), "tcp://%s:%s", "127.0.0.1", "20241"); 66 | 67 | 68 | client_service_t client_service; 69 | socket_ptr_t socket_ptr = net_factory_t::connect(buff, &client_service); 70 | 71 | assert(socket_ptr); 72 | login_t::in_t in; 73 | in.uid = 123; 74 | msg_sender_t::send(socket_ptr, 0, in); 75 | 76 | signal_helper_t::wait(); 77 | singleton_t::instance().close(); 78 | cout <<"\noh end\n"; 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /example/game_framework/common_include/logic_msg_def.h: -------------------------------------------------------------------------------- 1 | //! 消息定义 2 | #ifndef _LOGIC_MSG_DEF_H_ 3 | #define _LOGIC_MSG_DEF_H_ 4 | 5 | #include "net/codec.h" 6 | 7 | using namespace ff; 8 | 9 | struct user_login_t: public client_msg_i 10 | { 11 | user_login_t(): 12 | client_msg_i("user_login_t") 13 | {} 14 | virtual string encode() 15 | { 16 | return (init_encoder() << uid).get_buff(); 17 | } 18 | virtual void decode(const string& src_buff_) 19 | { 20 | init_decoder(src_buff_) >> uid; 21 | } 22 | 23 | long uid; 24 | }; 25 | 26 | struct user_logout_t: public client_msg_i 27 | { 28 | user_logout_t(): 29 | client_msg_i("user_login_t") 30 | {} 31 | virtual string encode() 32 | { 33 | return (init_encoder() << uid).get_buff(); 34 | } 35 | virtual void decode(const string& src_buff_) 36 | { 37 | init_decoder(src_buff_) >> uid; 38 | } 39 | 40 | long uid; 41 | }; 42 | #endif 43 | -------------------------------------------------------------------------------- /example/game_framework/gateway/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_gateway 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ../common_include ./include ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/game_framework/gateway/include/gateway_service.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _GATEWAY_SERVICE_H_ 3 | #define _GATEWAY_SERVICE_H_ 4 | 5 | #include "common_msg_def.h" 6 | 7 | #include "rpc/gateway_service_i.h" 8 | #include "rpc/ffrpc.h" 9 | 10 | namespace ff { 11 | 12 | class gateway_service_t: public gateway_service_i 13 | { 14 | public: 15 | struct client_session_t 16 | { 17 | client_session_t():uid(0){} 18 | long uid; 19 | }; 20 | public: 21 | gateway_service_t(); 22 | ~gateway_service_t(); 23 | 24 | virtual int handle_login(gate_msg_tool_t& msg_, socket_ptr_t sock_); 25 | virtual int handle_logout(socket_ptr_t sock_); 26 | virtual int handle_common_logic(gate_msg_tool_t& msg_, socket_ptr_t sock_); 27 | 28 | int add_user(long uid_, socket_ptr_t sock_); 29 | int del_user(long uid_); 30 | 31 | //! gateway 如何定义接口给 logic server 和 manager server ?? 32 | virtual int unicast(unicast_t::in_t& msg_, rpc_callcack_t& cb_); 33 | virtual int broadcast(broadcast_t::in_t& msg_, rpc_callcack_t& cb_); 34 | private: 35 | map m_all_clients; 36 | }; 37 | 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /example/game_framework/gateway/perf.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanchy/fflib/ee6a1ba918b444ceb5e86a25dbf7c4a236494709/example/game_framework/gateway/perf.txt -------------------------------------------------------------------------------- /example/game_framework/gateway/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "common_msg_def.h" 5 | #include "rpc/ffrpc.h" 6 | #include "log/log.h" 7 | 8 | #include "gateway_service.h" 9 | #include "rpc/broker_application.h" 10 | 11 | using namespace ff; 12 | 13 | /* 14 | login_t::in_t in; 15 | in.uid = 100; 16 | in.set_gate(); 17 | in.passwd = "Xxvefds"; 18 | 19 | string data = in.encode(); 20 | gate_msg_tool_t msg_tool; 21 | msg_tool.gate_decode(data.substr(8)); 22 | 23 | login_t::in_t foo; 24 | foo.decode(msg_tool.encode().substr(8)); 25 | 26 | cout << msg_tool.get_name() <<" " << foo.uid << " " << foo.passwd <<"\n"; 27 | return 0; 28 | */ 29 | int main(int argc, char* argv[]) 30 | { 31 | broker_application_t::run(argc, argv); 32 | 33 | char buff[128]; 34 | snprintf(buff, sizeof(buff), "tcp://%s:%s", "127.0.0.1", "10241"); 35 | 36 | assert(0 == singleton_t::instance().open(buff)); 37 | 38 | gateway_service_t gateway_service; 39 | singleton_t::instance().create_service_group("gateway"); 40 | singleton_t::instance().create_service("gateway", 0) 41 | .bind_service(&gateway_service) 42 | .reg(&gateway_service_t::unicast) 43 | .reg(&gateway_service_t::broadcast); 44 | 45 | 46 | net_factory_t::gateway_listen("-gateway_listen tcp://127.0.0.1:20241", &gateway_service); 47 | 48 | signal_helper_t::wait(); 49 | singleton_t::instance().close(); 50 | cout <<"\noh end\n"; 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /example/game_framework/logic/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_logic 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs ../../../fflib/gtest/src impl/task 19 | #头文件目录 20 | IncDir= ../common_include ./include ../../../fflib/ ../../../fflib/ext ./impl/ ../../../fflib/gtest/include ../../../fflib/gtest 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/command/task_command.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_TASK_COMMAND_H_ 3 | #define _FF_TASK_COMMAND_H_ 4 | 5 | #include "cqrs/command_i.h" 6 | 7 | namespace ff 8 | { 9 | 10 | class accept_task_cmd_t: public user_command_t 11 | { 12 | public: 13 | virtual void enc() 14 | { 15 | encoder() << tid; 16 | } 17 | virtual void dec() 18 | { 19 | decoder() >> tid; 20 | } 21 | 22 | uint32_t tid; 23 | }; 24 | 25 | class complete_task_cmd_t: public user_command_t 26 | { 27 | public: 28 | virtual void enc() 29 | { 30 | encoder() << tid; 31 | } 32 | virtual void dec() 33 | { 34 | decoder() >> tid; 35 | } 36 | 37 | uint32_t tid; 38 | }; 39 | 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/task/event_def.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EVENT_DEF_I_ 3 | #define _EVENT_DEF_I_ 4 | 5 | #include "cqrs/event_i.h" 6 | 7 | namespace ff 8 | { 9 | 10 | class task_accepted_t: public event_t 11 | { 12 | public: 13 | task_accepted_t(int task_id_ =0, int dest_value_ = 0): 14 | task_id(task_id_), 15 | dest_value(dest_value_) 16 | {} 17 | int task_id; 18 | int dest_value; 19 | }; 20 | 21 | class task_completed_t: public event_t 22 | { 23 | public: 24 | task_completed_t(int tid_): 25 | task_id(tid_) 26 | {} 27 | int task_id; 28 | }; 29 | 30 | class task_modified_t: public event_t 31 | { 32 | public: 33 | task_modified_t(int tid_, int value_): 34 | task_id(tid_), 35 | value(value_) 36 | {} 37 | int task_id; 38 | int value; 39 | }; 40 | 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/task/task_service.cpp: -------------------------------------------------------------------------------- 1 | #include "task_service.h" 2 | #include "command/task_command.h" 3 | #include "cqrs/bus_i.h" 4 | 5 | #include "user/user_mgr.h" 6 | using namespace ff; 7 | 8 | #include 9 | using namespace std; 10 | 11 | task_service_t::task_service_t() 12 | { 13 | } 14 | 15 | task_service_t::~task_service_t() 16 | { 17 | } 18 | 19 | int task_service_t::start() 20 | { 21 | subscriber_t subscriber; 22 | subscriber.reg(this) 23 | .reg(this); 24 | BUS.subscribe(subscriber); 25 | return 0; 26 | } 27 | 28 | int task_service_t::stop() 29 | { 30 | return 0; 31 | } 32 | 33 | void task_service_t::handle(const accept_task_cmd_t& cmd_) 34 | { 35 | cout <<"accept_task_cmd_t " << cmd_.tid << " xx\n"; 36 | USER_MGR.get_user(cmd_.uid).get_tasks().accet_task(cmd_.tid); 37 | } 38 | 39 | void task_service_t::handle(const complete_task_cmd_t& cmd_) 40 | { 41 | USER_MGR.get_user(cmd_.uid).get_tasks().complete_task(cmd_.tid); 42 | } 43 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/task/task_service.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_TASK_SERVICE_H_ 3 | #define _FF_TASK_SERVICE_H_ 4 | 5 | #include "base/singleton.h" 6 | 7 | namespace ff 8 | { 9 | class accept_task_cmd_t; 10 | class complete_task_cmd_t; 11 | 12 | class task_service_t 13 | { 14 | public: 15 | task_service_t(); 16 | ~task_service_t(); 17 | 18 | int start(); 19 | int stop(); 20 | 21 | void handle(const accept_task_cmd_t& cmd_); 22 | void handle(const complete_task_cmd_t& cmd_); 23 | }; 24 | 25 | #define TASK_SERVICE singleton_t::instance() 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/task/test_task.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanchy/fflib/ee6a1ba918b444ceb5e86a25dbf7c4a236494709/example/game_framework/logic/impl/task/test_task.h -------------------------------------------------------------------------------- /example/game_framework/logic/impl/task/user_task.cpp: -------------------------------------------------------------------------------- 1 | #include "user_task.h" 2 | #include "event_def.h" 3 | 4 | using namespace ff; 5 | #include 6 | using namespace std; 7 | 8 | user_tasks_t::user_tasks_t() 9 | {} 10 | 11 | user_tasks_t::~user_tasks_t() 12 | {} 13 | 14 | void user_tasks_t::accet_task(int task_id_) 15 | { 16 | if (m_tasks.find(task_id_) != m_tasks.end()) throw task_exception_t("tid exist"); 17 | apply_change(task_accepted_t(task_id_, 100)); 18 | } 19 | 20 | void user_tasks_t::complete_task(int task_id_) 21 | { 22 | task_set_t::iterator it = m_tasks.find(task_id_); 23 | 24 | if (it == m_tasks.end()) throw task_exception_t("tid not exist"); 25 | if (it->second.current_value < it->second.dest_value) throw task_exception_t("not completed"); 26 | 27 | apply_change(task_completed_t(task_id_)); 28 | } 29 | 30 | void user_tasks_t::modify_task(int task_id_, int value_) 31 | { 32 | task_set_t::iterator it = m_tasks.find(task_id_); 33 | 34 | if (it == m_tasks.end()) throw task_exception_t("tid not exist"); 35 | if (it->second.status != TASK_ACCEPTED) throw task_exception_t("status invalid"); 36 | 37 | apply_change(task_modified_t(task_id_, value_)); 38 | } 39 | 40 | void user_tasks_t::apply(const task_accepted_t& event_) 41 | { 42 | task_ino_t task_info(event_.task_id, event_.dest_value, TASK_ACCEPTED); 43 | m_tasks.insert(make_pair(event_.task_id, task_info)); 44 | } 45 | 46 | void user_tasks_t::apply(const task_completed_t& event_) 47 | { 48 | m_tasks[event_.task_id].status = TASK_COMPLETED; 49 | } 50 | 51 | void user_tasks_t::apply(const task_modified_t& event_) 52 | { 53 | m_tasks[event_.task_id].current_value += event_.value; 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/task/user_task.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _USER_TASKS_I_ 3 | #define _USER_TASKS_I_ 4 | 5 | #include "cqrs/aggregate_root_i.h" 6 | #include "cqrs/bus_i.h" 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | namespace ff 13 | { 14 | 15 | class task_accepted_t; 16 | class task_completed_t; 17 | class task_modified_t; 18 | 19 | class user_tasks_t: public aggregate_root_i 20 | { 21 | public: 22 | typedef runtime_error task_exception_t; 23 | enum task_status_e 24 | { 25 | TASK_UNACCEPTED, 26 | TASK_ACCEPTED, 27 | TASK_COMPLETED, 28 | }; 29 | struct task_ino_t 30 | { 31 | task_ino_t(int tid = 0, int dest_value_ = 0, int status_ = TASK_UNACCEPTED): 32 | task_id(tid), 33 | status(status_), 34 | current_value(0), 35 | dest_value(dest_value_) 36 | {} 37 | 38 | int task_id; 39 | int status; 40 | int current_value; 41 | int dest_value; 42 | }; 43 | typedef map task_set_t; 44 | public: 45 | user_tasks_t(); 46 | ~user_tasks_t(); 47 | 48 | void accet_task(int task_id_); 49 | void complete_task(int task_id_); 50 | void modify_task(int task_id_, int value_); 51 | 52 | template 53 | void apply_change(const T& event_, bool new_change_ = true) 54 | { 55 | apply(event_); 56 | if (new_change_) 57 | { 58 | BUS.publish(event_); 59 | } 60 | } 61 | 62 | void apply(const task_accepted_t& event_); 63 | void apply(const task_completed_t& event_); 64 | void apply(const task_modified_t& event_); 65 | 66 | protected: 67 | task_set_t m_tasks; 68 | 69 | }; 70 | 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/user/user.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_USER_H_ 3 | #define _FF_USER_H_ 4 | 5 | #include "task/user_task.h" 6 | 7 | namespace ff 8 | { 9 | class user_t 10 | { 11 | public: 12 | user_t(int64_t id_):m_uid(id_){} 13 | 14 | int64_t get_id() { return m_uid;} 15 | 16 | user_tasks_t& get_tasks() { return m_tasks; } 17 | private: 18 | int64_t m_uid; 19 | user_tasks_t m_tasks; 20 | }; 21 | 22 | }; 23 | 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /example/game_framework/logic/impl/user/user_mgr.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_USER_MGR_H_ 3 | #define _FF_USER_MGR_H_ 4 | 5 | #include "user/user.h" 6 | #include "base/singleton.h" 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | namespace ff 13 | { 14 | class user_mgr_t 15 | { 16 | public: 17 | user_t& get_user(int64_t id_) 18 | { 19 | map::iterator it = m_users.find(id_); 20 | if (it == m_users.end()) 21 | { 22 | throw runtime_error("none user"); 23 | } 24 | return *(it->second); 25 | } 26 | 27 | void add_user(user_t* user_) 28 | { 29 | m_users[user_->get_id()] = user_; 30 | } 31 | 32 | void del_user(int64_t uid_) 33 | { 34 | m_users.erase(uid_); 35 | } 36 | private: 37 | map m_users; 38 | }; 39 | 40 | 41 | #define USER_MGR singleton_t::instance() 42 | }; 43 | 44 | #endif 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/game_framework/logic/include/logic_service.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _MANAGER_SERVICE_H_ 3 | #define _MANAGER_SERVICE_H_ 4 | 5 | #include "common_msg_def.h" 6 | #include "rpc/ffrpc.h" 7 | 8 | namespace ff { 9 | 10 | class logic_service_t 11 | { 12 | public: 13 | struct client_session_t 14 | { 15 | client_session_t():gwid(0){} 16 | long gwid; 17 | }; 18 | public: 19 | logic_service_t(); 20 | ~logic_service_t(); 21 | 22 | virtual int login(login_t::in_t& msg_, rpc_callcack_t& cb_); 23 | virtual int logout(logout_t::in_t& msg_, rpc_callcack_t& cb_); 24 | virtual int common_msg(common_msg_t::in_t& msg_, rpc_callcack_t& cb_); 25 | private: 26 | map m_all_clients; 27 | }; 28 | 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /example/game_framework/logic/src/logic_service.cpp: -------------------------------------------------------------------------------- 1 | #include "logic_service.h" 2 | #include "rpc/ffrpc.h" 3 | #include "common_msg_def.h" 4 | #include "logic_msg_def.h" 5 | #include "rpc/rpc_callback.h" 6 | #include "net/msg_sender.h" 7 | #include "user/user_mgr.h" 8 | #include "cqrs/bus_i.h" 9 | using namespace ff; 10 | 11 | logic_service_t::logic_service_t() 12 | { 13 | 14 | } 15 | 16 | logic_service_t::~logic_service_t() 17 | { 18 | 19 | } 20 | 21 | int logic_service_t::login(login_t::in_t& msg_, rpc_callcack_t& cb_) 22 | { 23 | USER_MGR.add_user(new user_t(msg_.uid)); 24 | login_t::out_t ret; 25 | cb_(ret); 26 | 27 | struct lambda_t 28 | { 29 | static void callback(broadcast_t::out_t& msg_) 30 | { 31 | } 32 | }; 33 | 34 | 35 | user_login_t notify_msg; 36 | notify_msg.uid = msg_.uid; 37 | 38 | broadcast_t::in_t broadcast; 39 | broadcast.content = notify_msg.encode(); 40 | 41 | singleton_t::instance().get_service_group("gateway") 42 | ->get_service(0) 43 | ->async_call(broadcast, &lambda_t::callback); 44 | 45 | return 0; 46 | } 47 | 48 | int logic_service_t::logout(logout_t::in_t& msg_, rpc_callcack_t& cb_) 49 | { 50 | USER_MGR.del_user(msg_.uid); 51 | logout_t::out_t ret; 52 | cb_(ret); 53 | 54 | struct lambda_t 55 | { 56 | static void callback(logout_t::out_t& msg_) 57 | { 58 | } 59 | }; 60 | 61 | user_logout_t notify_msg; 62 | notify_msg.uid = msg_.uid; 63 | 64 | broadcast_t::in_t broadcast; 65 | broadcast.content = notify_msg.encode(); 66 | 67 | singleton_t::instance().get_service_group("gateway") 68 | ->get_service(0) 69 | ->async_call(broadcast, &lambda_t::callback); 70 | return 0; 71 | } 72 | 73 | int logic_service_t::common_msg(common_msg_t::in_t& msg_, rpc_callcack_t& cb_) 74 | { 75 | common_msg_t::out_t ret; 76 | cb_(ret); 77 | 78 | uint32_t* len = (uint32_t*)(msg_.content.c_str()); 79 | string name(msg_.content.c_str()+4, *len); 80 | BUS.publish(name, msg_.content); 81 | return 0; 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /example/game_framework/logic/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "common_msg_def.h" 5 | #include "rpc/ffrpc.h" 6 | #include "log/log.h" 7 | 8 | #include "logic_service.h" 9 | 10 | #include "cqrs/bus_i.h" 11 | #include "user/user_mgr.h" 12 | #include "command/task_command.h" 13 | #include "task/task_service.h" 14 | #include "task/test_task.h" 15 | 16 | using namespace ff; 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | char buff[128]; 21 | snprintf(buff, sizeof(buff), "tcp://%s:%s", "127.0.0.1", "10241"); 22 | 23 | assert(0 == singleton_t::instance().open(buff)); 24 | 25 | logic_service_t logic_service; 26 | TASK_SERVICE.start(); 27 | 28 | singleton_t::instance().create_service_group("logic"); 29 | singleton_t::instance().create_service("logic", 0) 30 | .bind_service(&logic_service) 31 | .reg(&logic_service_t::login) 32 | .reg(&logic_service_t::logout) 33 | .reg(&logic_service_t::common_msg); 34 | 35 | 36 | signal_helper_t::wait(); 37 | singleton_t::instance().close(); 38 | cout <<"\noh end\n"; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /example/game_framework/manager/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_manager 16 | 17 | #源文件目录 18 | SrcDir= . src ../../../fflib/base ../../../fflib/net ../../../fflib/rpc ../../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ../common_include ./include ../../../fflib/ ../../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/game_framework/manager/include/manager_service.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _MANAGER_SERVICE_H_ 3 | #define _MANAGER_SERVICE_H_ 4 | 5 | #include "common_msg_def.h" 6 | #include "rpc/ffrpc.h" 7 | 8 | namespace ff { 9 | 10 | class manager_service_t 11 | { 12 | public: 13 | struct client_session_t 14 | { 15 | client_session_t():gwid(0){} 16 | long gwid; 17 | }; 18 | public: 19 | manager_service_t(); 20 | ~manager_service_t(); 21 | 22 | virtual int login(login_t::in_t& msg_, rpc_callcack_t& cb_); 23 | virtual int logout(logout_t::in_t& msg_, rpc_callcack_t& cb_); 24 | private: 25 | map m_all_clients; 26 | }; 27 | 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /example/game_framework/manager/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #include "common_msg_def.h" 5 | #include "rpc/ffrpc.h" 6 | #include "log/log.h" 7 | 8 | #include "manager_service.h" 9 | 10 | using namespace ff; 11 | 12 | int main(int argc, char* argv[]) 13 | { 14 | char buff[128]; 15 | snprintf(buff, sizeof(buff), "tcp://%s:%s", "127.0.0.1", "10241"); 16 | 17 | assert(0 == singleton_t::instance().open(buff)); 18 | 19 | manager_service_t manager_service; 20 | singleton_t::instance().create_service_group("manager"); 21 | singleton_t::instance().create_service("manager", 0) 22 | .bind_service(&manager_service) 23 | .reg(&manager_service_t::login) 24 | .reg(&manager_service_t::logout); 25 | 26 | 27 | signal_helper_t::wait(); 28 | singleton_t::instance().close(); 29 | cout <<"\noh end\n"; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /example/game_framework/manager/src/manager_service.cpp: -------------------------------------------------------------------------------- 1 | #include "manager_service.h" 2 | #include "rpc/ffrpc.h" 3 | #include "common_msg_def.h" 4 | #include "rpc/rpc_callback.h" 5 | #include "net/msg_sender.h" 6 | 7 | using namespace ff; 8 | 9 | manager_service_t::manager_service_t() 10 | { 11 | 12 | } 13 | 14 | manager_service_t::~manager_service_t() 15 | { 16 | 17 | } 18 | 19 | int manager_service_t::login(login_t::in_t& msg_, rpc_callcack_t& cb_) 20 | { 21 | m_all_clients[msg_.uid]; 22 | login_t::out_t ret; 23 | cb_(ret); 24 | 25 | struct lambda_t 26 | { 27 | static void callback(login_t::out_t& msg_) 28 | { 29 | } 30 | }; 31 | 32 | singleton_t::instance().get_service_group("logic") 33 | ->get_service(0) 34 | ->async_call(msg_, &lambda_t::callback); 35 | 36 | return 0; 37 | } 38 | 39 | int manager_service_t::logout(logout_t::in_t& msg_, rpc_callcack_t& cb_) 40 | { 41 | m_all_clients.erase(msg_.uid); 42 | logout_t::out_t ret; 43 | cb_(ret); 44 | 45 | struct lambda_t 46 | { 47 | static void callback(logout_t::out_t& msg_) 48 | { 49 | } 50 | }; 51 | 52 | singleton_t::instance().get_service_group("logic") 53 | ->get_service(0) 54 | ->async_call(msg_, &lambda_t::callback); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /example/perf/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_perf 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall -DLUA_USE_READLINE 7 | LDFLAGS= -export-dynamic -lpthread -ldl -lpython2.6 -llua 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=msg_broker_server 16 | 17 | #源文件目录 18 | SrcDir= . ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs ../../fflib/gtest/src ./src src/plugin_impl ../../fflib/ext/generator 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext/ ../../fflib/ext/generator /usr/include/python2.6/ /usr/local/include/ ../../fflib/gtest/include ../../fflib/gtest/ 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/channel.h: -------------------------------------------------------------------------------- 1 | #ifndef _CHANNEL_H_ 2 | #define _CHANNEL_H_ 3 | 4 | #include "net/socket_i.h" 5 | 6 | using namespace ff; 7 | 8 | class channel_t 9 | { 10 | public: 11 | channel_t(socket_ptr_t sock_); 12 | ~channel_t(); 13 | void set_data(void* p); 14 | void* get_data() const; 15 | 16 | template 17 | T* get_data() const { return (T*)this->get_data(); } 18 | 19 | void async_send(const string& buff_); 20 | void close(); 21 | 22 | private: 23 | socket_ptr_t m_socket; 24 | void* m_data; 25 | }; 26 | 27 | typedef channel_t* channel_ptr_t; 28 | #endif 29 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/log_module.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOG_MODULE_H_ 2 | #define _LOG_MODULE_H_ 3 | 4 | #include "log/log.h" 5 | 6 | #define BROKER_SERVICE "BROKER_SERVICE" 7 | #define PLUGIN_IMPL "PLUGIN_IMPL" 8 | #endif 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/msg_broker_service.h: -------------------------------------------------------------------------------- 1 | #ifndef _MSG_BROKER_SERVICE_H_ 2 | #define _MSG_BROKER_SERVICE_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "net/socket_i.h" 8 | #include "net/msg_handler_i.h" 9 | #include "plugin_i.h" 10 | 11 | using namespace ff; 12 | 13 | class msg_broker_service_t: public msg_handler_i 14 | { 15 | public: 16 | msg_broker_service_t(); 17 | ~msg_broker_service_t(); 18 | 19 | int handle_broken(socket_ptr_t sock_); 20 | int handle_msg(const message_t& msg_, socket_ptr_t sock_); 21 | 22 | int start(const string& path_); 23 | int stop(); 24 | 25 | private: 26 | plugin_ptr_t m_plugin; 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/plugin_factory.h: -------------------------------------------------------------------------------- 1 | #ifndef _PLUGIN_FACTORY_H_ 2 | #define _PLUGIN_FACTORY_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "plugin_i.h" 8 | 9 | using namespace ff; 10 | 11 | class plugin_factory_t 12 | { 13 | public: 14 | static plugin_ptr_t create_plugin(const string& path_); 15 | }; 16 | #endif 17 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/plugin_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _PLUGIN_H_ 2 | #define _PLUGIN_H_ 3 | 4 | #include "channel.h" 5 | #include "net/message.h" 6 | 7 | using namespace ff; 8 | 9 | class plugin_i 10 | { 11 | public: 12 | virtual ~plugin_i(){} 13 | virtual int start() = 0; 14 | virtual int stop() = 0; 15 | 16 | virtual int handle_broken(channel_ptr_t channel_) = 0; 17 | virtual int handle_msg(const message_t& msg_, channel_ptr_t channel_) = 0; 18 | }; 19 | 20 | typedef plugin_i* plugin_ptr_t; 21 | typedef int (*handle_channel_msg_func_t)(const message_t& msg_, channel_ptr_t); 22 | typedef int (*handle_channel_broken_func_t)(channel_ptr_t); 23 | 24 | #define HANDLE_CHANNEL_MSG "handle_channel_msg" 25 | #define HANDLE_CHANNEL_BROKEN "handle_channel_broken" 26 | #endif 27 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/plugin_impl/plugin_dll.h: -------------------------------------------------------------------------------- 1 | #ifndef _PLUGIN_IMPL_H_ 2 | #define _PLUGIN_IMPL_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "plugin_i.h" 8 | 9 | using namespace ff; 10 | 11 | class plugin_dll_t : public plugin_i 12 | { 13 | public: 14 | plugin_dll_t(const string& name_); 15 | ~plugin_dll_t(); 16 | int start(); 17 | int stop(); 18 | 19 | int handle_broken(channel_ptr_t channel_); 20 | int handle_msg(const message_t& msg_, channel_ptr_t channel_); 21 | 22 | private: 23 | string m_dll_name; 24 | void* m_dll_handler; 25 | handle_channel_msg_func_t m_msg_cb; 26 | handle_channel_broken_func_t m_broken_cb; 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/plugin_impl/plugin_lua.h: -------------------------------------------------------------------------------- 1 | #ifndef _PLUGIN_LUA_H_ 2 | #define _PLUGIN_LUA_H_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | #include 8 | #include "plugin_i.h" 9 | 10 | using namespace ff; 11 | 12 | class plugin_lua_t : public plugin_i 13 | { 14 | public: 15 | plugin_lua_t(const string& name_); 16 | ~plugin_lua_t(); 17 | int start(); 18 | int stop(); 19 | 20 | int handle_broken(channel_ptr_t channel_); 21 | int handle_msg(const message_t& msg_, channel_ptr_t channel_); 22 | 23 | channel_ptr_t get_channel(long p); 24 | private: 25 | int load_lua_mod(); 26 | int call_lua_handle_msg(long val, const string& msg); 27 | int call_lua_handle_broken(long val); 28 | private: 29 | string m_lua_name; 30 | lua_State* m_ls; 31 | map m_channel_mgr; 32 | }; 33 | #endif 34 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/plugin_impl/plugin_python.h: -------------------------------------------------------------------------------- 1 | #ifndef _PLUGIN_PYTHON_H_ 2 | #define _PLUGIN_PYTHON_H_ 3 | #include 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #include "plugin_i.h" 10 | 11 | using namespace ff; 12 | 13 | class plugin_python_t : public plugin_i 14 | { 15 | public: 16 | plugin_python_t(const string& name_); 17 | ~plugin_python_t(); 18 | int start(); 19 | int stop(); 20 | 21 | int handle_broken(channel_ptr_t channel_); 22 | int handle_msg(const message_t& msg_, channel_ptr_t channel_); 23 | 24 | channel_ptr_t get_channel(long p); 25 | private: 26 | int load_py_mod(); 27 | int call_py_handle_msg(long val, const char* msg); 28 | int call_py_handle_broken(long val); 29 | private: 30 | string m_py_name; 31 | PyObject * m_py_mod; 32 | map m_channel_mgr; 33 | }; 34 | #endif 35 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/include/plugin_impl/pyext.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _PYEXT_H_ 3 | #define _PYEXT_H_ 4 | #include "plugin_impl/plugin_python.h" 5 | 6 | extern "C" { 7 | 8 | static plugin_python_t* g_plugin_py_obj = NULL; 9 | static PyObject * 10 | channel_send(PyObject *self, PyObject *args) 11 | { 12 | long ptr; 13 | const char *msg; 14 | 15 | if (!PyArg_ParseTuple(args, "ls", &ptr, &msg)) 16 | return NULL; 17 | 18 | channel_ptr_t c = g_plugin_py_obj->get_channel(ptr); 19 | if (c) 20 | { 21 | c->async_send(msg); 22 | } 23 | return Py_BuildValue("l", 0); 24 | } 25 | 26 | static PyMethodDef ChannelMethods[] = { 27 | {"send", channel_send, METH_VARARGS, 28 | "send msg."}, 29 | {NULL, NULL, 0, NULL} /* Sentinel */ 30 | }; 31 | 32 | PyMODINIT_FUNC 33 | initpyext(plugin_python_t* obj) 34 | { 35 | PyObject *m; 36 | 37 | g_plugin_py_obj = obj; 38 | m = Py_InitModule("channel", ChannelMethods); 39 | if (m == NULL) 40 | return; 41 | } 42 | 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/plugin/include/msg_broker_iterface.h: -------------------------------------------------------------------------------- 1 | #ifndef _MSG_BROKER_INTERFACE_H_ 2 | #define _MSG_BROKER_INTERFACE_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | class message_t 8 | { 9 | public: 10 | const string& get_body() const; 11 | }; 12 | 13 | class channel_t 14 | { 15 | public: 16 | void set_data(void* p); 17 | void* get_data() const; 18 | 19 | template 20 | T* get_data() const { return (T*)this->get_data(); } 21 | 22 | void async_send(const string& buff_); 23 | void close(); 24 | }; 25 | typedef channel_t* channel_ptr_t; 26 | #endif 27 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/plugin/plugin_echo_dll/gen_dll.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | g++ -fPIC -shared -I../include/ *.cpp -o libecho.so 3 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/plugin/plugin_echo_dll/plugin_echo_dll.cpp: -------------------------------------------------------------------------------- 1 | #include "msg_broker_iterface.h" 2 | #include 3 | using namespace std; 4 | 5 | extern "C"{ 6 | 7 | int handle_channel_msg(const message_t& msg_, channel_ptr_t channel_) 8 | { 9 | cout <<"handle_channel_msg:" << msg_.get_body() << "\n"; 10 | channel_->async_send("oh nice"); 11 | return 0; 12 | } 13 | 14 | int handle_channel_broken(channel_ptr_t channel_) 15 | { 16 | cout <<"handle_channel_broken:\n"; 17 | channel_->close(); 18 | delete channel_; 19 | return 0; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/plugin/plugin_echo_lua/echo.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | print("lua load end ok...") 5 | 6 | function handle_msg(channel_, msg_) 7 | channel.send(channel_, msg_) 8 | print(channel_, msg_) 9 | end 10 | 11 | function handle_broken(channel_) 12 | print(channel_) 13 | end 14 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/plugin/plugin_echo_py/echo.py: -------------------------------------------------------------------------------- 1 | import channel 2 | def handle_msg(channel_, msg_): 3 | print(channel_, msg_) 4 | channel.send(channel_, msg_) 5 | 6 | def handle_broken(channel_): 7 | print(channel_) 8 | 9 | 10 | print("load end ok ....") 11 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/src/channel.cpp: -------------------------------------------------------------------------------- 1 | #include "channel.h" 2 | 3 | channel_t::channel_t(socket_ptr_t sock_): 4 | m_socket(sock_), 5 | m_data(NULL) 6 | { 7 | } 8 | 9 | channel_t::~channel_t() 10 | { 11 | if (m_socket) 12 | { 13 | m_socket->safe_delete(); 14 | } 15 | } 16 | 17 | void channel_t::set_data(void* p) 18 | { 19 | m_data = p; 20 | } 21 | 22 | void* channel_t::get_data() const 23 | { 24 | return m_data; 25 | } 26 | 27 | void channel_t::async_send(const string& buff_) 28 | { 29 | m_socket->async_send(buff_); 30 | } 31 | 32 | void channel_t::close() 33 | { 34 | m_socket->close(); 35 | } 36 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #include "net/acceptor_impl.h" 10 | #include "net/epoll_impl.h" 11 | #include "base/thread.h" 12 | #include "base/smart_ptr.h" 13 | #include "msg_broker_service.h" 14 | #include "net/net_factory.h" 15 | 16 | void handler(int sig) { 17 | printf("signal:%d\n", sig); 18 | exit(0); 19 | } 20 | 21 | int main(int argc, char* argv[]) 22 | { 23 | signal(SIGINT,handler); 24 | if (argc != 4) 25 | { 26 | cout < 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | #include "log_module.h" 8 | #include "msg_broker_service.h" 9 | #include "channel.h" 10 | #include "plugin_factory.h" 11 | 12 | msg_broker_service_t::msg_broker_service_t() 13 | { 14 | } 15 | 16 | msg_broker_service_t::~msg_broker_service_t() 17 | { 18 | if (m_plugin) 19 | { 20 | delete m_plugin; 21 | } 22 | } 23 | 24 | int msg_broker_service_t::handle_broken(socket_ptr_t sock_) 25 | { 26 | try 27 | { 28 | channel_t* c = sock_->get_data(); 29 | if (NULL == c) 30 | { 31 | sock_->close(); 32 | sock_->safe_delete(); 33 | return 0; 34 | } 35 | m_plugin->handle_broken(c); 36 | } 37 | catch(exception& e) 38 | { 39 | logerror((BROKER_SERVICE, "chat_service_t::handle_broken exception<%s>", e.what())); 40 | sock_->close(); 41 | } 42 | return 0; 43 | } 44 | 45 | int msg_broker_service_t::handle_msg(const message_t& msg_, socket_ptr_t sock_) 46 | { 47 | try 48 | { 49 | channel_t* c = sock_->get_data(); 50 | if (NULL == c) 51 | { 52 | c = new channel_t(sock_); 53 | sock_->set_data(c); 54 | } 55 | m_plugin->handle_msg(msg_, c); 56 | } 57 | catch(exception& e) 58 | { 59 | logerror((BROKER_SERVICE, "chat_service_t::handle_msg exception<%s>", e.what())); 60 | sock_->close(); 61 | } 62 | return 0; 63 | } 64 | 65 | int msg_broker_service_t::start(const string& path_) 66 | { 67 | m_plugin = plugin_factory_t::create_plugin(path_); 68 | 69 | if (NULL == m_plugin) 70 | { 71 | return -1; 72 | } 73 | return m_plugin->start(); 74 | } 75 | 76 | int msg_broker_service_t::stop() 77 | { 78 | m_plugin->stop(); 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/src/plugin_factory.cpp: -------------------------------------------------------------------------------- 1 | #include "plugin_impl/plugin_python.h" 2 | #include "plugin_factory.h" 3 | #include "plugin_impl/plugin_dll.h" 4 | #include "plugin_impl/plugin_lua.h" 5 | 6 | plugin_ptr_t plugin_factory_t::create_plugin(const string& path_) 7 | { 8 | if (-1 != (int)path_.find(".so")) 9 | { 10 | return new plugin_dll_t(path_); 11 | } 12 | else if (-1 != (int)path_.find(".py")) 13 | { 14 | return new plugin_python_t(path_); 15 | } 16 | else if (-1 != (int)path_.find(".lua")) 17 | { 18 | return new plugin_lua_t(path_); 19 | } 20 | return NULL; 21 | } 22 | -------------------------------------------------------------------------------- /example/plugin_msg_broker/src/plugin_impl/plugin_dll.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "log_module.h" 5 | #include "plugin_impl/plugin_dll.h" 6 | 7 | plugin_dll_t::plugin_dll_t(const string& name_): 8 | m_dll_name(name_), 9 | m_dll_handler(NULL), 10 | m_msg_cb(NULL), 11 | m_broken_cb(NULL) 12 | { 13 | } 14 | 15 | plugin_dll_t::~plugin_dll_t() 16 | { 17 | } 18 | 19 | int plugin_dll_t::start() 20 | { 21 | m_dll_handler = ::dlopen(m_dll_name.c_str(), RTLD_NOW|RTLD_GLOBAL); 22 | 23 | if (NULL == m_dll_handler) 24 | { 25 | logerror((PLUGIN_IMPL, "plugin_dll_t::start dlopen failed:<%s>", dlerror())); 26 | return -1; 27 | } 28 | 29 | m_msg_cb = (handle_channel_msg_func_t)::dlsym(m_dll_handler, HANDLE_CHANNEL_MSG); 30 | m_broken_cb = (handle_channel_broken_func_t)::dlsym(m_dll_handler, HANDLE_CHANNEL_BROKEN); 31 | 32 | if (NULL == m_msg_cb) 33 | { 34 | logerror((PLUGIN_IMPL, "plugin_dll_t::start dlopen failed:<%s> not exist", HANDLE_CHANNEL_MSG)); 35 | return -1; 36 | } 37 | if (NULL == m_broken_cb) 38 | { 39 | logerror((PLUGIN_IMPL, "plugin_dll_t::start dlopen failed:<%s> not exist", HANDLE_CHANNEL_BROKEN)); 40 | return -1; 41 | } 42 | 43 | return 0; 44 | } 45 | 46 | int plugin_dll_t::stop() 47 | { 48 | ::dlclose(m_dll_handler); 49 | return 0; 50 | } 51 | 52 | int plugin_dll_t::handle_broken(channel_ptr_t channel_) 53 | { 54 | return m_broken_cb(channel_); 55 | } 56 | 57 | int plugin_dll_t::handle_msg(const message_t& msg_, channel_ptr_t channel_) 58 | { 59 | return m_msg_cb(msg_, channel_); 60 | } 61 | -------------------------------------------------------------------------------- /example/ranklist/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_ranklist 16 | 17 | #源文件目录 18 | SrcDir= . src 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/ranklist/include/rank_obj.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANK_OBJ_H_ 2 | #define _RANK_OBJ_H_ 3 | 4 | class rank_obj_t 5 | { 6 | public: 7 | rank_obj_t():m_rank(0){} 8 | virtual ~rank_obj_t() {} 9 | virtual long get_attr(int AttrId) { return -1; } 10 | 11 | void set_rank(int rank_) { m_rank = rank_; } 12 | int get_rank() const { return m_rank; } 13 | private: 14 | int m_rank; 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /example/ranklist/include/rank_obj_mgr.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANK_OBJ_MGR_H_ 2 | #define _RANK_OBJ_MGR_H_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class rank_obj_t; 9 | 10 | class rank_obj_mgr_t 11 | { 12 | public: 13 | virtual int add(long id, rank_obj_t* obj_) 14 | { 15 | return m_objs.insert(make_pair(id, obj_)).second == true? 0: -1; 16 | } 17 | virtual void del(long id_) 18 | { 19 | m_objs.erase(id_); 20 | } 21 | virtual rank_obj_t* find(long id_) 22 | { 23 | map::iterator it = m_objs.find(id_); 24 | return it != m_objs.end()? it->second: NULL; 25 | } 26 | 27 | template 28 | void foreach(T func_) 29 | { 30 | for (map::iterator it = m_objs.begin(); it != m_objs.end(); ++it) 31 | { 32 | func_(it->second); 33 | } 34 | } 35 | 36 | private: 37 | map m_objs; 38 | }; 39 | #endif 40 | -------------------------------------------------------------------------------- /example/ranklist/include/rank_system.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANK_SYSTEM_H_ 2 | #define _RANK_SYSTEM_H_ 3 | 4 | class rank_obj_mgr_t; 5 | class ranklist_t; 6 | 7 | #include 8 | using namespace std; 9 | 10 | class rank_system_t 11 | { 12 | typedef map ranklist_map_t; 13 | public: 14 | rank_system_t(rank_obj_mgr_t* rank_obj_mgr_); 15 | ~rank_system_t(); 16 | 17 | ranklist_t& create_ranklist(int attr_id_, int rank_num_); 18 | int destory_ranklist(int attr_id_); 19 | 20 | protected: 21 | rank_obj_mgr_t* m_rank_obj_mgr; 22 | ranklist_map_t m_ranklist; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /example/ranklist/include/ranklist.h: -------------------------------------------------------------------------------- 1 | #ifndef _RANKLIST_H_ 2 | #define _RANKLIST_H_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class rank_obj_t; 9 | class rank_obj_mgr_t; 10 | 11 | #include "rank_obj.h" 12 | 13 | class ranklist_t 14 | { 15 | typedef multimap > sort_map_t; 16 | enum 17 | { 18 | MAX_RANK_NUM = 1000 19 | }; 20 | struct sort_functor_t 21 | { 22 | sort_functor_t(int attr_id_, sort_map_t* sort_map_, int max_rank_num_): 23 | m_attr_id(attr_id_), 24 | m_sort_map(sort_map_), 25 | m_max_rank_num(max_rank_num_) 26 | {} 27 | void operator()(rank_obj_t* rank_obj_) 28 | { 29 | int value = rank_obj_->get_attr(m_attr_id); 30 | if (m_sort_map->size() <= (size_t)m_max_rank_num) 31 | { 32 | m_sort_map->insert(make_pair(value, rank_obj_)); 33 | } 34 | else if (value > m_sort_map->rbegin()->second->get_attr(m_attr_id)) 35 | { 36 | m_sort_map->insert(make_pair(value, rank_obj_)); 37 | m_sort_map->erase(--(m_sort_map->end())); 38 | } 39 | } 40 | int m_attr_id; 41 | sort_map_t* m_sort_map; 42 | int m_max_rank_num; 43 | }; 44 | 45 | struct rank_info_t 46 | { 47 | int rank; 48 | rank_obj_t* rank_obj; 49 | long old_attr; 50 | }; 51 | public: 52 | ranklist_t(rank_obj_mgr_t* obj_mgr_, int attr_id_, int max_rank_num_ = MAX_RANK_NUM); 53 | 54 | void sort(); 55 | int update_obj(rank_obj_t* rank_obj_); 56 | 57 | int get_rank(int from_, int to_, vector& ret_); 58 | 59 | private: 60 | void resort_ranklist(int rank_, sort_map_t::iterator it_begin_, sort_map_t::iterator it_end_); 61 | sort_map_t::iterator find(long attr_, rank_obj_t* pbj_); 62 | 63 | int check_rank_num_limit(); 64 | bool is_first(int rank_) const {return 1 == rank_;} 65 | bool is_last(int rank_) const {return m_ranklist_cache_vt.size() == (size_t)rank_;} 66 | private: 67 | rank_obj_mgr_t* m_rank_obj_mgr; 68 | int m_attr_id; 69 | int m_max_rank_num; 70 | sort_map_t m_ranklist_sort_map; 71 | 72 | //! rank 1- N 73 | vector m_ranklist_cache_vt; 74 | }; 75 | #endif 76 | -------------------------------------------------------------------------------- /example/ranklist/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | #include "rank_obj.h" 6 | #include "rank_obj_mgr.h" 7 | #include "rank_system.h" 8 | 9 | int main(int argc, char* argv[]) 10 | { 11 | rank_obj_mgr_t rank_obj_mgr; 12 | rank_system_t rank_system(&rank_obj_mgr); 13 | 14 | enum 15 | { 16 | LEVEL_RANK = 1 17 | }; 18 | //! 等级排行榜, 排名前一百个 19 | rank_system.create_ranklist(LEVEL_RANK, 100); 20 | ::system("pause"); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /example/ranklist/src/rank_system.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "rank_system.h" 3 | #include "ranklist.h" 4 | 5 | rank_system_t::rank_system_t(rank_obj_mgr_t* rank_obj_mgr_): 6 | m_rank_obj_mgr(rank_obj_mgr_) 7 | { 8 | 9 | } 10 | 11 | rank_system_t::~rank_system_t() 12 | { 13 | 14 | } 15 | 16 | ranklist_t& rank_system_t::create_ranklist(int attr_id_, int rank_num_) 17 | { 18 | ranklist_map_t::iterator it = m_ranklist.find(attr_id_); 19 | if (it != m_ranklist.end()) 20 | { 21 | return *(it->second); 22 | } 23 | ranklist_t* ret = new ranklist_t(m_rank_obj_mgr, attr_id_, rank_num_); 24 | m_ranklist[attr_id_] = ret; 25 | return *ret; 26 | } 27 | 28 | int rank_system_t::destory_ranklist(int attr_id_) 29 | { 30 | ranklist_map_t::iterator it = m_ranklist.find(attr_id_); 31 | if (it != m_ranklist.end()) 32 | { 33 | delete it->second; 34 | m_ranklist.erase(it); 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /example/ranklist/src/ranklist.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanchy/fflib/ee6a1ba918b444ceb5e86a25dbf7c4a236494709/example/ranklist/src/ranklist.cpp -------------------------------------------------------------------------------- /example/rpc/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_rpc 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/lib ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /example/rpc/include/msg_def.h: -------------------------------------------------------------------------------- 1 | //! 消息定义 2 | #ifndef _MSG_DEF_H_ 3 | #define _MSG_DEF_H_ 4 | 5 | #include "net/codec.h" 6 | 7 | using namespace ff; 8 | 9 | struct test_msg_t: public msg_i 10 | { 11 | test_msg_t(): 12 | msg_i("test") 13 | {} 14 | virtual string encode() 15 | { 16 | return (init_encoder() << val).get_buff(); 17 | } 18 | virtual void decode(const string& src_buff_) 19 | { 20 | init_decoder(src_buff_) >> val; 21 | } 22 | 23 | int val; 24 | }; 25 | #endif 26 | -------------------------------------------------------------------------------- /example/tutorial/Makefile: -------------------------------------------------------------------------------- 1 | #交叉编译器路径 2 | CROSS= 3 | CP=/bin/cp 4 | RM=-/bin/rm -rf 5 | LN=/bin/ln -s 6 | CFLAGS=-g -Wall 7 | LDFLAGS= -lpthread 8 | #链接库名 9 | LIB_NAME= 10 | #链接库版本 11 | LIB_VER=1.0.0 12 | #平台 13 | ARCH= 14 | # 二进制目标 15 | BIN=app_echo_server 16 | 17 | #源文件目录 18 | SrcDir= . src ../../fflib/base ../../fflib/net ../../fflib/rpc ../../fflib/cqrs 19 | #头文件目录 20 | IncDir= ./include ../../fflib/ ../../fflib/ext 21 | #连接库目录 22 | LibDir= /usr/local/lib 23 | SRCS=$(foreach dir,$(SrcDir),$(wildcard $(dir)/*.cpp)) 24 | #INCS=$(foreach dir,$(IncDir),$(wildcard $(dir)/*.h)) 25 | INCS=$(foreach dir,$(IncDir),$(addprefix -I,$(dir))) 26 | LINKS=$(foreach dir,$(LibDir),$(addprefix -L,$(dir))) 27 | CFLAGS := $(CFLAGS) $(INCS) 28 | LDFLAGS:= $(LINKS) $(LDFLAGS) 29 | CC=g++ 30 | ARCH=PC 31 | OBJS = $(SRCS:%.cpp=%.o) 32 | .PHONY:all clean 33 | 34 | all:$(BIN) 35 | $(BIN):$(OBJS) 36 | $(CC) -o $(BIN) $(OBJS) $(LDFLAGS) 37 | @echo -e " OK!\tComplie $@ " 38 | # @$(LN) $(shell pwd)/$(LIB_NAME).$(LIB_VER) /lib/$(LIB_NAME) 39 | 40 | %.o:%.cpp 41 | @echo -e "[$(ARCH)] \t\tCompileing $@..." 42 | @$(CC) $(CFLAGS) -c $< -o $@ 43 | .PHONY: clean 44 | clean: 45 | @echo -e "[$(ARCH)] \tCleaning files..." 46 | @$(RM) $(OBJS) $(BIN) 47 | -------------------------------------------------------------------------------- /fflib/ai/ffai.h: -------------------------------------------------------------------------------- 1 | #ifndef _FF_AI_H_ 2 | #define _FF_AI_H_ 3 | 4 | #include "base/fftype.h" 5 | #include "base/singleton.h" 6 | #include "base/smart_ptr.h" 7 | 8 | #include 9 | using namespace std; 10 | 11 | namespace ff 12 | { 13 | 14 | template 15 | class ffstate_machine_t; 16 | 17 | template 18 | class ff_state_t 19 | { 20 | public: 21 | typedef ffstate_machine_t fsm_t; 22 | public: 23 | virtual ~ff_state_t(){} 24 | virtual void enter(fsm_t*) {} 25 | virtual void update(fsm_t*) {} 26 | virtual void exit(fsm_t*) {} 27 | virtual void handle(fsm_t*, type_i& event_){} 28 | }; 29 | 30 | template 31 | class ffstate_machine_t 32 | { 33 | public: 34 | typedef shared_ptr_t > ff_state_ptr_t; 35 | public: 36 | ffstate_machine_t(T* obj_): 37 | m_dest_obj(obj_) 38 | {} 39 | 40 | virtual ~ffstate_machine_t(){} 41 | T* get_owener() { return m_dest_obj; } 42 | void update() 43 | { 44 | if(m_current_state) m_current_state->update(this); 45 | } 46 | 47 | void handle(type_i& event_) 48 | { 49 | if (m_current_state) m_current_state->handle(this, event_); 50 | } 51 | 52 | void change(ff_state_ptr_t new_state_) 53 | { 54 | m_previous_state = m_current_state; 55 | if (m_current_state) 56 | { 57 | m_current_state->exit(this); 58 | } 59 | 60 | m_current_state = new_state_; 61 | if (m_current_state) m_current_state->enter(this); 62 | } 63 | 64 | ff_state_ptr_t& current_state() { return m_current_state; } 65 | ff_state_ptr_t& previous_state() { return m_previous_state; } 66 | 67 | private: 68 | T* m_dest_obj; 69 | ff_state_ptr_t m_previous_state; 70 | ff_state_ptr_t m_current_state; 71 | }; 72 | 73 | } 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /fflib/base/arg_helper.h: -------------------------------------------------------------------------------- 1 | #ifndef _ARG_HELPER_H_ 2 | #define _ARG_HELPER_H_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | #include "base/strtool.h" 9 | 10 | class arg_helper_t 11 | { 12 | public: 13 | arg_helper_t(int argc, char* argv[]) 14 | { 15 | for (int i = 0; i < argc; ++i) 16 | { 17 | m_args.push_back(argv[i]); 18 | } 19 | } 20 | arg_helper_t(string arg_str_) 21 | { 22 | vector v; 23 | strtool::split(arg_str_, v, " "); 24 | m_args.insert(m_args.end(), v.begin(), v.end()); 25 | } 26 | string get_option(int idx_) const 27 | { 28 | if ((size_t)idx_ >= m_args.size()) 29 | { 30 | return ""; 31 | } 32 | return m_args[idx_]; 33 | } 34 | bool is_enable_option(string opt_) const 35 | { 36 | for (size_t i = 0; i < m_args.size(); ++i) 37 | { 38 | if (opt_ == m_args[i]) 39 | { 40 | return true; 41 | } 42 | } 43 | return false; 44 | } 45 | 46 | string get_option_value(string opt_) const 47 | { 48 | string ret; 49 | for (size_t i = 0; i < m_args.size(); ++i) 50 | { 51 | if (opt_ == m_args[i]) 52 | { 53 | size_t value_idx = ++ i; 54 | if (value_idx >= m_args.size()) 55 | { 56 | return ret; 57 | } 58 | ret = m_args[value_idx]; 59 | return ret; 60 | } 61 | } 62 | return ret; 63 | } 64 | private: 65 | vector m_args; 66 | }; 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /fflib/base/atomic_op.h: -------------------------------------------------------------------------------- 1 | #ifndef _FF_ATOMIC_H_ 2 | #define _FF_ATOMIC_H_ 3 | 4 | namespace ff { 5 | //! windows.h 6 | //! InterlockedIncrement 7 | //! InterlockedDecrement 8 | 9 | #define ATOMIC_ADD(src_ptr, v) (void)__sync_add_and_fetch(src_ptr, v) 10 | #define ATOMIC_SUB_AND_FETCH(src_ptr, v) __sync_sub_and_fetch(src_ptr, v) 11 | #define ATOMIC_ADD_AND_FETCH(src_ptr, v) __sync_add_and_fetch(src_ptr, v) 12 | #define ATOMIC_FETCH(src_ptr) __sync_add_and_fetch(src_ptr, 0) 13 | #define ATOMIC_SET(src_ptr, v) (void)__sync_bool_compare_and_swap(src_ptr, *(src_ptr), v) 14 | 15 | class ref_count_t 16 | { 17 | typedef volatile long atomic_t; 18 | public: 19 | ref_count_t(): 20 | m_ref_num(0) 21 | {} 22 | ~ref_count_t() 23 | {} 24 | 25 | inline void inc(int n = 1) 26 | { 27 | ATOMIC_ADD(&m_ref_num, n); 28 | } 29 | inline bool dec_and_check_zero(int n = 1) 30 | { 31 | return 0 == ATOMIC_SUB_AND_FETCH(&m_ref_num, n); 32 | } 33 | inline atomic_t inc_and_fetch(int n = 1) 34 | { 35 | return ATOMIC_ADD_AND_FETCH(&m_ref_num, n); 36 | } 37 | inline atomic_t value() 38 | { 39 | return ATOMIC_FETCH(&m_ref_num); 40 | } 41 | 42 | private: 43 | atomic_t m_ref_num; 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /fflib/base/daemon_tool.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _DAEMON_TOOL_H_ 3 | #define _DAEMON_TOOL_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace ff 13 | { 14 | class daemon_tool_t 15 | { 16 | public: 17 | static void daemon() 18 | { 19 | daemon(NULL); 20 | } 21 | 22 | static void daemon(const char* uname_) 23 | { 24 | pid_t pid, sid; 25 | 26 | if ((pid = fork()) < 0) 27 | { 28 | printf("daemon fork failed:%s\n", strerror(errno)); 29 | exit(EXIT_FAILURE); 30 | } 31 | else if(pid != 0) 32 | { 33 | exit(EXIT_SUCCESS); 34 | } 35 | 36 | char buffer[1024]; 37 | getcwd(buffer, sizeof(buffer)); 38 | 39 | if(chdir(buffer) == -1) 40 | { 41 | printf("chdir failed:%s", strerror(errno)); 42 | exit(EXIT_FAILURE); 43 | } 44 | 45 | if(uname_ != NULL) 46 | { 47 | int uid = get_uid(uname_); 48 | if(uid == -1) 49 | { 50 | printf("get_uid failed:%s", strerror(errno)); 51 | exit(EXIT_FAILURE); 52 | } 53 | if(setuid(uid) == -1) 54 | { 55 | printf("setuid failed:%s", strerror(errno)); 56 | exit(EXIT_FAILURE); 57 | } 58 | } 59 | 60 | sid = setsid(); 61 | if (sid < 0) 62 | { 63 | printf("daemon setsid failed:%s", strerror(errno)); 64 | exit (EXIT_FAILURE); 65 | } 66 | 67 | umask (022); 68 | 69 | for (int i = getdtablesize() - 1; i >= 0; --i) 70 | { 71 | (void)close(i); 72 | } 73 | 74 | int fd_dev = open("/dev/null", O_RDWR); 75 | (void)dup(fd_dev); 76 | (void)dup(fd_dev); 77 | } 78 | 79 | static int get_uid(const char* uname_) 80 | { 81 | struct passwd *user = NULL; 82 | user = getpwnam(uname_); 83 | if(user == NULL) 84 | { 85 | return -1; 86 | } 87 | return user->pw_uid; 88 | } 89 | }; 90 | 91 | } 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /fflib/base/os_tool.h: -------------------------------------------------------------------------------- 1 | #ifndef _FF_OS_TOOL_H_ 2 | #define _FF_OS_TOOL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | using namespace std; 13 | 14 | namespace ff 15 | { 16 | 17 | struct os_tool_t 18 | { 19 | static int ls(const string& path_, vector& ret_) 20 | { 21 | const char* dir = path_.c_str(); 22 | DIR *dp; 23 | struct dirent *entry; 24 | 25 | if((dp = opendir(dir)) == NULL) { 26 | fprintf(stderr,"cannot open directory: %s\n", dir); 27 | return -1; 28 | } 29 | 30 | while((entry = readdir(dp)) != NULL) { 31 | if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0) 32 | continue; 33 | ret_.push_back(entry->d_name); 34 | } 35 | closedir(dp); 36 | return 0; 37 | } 38 | static bool is_dir(const string& name_) 39 | { 40 | struct stat s; 41 | if(lstat(name_.c_str(), &s) < 0){ 42 | return false; 43 | } 44 | return S_ISDIR(s.st_mode); 45 | } 46 | }; 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /fflib/base/signal_helper.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _SIGNAL_HELPER_H_ 3 | #define _SIGNAL_HELPER_H_ 4 | 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | class signal_helper_t 13 | { 14 | public: 15 | static int bloack() 16 | { 17 | sigset_t mask_sig; 18 | 19 | ::sigfillset(&mask_sig); 20 | return ::pthread_sigmask(SIG_BLOCK, &mask_sig, NULL); 21 | } 22 | static int wait(string option_ = "") 23 | { 24 | sigset_t mask_sig; 25 | sigemptyset(&mask_sig); 26 | sigaddset(&mask_sig, SIGINT); 27 | sigaddset(&mask_sig, SIGQUIT); 28 | sigaddset(&mask_sig, SIGTERM); 29 | 30 | int sig_num = 0; 31 | pthread_sigmask(SIG_BLOCK, &mask_sig, 0); 32 | 33 | ::sigwait(&mask_sig, &sig_num); 34 | return sig_num; 35 | } 36 | }; 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /fflib/base/singleton.h: -------------------------------------------------------------------------------- 1 | #ifndef _SINGLETON_H_ 2 | #define _SINGLETON_H_ 3 | 4 | #include 5 | #include 6 | 7 | template 8 | class singleton_t 9 | { 10 | public: 11 | static T& instance() 12 | { 13 | pthread_once(&m_ponce, &singleton_t::init); 14 | return *m_instance; 15 | } 16 | 17 | static T* instance_ptr() 18 | { 19 | return m_instance; 20 | } 21 | private: 22 | static void init() 23 | { 24 | m_instance = new T(); 25 | atexit(destroy); 26 | } 27 | static void destroy() 28 | { 29 | if(m_instance) 30 | { 31 | delete m_instance; 32 | m_instance = 0; 33 | } 34 | } 35 | 36 | private: 37 | static T* volatile m_instance; 38 | static pthread_once_t m_ponce; 39 | }; 40 | 41 | template 42 | T* volatile singleton_t::m_instance = NULL; 43 | 44 | template 45 | pthread_once_t singleton_t::m_ponce = PTHREAD_ONCE_INIT; 46 | 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /fflib/base/thread.cpp: -------------------------------------------------------------------------------- 1 | #include "base/thread.h" 2 | 3 | using namespace ff; 4 | 5 | void* thread_t::thread_func(void* p_) 6 | { 7 | task_t* t = (task_t*)p_; 8 | t->run(); 9 | delete t; 10 | return 0; 11 | } 12 | 13 | int thread_t::create_thread(task_t func, int num) 14 | { 15 | for (int i = 0; i < num; ++i) 16 | { 17 | pthread_t ntid; 18 | task_t* t = new task_t(func); 19 | if (0 == ::pthread_create(&ntid, NULL, thread_func, t)) 20 | { 21 | m_tid_list.push_back(ntid); 22 | } 23 | } 24 | return 0; 25 | } 26 | 27 | int thread_t::join() 28 | { 29 | list::iterator it = m_tid_list.begin(); 30 | for (; it != m_tid_list.end(); ++it) 31 | { 32 | pthread_join((*it), NULL); 33 | } 34 | m_tid_list.clear(); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /fflib/base/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREAD_H_ 2 | #define _THREAD_H_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | #include "base/task_queue_i.h" 9 | #include "base/task_queue_impl.h" 10 | 11 | namespace ff { 12 | 13 | class thread_t 14 | { 15 | static void* thread_func(void* p_); 16 | 17 | public: 18 | int create_thread(task_t func, int num = 1); 19 | int join(); 20 | 21 | private: 22 | list m_tid_list; 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /fflib/base/time_tool.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_TIME_TOOL_H_ 3 | #define _FF_TIME_TOOL_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | #include "time.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace std; 14 | 15 | //! 获取特定时间的unix 时间戳 16 | struct time_tool_t 17 | { 18 | static long today_at_zero()//!今日零点时间戳 19 | { 20 | time_t now = ::time(NULL); 21 | tm tm_val = *::localtime(&now); 22 | long ret = (long)now - tm_val.tm_hour*3600 - tm_val.tm_min*60 - tm_val.tm_sec; 23 | return ret; 24 | } 25 | static long next_month()//!下个月开始时间戳 26 | { 27 | time_t now = ::time(NULL); 28 | tm tm_val = *::localtime(&now); 29 | 30 | //! 计算这个月有多少天 31 | static int help_month[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 32 | int month_day_num = help_month[tm_val.tm_mon]; 33 | if (1 == tm_val.tm_mon)//! 检查2月闰月 34 | { 35 | if ((tm_val.tm_year + 1900) % 4 == 0) ++ month_day_num; 36 | } 37 | 38 | long ret = (long)now + (month_day_num - tm_val.tm_mday)*86400 + (23 - tm_val.tm_hour)*3600 + 39 | (59 - tm_val.tm_min)*60 + (60 - tm_val.tm_sec); 40 | return ret; 41 | } 42 | }; 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /fflib/cqrs/aggregate_root_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_AGGREGATE_ROOT_I_ 3 | #define _FF_AGGREGATE_ROOT_I_ 4 | 5 | #include 6 | using namespace std; 7 | 8 | #include "cqrs/event_i.h" 9 | 10 | namespace ff 11 | { 12 | 13 | typedef long guid_t; 14 | 15 | class aggregate_root_i: public type_i 16 | { 17 | typedef list event_list_t; 18 | public: 19 | aggregate_root_i():m_id(0){} 20 | virtual ~aggregate_root_i(){} 21 | 22 | virtual guid_t get_id() const { return m_id; } 23 | virtual void set_id(guid_t id_) { m_id = id_; } 24 | 25 | void add_event(event_i* e_) {m_events.push_back(e_);} 26 | const event_list_t& get_events() const { return m_events; } 27 | void clear_event() 28 | { 29 | for (event_list_t::iterator it = m_events.begin(); it != m_events.end(); ++it) 30 | { 31 | delete *it; 32 | } 33 | m_events.clear(); 34 | } 35 | 36 | template 37 | void add_event(const T& event_) 38 | { 39 | this->add_event(new T(event_)); 40 | } 41 | protected: 42 | guid_t m_id; 43 | event_list_t m_events; 44 | }; 45 | 46 | template 47 | class aggregate_root_t: public auto_type_t 48 | { 49 | public: 50 | virtual ~ aggregate_root_t(){} 51 | }; 52 | 53 | #define AR aggregate_root_t 54 | } 55 | #endif 56 | -------------------------------------------------------------------------------- /fflib/cqrs/command_handler_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_COMMAD_HANDLER_I_ 3 | #define _FF_COMMAD_HANDLER_I_ 4 | 5 | namespace ff 6 | { 7 | 8 | class command_handler_i: public type_i 9 | { 10 | public: 11 | virtual ~command_handler_i(){} 12 | }; 13 | 14 | template 15 | class command_handler_t: public auto_type_t 16 | { 17 | public: 18 | virtual ~command_handler_t(){} 19 | }; 20 | 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /fflib/cqrs/command_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_COMMAD_I_ 3 | #define _FF_COMMAD_I_ 4 | 5 | #include "base/fftype.h" 6 | #include "net/codec.h" 7 | 8 | namespace ff 9 | { 10 | 11 | class command_i: public type_i 12 | { 13 | public: 14 | virtual ~command_i(){} 15 | }; 16 | 17 | template 18 | class command_t: public auto_type_t 19 | { 20 | public: 21 | virtual ~command_t(){} 22 | bin_decoder_t& decoder() { return m_decoder; } 23 | bin_encoder_t& encoder() { return m_encoder; } 24 | virtual string encode() 25 | { 26 | enc(); 27 | return encoder().get_buff(); 28 | } 29 | virtual void decode(const string& src_buff_) 30 | { 31 | decoder().init(src_buff_); 32 | dec(); 33 | } 34 | virtual void enc() = 0; 35 | virtual void dec() = 0; 36 | 37 | private: 38 | bin_decoder_t m_decoder; 39 | bin_encoder_t m_encoder; 40 | }; 41 | 42 | 43 | template 44 | class user_command_t: public auto_type_t 45 | { 46 | public: 47 | user_command_t():uid(0){} 48 | virtual ~user_command_t(){} 49 | bin_decoder_t& decoder() { return m_decoder; } 50 | bin_encoder_t& encoder() { return m_encoder; } 51 | virtual string encode() 52 | { 53 | encoder() << uid; 54 | enc(); 55 | return encoder().get_buff(); 56 | } 57 | virtual void decode(const string& src_buff_) 58 | { 59 | decoder().init(src_buff_) >> uid; 60 | dec(); 61 | } 62 | virtual void enc() = 0; 63 | virtual void dec() = 0; 64 | 65 | int64_t get_id() const { return uid; } 66 | void set_id(int64_t id_) { uid = id_; } 67 | private: 68 | bin_decoder_t m_decoder; 69 | bin_encoder_t m_encoder; 70 | public: 71 | int64_t uid; 72 | }; 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /fflib/cqrs/event_i.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_EVENT_I_ 3 | #define _FF_EVENT_I_ 4 | 5 | #include "base/fftype.h" 6 | 7 | namespace ff 8 | { 9 | 10 | class event_i: public type_i 11 | { 12 | public: 13 | virtual ~event_i(){} 14 | }; 15 | 16 | template 17 | class event_t: public auto_type_t 18 | { 19 | public: 20 | virtual ~event_t(){} 21 | }; 22 | 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /fflib/db/db_ops.h: -------------------------------------------------------------------------------- 1 | #ifndef _FF_DB_OPS_H_ 2 | #define _FF_DB_OPS_H_ 3 | 4 | #include 5 | 6 | 7 | namespace ff 8 | { 9 | 10 | class db_each_row_callback_i 11 | { 12 | public: 13 | virtual ~db_each_row_callback_i() {} 14 | virtual void callback(int col_num_, char** col_datas_, char** col_names_, long* col_length_) = 0; 15 | }; 16 | 17 | class db_ops_i 18 | { 19 | public: 20 | virtual ~db_ops_i(){} 21 | 22 | virtual int connect(const std::string& args_) = 0; 23 | virtual bool is_connected() = 0; 24 | virtual int exe_sql(const std::string& sql_, db_each_row_callback_i* cb_) = 0; 25 | virtual void close() = 0; 26 | virtual int affected_rows() = 0; 27 | virtual const char* error_msg() = 0; 28 | 29 | virtual int ping() = 0; 30 | virtual void begin_transaction() = 0; 31 | virtual void commit_transaction() = 0; 32 | virtual void rollback_transaction() = 0; 33 | }; 34 | 35 | } 36 | #endif 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /fflib/db/ffdb.h: -------------------------------------------------------------------------------- 1 | 2 | //! 封装db的操作 3 | #ifndef _FFDB_H_ 4 | #define _FFDB_H_ 5 | 6 | #include 7 | #include 8 | 9 | 10 | #include "db/db_ops.h" 11 | 12 | namespace ff 13 | { 14 | 15 | class each_row_common_cb_t: public db_each_row_callback_i 16 | { 17 | public: 18 | each_row_common_cb_t(std::vector >* data_, std::vector* col_name_): 19 | m_all_data(data_), 20 | m_col_name(col_name_) 21 | {} 22 | virtual void callback(int col_num_, char** col_datas_, char** col_names_, long* col_length_) 23 | { 24 | (*m_all_data).push_back(std::vector()); 25 | std::vector& data = (*m_all_data)[(*m_all_data).size() - 1]; 26 | data.resize(col_num_); 27 | for (int i = 0; i < col_num_; ++i) 28 | { 29 | if (col_datas_[i]) 30 | { 31 | data[i].assign(col_datas_[i], col_length_[i]); 32 | } 33 | } 34 | if (m_col_name && (*m_col_name).empty()) 35 | { 36 | (*m_col_name).resize(col_num_); 37 | for (int i = 0; i < col_num_; ++i) 38 | { 39 | if (col_names_[i]) 40 | (*m_col_name)[i].assign(col_names_[i]); 41 | } 42 | } 43 | } 44 | private: 45 | std::vector >* m_all_data; 46 | std::vector* m_col_name; 47 | }; 48 | 49 | class ffdb_t 50 | { 51 | public: 52 | ffdb_t(); 53 | ~ffdb_t(); 54 | 55 | static std::string escape(const std::string& src_); 56 | static void dump(std::vector >& ret_data, std::vector& col_names_); 57 | 58 | int connect(const std::string& args_); 59 | bool is_connected(); 60 | void close(); 61 | int affected_rows(); 62 | const char* error_msg(); 63 | 64 | int exe_sql(const std::string& sql_, db_each_row_callback_i* cb_ = NULL); 65 | int exe_sql(const std::string& sql_, std::vector >& ret_data_); 66 | int exe_sql(const std::string& sql_, std::vector >& ret_data_, std::vector& col_names_); 67 | 68 | int ping(); 69 | private: 70 | db_ops_i* m_db_ops; 71 | }; 72 | 73 | } 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /fflib/db/mysql_ops.h: -------------------------------------------------------------------------------- 1 | #ifndef _MYSQL_OPS_H_ 2 | #define _MYSQL_OPS_H_ 3 | 4 | extern "C"{ 5 | #include 6 | #include 7 | } 8 | 9 | #include 10 | 11 | 12 | #include "db/db_ops.h" 13 | #include "base/lock.h" 14 | 15 | namespace ff 16 | { 17 | 18 | class mysql_ops_t : public db_ops_i 19 | { 20 | static mutex_t g_mutex; 21 | 22 | public: 23 | mysql_ops_t(); 24 | virtual ~mysql_ops_t(); 25 | 26 | virtual int connect(const std::string& args_); 27 | virtual bool is_connected(); 28 | virtual int exe_sql(const std::string& sql_, db_each_row_callback_i* cb_); 29 | virtual void close(); 30 | virtual int affected_rows() { return m_affected_rows_num; } 31 | virtual const char* error_msg(); 32 | 33 | virtual void begin_transaction(); 34 | virtual void commit_transaction(); 35 | virtual void rollback_transaction(); 36 | virtual int ping(); 37 | 38 | private: 39 | void clear_env(); 40 | private: 41 | std::string m_host_arg; 42 | MYSQL m_mysql; 43 | bool m_connected; 44 | std::string m_error; 45 | int m_affected_rows_num; 46 | 47 | }; 48 | } 49 | #endif 50 | 51 | -------------------------------------------------------------------------------- /fflib/db/sqlite_ops.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_SQLITE_OPS_H_ 3 | #define _FF_SQLITE_OPS_H_ 4 | 5 | #include "db/db_ops.h" 6 | #include "db/sqlite3.h" 7 | 8 | #include 9 | 10 | 11 | namespace ff 12 | { 13 | 14 | class sqlite_ops_t : public db_ops_i 15 | { 16 | public: 17 | struct callback_info_t 18 | { 19 | callback_info_t(sqlite_ops_t* p = NULL): 20 | obj(p), 21 | callback(NULL) 22 | {} 23 | sqlite_ops_t* obj; 24 | db_each_row_callback_i* callback; 25 | std::vector length_buff; 26 | }; 27 | public: 28 | sqlite_ops_t(); 29 | virtual ~sqlite_ops_t(); 30 | 31 | virtual int connect(const std::string& args_); 32 | virtual bool is_connected(); 33 | virtual int exe_sql(const std::string& sql_, db_each_row_callback_i* cb_); 34 | virtual void close(); 35 | virtual int affected_rows() { return m_affected_rows_num; } 36 | virtual const char* error_msg(); 37 | 38 | void inc_affect_row_num() { ++ m_affected_rows_num; } 39 | 40 | 41 | virtual void begin_transaction(); 42 | virtual void commit_transaction(); 43 | virtual void rollback_transaction(); 44 | virtual int ping() { return 0; } 45 | private: 46 | void clear_env(); 47 | private: 48 | sqlite3* m_sqlite; 49 | bool m_connected; 50 | std::string m_error; 51 | int m_affected_rows_num; 52 | callback_info_t m_callback_info; 53 | }; 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /fflib/ext/algorithm/astar/astar.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _A_STAR_H_ 3 | #define _A_STAR_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | namespace ff { 13 | 14 | class astar_t { 15 | public: 16 | 17 | }; 18 | 19 | 20 | class astar_impl_t { 21 | 22 | enum pos_pass_flag_e 23 | { 24 | CAN_PASS = 0, 25 | CAN_NOT_PASS 26 | }; 27 | public: 28 | struct pos_t 29 | { 30 | pos_t(): x(0), y(0){} 31 | uint32_t x; 32 | uint32_t y; 33 | }; 34 | struct pos_search_info_t 35 | { 36 | void set_g_h(uint32_t g_, uint32_t h_) { g = g_; h = h_; f = g + h; } 37 | void set_pos(uint32_t x_, uint32_t y_, uint32_t index_) 38 | { x = x_; y = y_; index = index_;} 39 | uint32_t index; 40 | uint32_t parent_index; 41 | uint32_t x; 42 | uint32_t y; 43 | uint32_t g; 44 | uint32_t h; 45 | uint32_t f; 46 | }; 47 | public: 48 | astar_impl_t(); 49 | int init(uint32_t width_, uint32_t height_); 50 | 51 | int change_pos_state(uint32_t index_, int flag_); 52 | 53 | int search_path(uint32_t from_x_, uint32_t from_y_, uint32_t to_x_, uint32_t to_y_, vector& path_); 54 | 55 | private: 56 | uint32_t distance(uint32_t from_x_, uint32_t from_y_, uint32_t to_x_, uint32_t to_y_); 57 | private: 58 | uint32_t m_width; 59 | uint32_t m_height; 60 | vector m_area; 61 | }; 62 | 63 | } 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /fflib/ext/algorithm/astar/astar_element.h: -------------------------------------------------------------------------------- 1 | #ifndef _A_STAR_ELEMENT_H_ 2 | #define _A_STAR_ELEMENT_H_ 3 | 4 | #include 5 | 6 | class astar_element_t 7 | { 8 | public: 9 | void set(); 10 | uint32_t get(); 11 | 12 | private: 13 | uint32_t m_index_num; 14 | }; 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /fflib/ext/generator/README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanchy/fflib/ee6a1ba918b444ceb5e86a25dbf7c4a236494709/fflib/ext/generator/README.txt -------------------------------------------------------------------------------- /fflib/ext/generator/example.idl: -------------------------------------------------------------------------------- 1 | 2 | struct get_friends_req_t 3 | { 4 | uint32 uid; 5 | }; 6 | 7 | 8 | struct all_friends_ret_t 9 | { 10 | array friends; 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /fflib/ext/generator/idl_generator.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | from pylib.inc import * 4 | from pylib.src_parser import src_parser_t 5 | from pylib.code_generator import code_generator_t 6 | 7 | 8 | if __name__ =='__main__': 9 | if len(sys.argv) < 3: 10 | print('Usage: %s idl_filename dest_file_name' % (sys.argv[0])) 11 | exit(0) 12 | idl_filename = sys.argv[1] 13 | dest_file_name = sys.argv[2] 14 | 15 | p = src_parser_t(idl_filename) 16 | p.exe() 17 | mgr = p.get_struct_def_mgr() 18 | mgr.dump() 19 | cg = code_generator_t(mgr, dest_file_name) 20 | cg.exe() 21 | 22 | -------------------------------------------------------------------------------- /fflib/ext/generator/json_outstream.cpp: -------------------------------------------------------------------------------- 1 | #include "json_outstream.h" 2 | 3 | json_outstream_t::json_outstream_t(rapidjson::Document::AllocatorType& a): 4 | m_allocator(a) 5 | { 6 | } 7 | 8 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, int8_t dest_) 9 | { 10 | jval_.AddMember(filed_name_, dest_, m_allocator); 11 | return *this; 12 | } 13 | 14 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, uint8_t dest_) 15 | { 16 | jval_.AddMember(filed_name_, dest_, m_allocator); 17 | return *this; 18 | } 19 | 20 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, int16_t dest_) 21 | { 22 | jval_.AddMember(filed_name_, dest_, m_allocator); 23 | return *this; 24 | } 25 | 26 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, uint16_t dest_) 27 | { 28 | jval_.AddMember(filed_name_, dest_, m_allocator); 29 | return *this; 30 | } 31 | 32 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, int32_t dest_) 33 | { 34 | jval_.AddMember(filed_name_, dest_, m_allocator); 35 | return *this; 36 | } 37 | 38 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, uint32_t dest_) 39 | { 40 | jval_.AddMember(filed_name_, dest_, m_allocator); 41 | return *this; 42 | } 43 | 44 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, int64_t dest_) 45 | { 46 | jval_.AddMember(filed_name_, dest_, m_allocator); 47 | return *this; 48 | } 49 | 50 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, uint64_t dest_) 51 | { 52 | jval_.AddMember(filed_name_, dest_, m_allocator); 53 | return *this; 54 | } 55 | 56 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, bool dest_) 57 | { 58 | jval_.AddMember(filed_name_, dest_, m_allocator); 59 | return *this; 60 | } 61 | 62 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, float dest_) 63 | { 64 | jval_.AddMember(filed_name_, dest_, m_allocator); 65 | return *this; 66 | } 67 | 68 | json_outstream_t& json_outstream_t::encode(const char* filed_name_, json_value_t& jval_, const string& dest_) 69 | { 70 | json_value_t tmp_val(dest_.c_str(), dest_.length(), m_allocator); 71 | jval_.AddMember(filed_name_, tmp_val, m_allocator); 72 | return *this; 73 | } 74 | -------------------------------------------------------------------------------- /fflib/ext/generator/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | #include "rapidjson/document.h" // rapidjson's DOM-style API 10 | #include "rapidjson/prettywriter.h" // for stringify JSON 11 | #include "rapidjson/filestream.h" // wrapper of C stream for prettywriter as output 12 | //! using namespace rapidjson; 13 | 14 | #include "msg_def.h" 15 | 16 | class socket_t 17 | { 18 | public: 19 | void async_write(msg_ptr_t msg_) 20 | { 21 | //! TODO do io write 22 | cout <<"wile send:" << msg_->encode_json() <<"\n"; 23 | } 24 | }; 25 | 26 | typedef socket_t* socket_ptr_t; 27 | 28 | class logic_service_t 29 | { 30 | public: 31 | void handle(shared_ptr_t req_, socket_ptr_t sock_) 32 | { 33 | cout << "req uid:" << req_->uid <<"\n"; 34 | //! DO some logic code 35 | shared_ptr_t msg(new all_friends_ret_t()); 36 | 37 | for (int i = 0; i < 10; ++i) 38 | msg->friends.push_back(i); 39 | 40 | sock_->async_write(msg); 41 | } 42 | }; 43 | 44 | 45 | int main(int argc, char* argv[]) 46 | { 47 | try 48 | { 49 | string tmp = "{\"get_friends_req_t\":{\"uid\":12345}}"; 50 | logic_service_t logic_service; 51 | msg_dispather_t msg_dispather(logic_service); 52 | //! ÕâÀïʵ¼ÊÉÏÓ¦¸Ã±»ÍøÂç²ãµ÷Óà 53 | socket_ptr_t sock = new socket_t(); 54 | msg_dispather.dispath(tmp, sock); 55 | } 56 | catch(exception& e) 57 | { 58 | cout <<"e:"<< e.what() <<"\n"; 59 | } 60 | cout <<"main end ok\n"; 61 | } 62 | -------------------------------------------------------------------------------- /fflib/ext/generator/pylib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanchy/fflib/ee6a1ba918b444ceb5e86a25dbf7c4a236494709/fflib/ext/generator/pylib/__init__.py -------------------------------------------------------------------------------- /fflib/ext/generator/rapidjson/filereadstream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 2 | #define RAPIDJSON_FILEREADSTREAM_H_ 3 | 4 | #include "rapidjson.h" 5 | #include 6 | 7 | namespace rapidjson { 8 | 9 | //! File byte stream for input using fread(). 10 | /*! 11 | \implements Stream 12 | */ 13 | class FileReadStream { 14 | public: 15 | typedef char Ch; //!< Character type (byte). 16 | 17 | //! Constructor. 18 | /*! 19 | \param fp File pointer opened for read. 20 | \param buffer user-supplied buffer. 21 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 22 | */ 23 | FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 24 | RAPIDJSON_ASSERT(fp_ != 0); 25 | RAPIDJSON_ASSERT(bufferSize >= 4); 26 | Read(); 27 | } 28 | 29 | Ch Peek() const { return *current_; } 30 | Ch Take() { Ch c = *current_; Read(); return c; } 31 | size_t Tell() const { return count_ + (current_ - buffer_); } 32 | 33 | // Not implemented 34 | void Put(Ch c) { RAPIDJSON_ASSERT(false); } 35 | void Flush() { RAPIDJSON_ASSERT(false); } 36 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 37 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 38 | 39 | // For encoding detection only. 40 | const Ch* Peek4() const { 41 | return (current_ + 4 <= bufferLast_) ? current_ : 0; 42 | } 43 | 44 | private: 45 | void Read() { 46 | if (current_ < bufferLast_) 47 | ++current_; 48 | else if (!eof_) { 49 | count_ += readCount_; 50 | readCount_ = fread(buffer_, 1, bufferSize_, fp_); 51 | bufferLast_ = buffer_ + readCount_ - 1; 52 | current_ = buffer_; 53 | 54 | if (readCount_ < bufferSize_) { 55 | buffer_[readCount_] = '\0'; 56 | ++bufferLast_; 57 | eof_ = true; 58 | } 59 | } 60 | } 61 | 62 | FILE* fp_; 63 | Ch *buffer_; 64 | size_t bufferSize_; 65 | Ch *bufferLast_; 66 | Ch *current_; 67 | size_t readCount_; 68 | size_t count_; //!< Number of characters read 69 | bool eof_; 70 | }; 71 | 72 | } // namespace rapidjson 73 | 74 | #endif // RAPIDJSON_FILESTREAM_H_ 75 | -------------------------------------------------------------------------------- /fflib/ext/generator/rapidjson/filestream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILESTREAM_H_ 2 | #define RAPIDJSON_FILESTREAM_H_ 3 | 4 | #include "rapidjson.h" 5 | #include 6 | 7 | namespace rapidjson { 8 | 9 | //! (Depreciated) Wrapper of C file stream for input or output. 10 | /*! 11 | This simple wrapper does not check the validity of the stream. 12 | \implements Stream 13 | \deprecated { This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. } 14 | */ 15 | class FileStream { 16 | public: 17 | typedef char Ch; //!< Character type. Only support char. 18 | 19 | FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); } 20 | char Peek() const { return current_; } 21 | char Take() { char c = current_; Read(); return c; } 22 | size_t Tell() const { return count_; } 23 | void Put(char c) { fputc(c, fp_); } 24 | void Flush() { fflush(fp_); } 25 | 26 | // Not implemented 27 | char* PutBegin() { return 0; } 28 | size_t PutEnd(char*) { return 0; } 29 | 30 | private: 31 | void Read() { 32 | RAPIDJSON_ASSERT(fp_ != 0); 33 | int c = fgetc(fp_); 34 | if (c != EOF) { 35 | current_ = (char)c; 36 | count_++; 37 | } 38 | else if (current_ != '\0') 39 | current_ = '\0'; 40 | } 41 | 42 | FILE* fp_; 43 | char current_; 44 | size_t count_; 45 | }; 46 | 47 | } // namespace rapidjson 48 | 49 | #endif // RAPIDJSON_FILESTREAM_H_ 50 | -------------------------------------------------------------------------------- /fflib/ext/generator/rapidjson/filewritestream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 2 | #define RAPIDJSON_FILEWRITESTREAM_H_ 3 | 4 | #include "rapidjson.h" 5 | #include 6 | 7 | namespace rapidjson { 8 | 9 | //! Wrapper of C file stream for input using fread(). 10 | /*! 11 | \implements Stream 12 | */ 13 | class FileWriteStream { 14 | public: 15 | typedef char Ch; //!< Character type. Only support char. 16 | 17 | FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 18 | RAPIDJSON_ASSERT(fp_ != 0); 19 | } 20 | 21 | void Put(char c) { 22 | if (current_ >= bufferEnd_) 23 | Flush(); 24 | 25 | *current_++ = c; 26 | } 27 | 28 | void PutN(char c, size_t n) { 29 | size_t avail = bufferEnd_ - current_; 30 | while (n > avail) { 31 | memset(current_, c, avail); 32 | current_ += avail; 33 | Flush(); 34 | n -= avail; 35 | avail = bufferEnd_ - current_; 36 | } 37 | 38 | if (n > 0) { 39 | memset(current_, c, n); 40 | current_ += n; 41 | } 42 | } 43 | 44 | void Flush() { 45 | if (current_ != buffer_) { 46 | fwrite(buffer_, 1, current_ - buffer_, fp_); 47 | current_ = buffer_; 48 | } 49 | } 50 | 51 | // Not implemented 52 | char Peek() const { RAPIDJSON_ASSERT(false); } 53 | char Take() { RAPIDJSON_ASSERT(false); } 54 | size_t Tell() const { RAPIDJSON_ASSERT(false); } 55 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 56 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 57 | 58 | private: 59 | FILE* fp_; 60 | char *buffer_; 61 | char *bufferEnd_; 62 | char *current_; 63 | }; 64 | 65 | //! Implement specialized version of PutN() with memset() for better performance. 66 | template<> 67 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 68 | stream.PutN(c, n); 69 | } 70 | 71 | } // namespace rapidjson 72 | 73 | #endif // RAPIDJSON_FILESTREAM_H_ 74 | -------------------------------------------------------------------------------- /fflib/ext/generator/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 2 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 3 | 4 | namespace rapidjson { 5 | namespace internal { 6 | 7 | //! Custom strlen() which works on different character types. 8 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 9 | \param s Null-terminated input string. 10 | \return Number of characters in the string. 11 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 12 | */ 13 | template 14 | inline SizeType StrLen(const Ch* s) { 15 | const Ch* p = s; 16 | while (*p != '\0') 17 | ++p; 18 | return SizeType(p - s); 19 | } 20 | 21 | } // namespace internal 22 | } // namespace rapidjson 23 | 24 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 25 | -------------------------------------------------------------------------------- /fflib/ext/generator/rapidjson/stringbuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 2 | #define RAPIDJSON_STRINGBUFFER_H_ 3 | 4 | #include "rapidjson.h" 5 | #include "internal/stack.h" 6 | 7 | namespace rapidjson { 8 | 9 | //! Represents an in-memory output stream. 10 | /*! 11 | \tparam Encoding Encoding of the stream. 12 | \tparam Allocator type for allocating memory buffer. 13 | \implements Stream 14 | */ 15 | template 16 | struct GenericStringBuffer { 17 | typedef typename Encoding::Ch Ch; 18 | 19 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 20 | 21 | void Put(Ch c) { *stack_.template Push() = c; } 22 | void Flush() {} 23 | 24 | void Clear() { stack_.Clear(); } 25 | 26 | const Ch* GetString() const { 27 | // Push and pop a null terminator. This is safe. 28 | *stack_.template Push() = '\0'; 29 | stack_.template Pop(1); 30 | 31 | return stack_.template Bottom(); 32 | } 33 | 34 | size_t GetSize() const { return stack_.GetSize(); } 35 | 36 | static const size_t kDefaultCapacity = 256; 37 | mutable internal::Stack stack_; 38 | }; 39 | 40 | typedef GenericStringBuffer > StringBuffer; 41 | 42 | //! Implement specialized version of PutN() with memset() for better performance. 43 | template<> 44 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 45 | memset(stream.stack_.Push(n), c, n * sizeof(c)); 46 | } 47 | 48 | } // namespace rapidjson 49 | 50 | #endif // RAPIDJSON_STRINGBUFFER_H_ 51 | -------------------------------------------------------------------------------- /fflib/ext/generator/run.sh: -------------------------------------------------------------------------------- 1 | g++ -Wall -g -O2 main.cc *.cpp -o app_test 2 | -------------------------------------------------------------------------------- /fflib/ext/generator/smart_ptr/ref_count.h: -------------------------------------------------------------------------------- 1 | #ifndef _REF_COUNT_H_ 2 | #define _REF_COUNT_H_ 3 | 4 | #define ATOMIC_ADD(src_ptr, v) (void)__sync_add_and_fetch(src, v) 5 | #define ATOMIC_SUB_AND_FETCH(src_ptr, v) __sync_sub_and_fetch(src, v) 6 | 7 | class ref_count_t 8 | { 9 | typedef volatile long atomic_t; 10 | public: 11 | ref_count_t(): 12 | m_ref_num(1) 13 | {} 14 | ~ref_count_t() 15 | {} 16 | 17 | inline void inc() 18 | { 19 | //ATOMIC_ADD(&m_ref_num, 1); 20 | ++m_ref_num; 21 | } 22 | inline bool dec_and_check_zero() 23 | { 24 | return 0 == --m_ref_num;//ATOMIC_SUB_AND_FETCH((&m_ref_num, 1); 25 | } 26 | inline atomic_t size() 27 | { 28 | return m_ref_num; 29 | } 30 | 31 | private: 32 | atomic_t m_ref_num; 33 | }; 34 | #endif 35 | -------------------------------------------------------------------------------- /fflib/ext/log/log.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOG_H_ 2 | #define _LOG_H_ 3 | 4 | #include 5 | #include 6 | 7 | struct log_t 8 | { 9 | static int log_impl(const char* mod, const char* fmt, ...) 10 | { 11 | char buff[256]; 12 | int len = snprintf(buff, sizeof(buff), "%s ", mod); 13 | 14 | va_list vl; 15 | va_start(vl, fmt); 16 | vsnprintf(buff + len, sizeof(buff) - len - 1, fmt, vl); 17 | va_end(vl); 18 | printf("%s", buff); 19 | return 0; 20 | } 21 | }; 22 | 23 | #define BROKER "BROKER" 24 | #define RPC "RPC" 25 | #define FF "FF" 26 | #define MSG_BUS "MSG_BUS" 27 | 28 | #define logdebug(content) {}//printf("\033[1;33mDEBUG "); log_t::log_impl content ; printf("\033[0m\n") 29 | #define logtrace(content) {}//printf("TRACE "); log_t::log_impl content ; printf("\n") 30 | #define loginfo(content) {}//printf("\033[1;32mINFO "); log_t::log_impl content ; printf("\033[0m\n") 31 | #define logwarn(content) printf("\033[1;34mWARN "); log_t::log_impl content ; printf("\033[0m\n") 32 | #define logerror(content) printf("\033[0;31mERROR "); log_t::log_impl content ; printf("\033[0m\n") 33 | #define logfatal(content) printf("\033[0;35mFATAL "); log_t::log_impl content ; printf("\033[0m") 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /fflib/ext/rapidjson/filereadstream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 2 | #define RAPIDJSON_FILEREADSTREAM_H_ 3 | 4 | #include "rapidjson.h" 5 | #include 6 | 7 | namespace rapidjson { 8 | 9 | //! File byte stream for input using fread(). 10 | /*! 11 | \implements Stream 12 | */ 13 | class FileReadStream { 14 | public: 15 | typedef char Ch; //!< Character type (byte). 16 | 17 | //! Constructor. 18 | /*! 19 | \param fp File pointer opened for read. 20 | \param buffer user-supplied buffer. 21 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 22 | */ 23 | FileReadStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 24 | RAPIDJSON_ASSERT(fp_ != 0); 25 | RAPIDJSON_ASSERT(bufferSize >= 4); 26 | Read(); 27 | } 28 | 29 | Ch Peek() const { return *current_; } 30 | Ch Take() { Ch c = *current_; Read(); return c; } 31 | size_t Tell() const { return count_ + (current_ - buffer_); } 32 | 33 | // Not implemented 34 | void Put(Ch c) { RAPIDJSON_ASSERT(false); } 35 | void Flush() { RAPIDJSON_ASSERT(false); } 36 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 37 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 38 | 39 | // For encoding detection only. 40 | const Ch* Peek4() const { 41 | return (current_ + 4 <= bufferLast_) ? current_ : 0; 42 | } 43 | 44 | private: 45 | void Read() { 46 | if (current_ < bufferLast_) 47 | ++current_; 48 | else if (!eof_) { 49 | count_ += readCount_; 50 | readCount_ = fread(buffer_, 1, bufferSize_, fp_); 51 | bufferLast_ = buffer_ + readCount_ - 1; 52 | current_ = buffer_; 53 | 54 | if (readCount_ < bufferSize_) { 55 | buffer_[readCount_] = '\0'; 56 | ++bufferLast_; 57 | eof_ = true; 58 | } 59 | } 60 | } 61 | 62 | FILE* fp_; 63 | Ch *buffer_; 64 | size_t bufferSize_; 65 | Ch *bufferLast_; 66 | Ch *current_; 67 | size_t readCount_; 68 | size_t count_; //!< Number of characters read 69 | bool eof_; 70 | }; 71 | 72 | } // namespace rapidjson 73 | 74 | #endif // RAPIDJSON_FILESTREAM_H_ 75 | -------------------------------------------------------------------------------- /fflib/ext/rapidjson/filestream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILESTREAM_H_ 2 | #define RAPIDJSON_FILESTREAM_H_ 3 | 4 | #include "rapidjson.h" 5 | #include 6 | 7 | namespace rapidjson { 8 | 9 | //! (Depreciated) Wrapper of C file stream for input or output. 10 | /*! 11 | This simple wrapper does not check the validity of the stream. 12 | \implements Stream 13 | \deprecated { This was only for basic testing in version 0.1, it is found that the performance is very low by using fgetc(). Use FileReadStream instead. } 14 | */ 15 | class FileStream { 16 | public: 17 | typedef char Ch; //!< Character type. Only support char. 18 | 19 | FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); } 20 | char Peek() const { return current_; } 21 | char Take() { char c = current_; Read(); return c; } 22 | size_t Tell() const { return count_; } 23 | void Put(char c) { fputc(c, fp_); } 24 | void Flush() { fflush(fp_); } 25 | 26 | // Not implemented 27 | char* PutBegin() { return 0; } 28 | size_t PutEnd(char*) { return 0; } 29 | 30 | private: 31 | void Read() { 32 | RAPIDJSON_ASSERT(fp_ != 0); 33 | int c = fgetc(fp_); 34 | if (c != EOF) { 35 | current_ = (char)c; 36 | count_++; 37 | } 38 | else if (current_ != '\0') 39 | current_ = '\0'; 40 | } 41 | 42 | FILE* fp_; 43 | char current_; 44 | size_t count_; 45 | }; 46 | 47 | } // namespace rapidjson 48 | 49 | #endif // RAPIDJSON_FILESTREAM_H_ 50 | -------------------------------------------------------------------------------- /fflib/ext/rapidjson/filewritestream.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 2 | #define RAPIDJSON_FILEWRITESTREAM_H_ 3 | 4 | #include "rapidjson.h" 5 | #include 6 | 7 | namespace rapidjson { 8 | 9 | //! Wrapper of C file stream for input using fread(). 10 | /*! 11 | \implements Stream 12 | */ 13 | class FileWriteStream { 14 | public: 15 | typedef char Ch; //!< Character type. Only support char. 16 | 17 | FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 18 | RAPIDJSON_ASSERT(fp_ != 0); 19 | } 20 | 21 | void Put(char c) { 22 | if (current_ >= bufferEnd_) 23 | Flush(); 24 | 25 | *current_++ = c; 26 | } 27 | 28 | void PutN(char c, size_t n) { 29 | size_t avail = bufferEnd_ - current_; 30 | while (n > avail) { 31 | memset(current_, c, avail); 32 | current_ += avail; 33 | Flush(); 34 | n -= avail; 35 | avail = bufferEnd_ - current_; 36 | } 37 | 38 | if (n > 0) { 39 | memset(current_, c, n); 40 | current_ += n; 41 | } 42 | } 43 | 44 | void Flush() { 45 | if (current_ != buffer_) { 46 | fwrite(buffer_, 1, current_ - buffer_, fp_); 47 | current_ = buffer_; 48 | } 49 | } 50 | 51 | // Not implemented 52 | char Peek() const { RAPIDJSON_ASSERT(false); } 53 | char Take() { RAPIDJSON_ASSERT(false); } 54 | size_t Tell() const { RAPIDJSON_ASSERT(false); } 55 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 56 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 57 | 58 | private: 59 | FILE* fp_; 60 | char *buffer_; 61 | char *bufferEnd_; 62 | char *current_; 63 | }; 64 | 65 | //! Implement specialized version of PutN() with memset() for better performance. 66 | template<> 67 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 68 | stream.PutN(c, n); 69 | } 70 | 71 | } // namespace rapidjson 72 | 73 | #endif // RAPIDJSON_FILESTREAM_H_ 74 | -------------------------------------------------------------------------------- /fflib/ext/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 2 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 3 | 4 | namespace rapidjson { 5 | namespace internal { 6 | 7 | //! Custom strlen() which works on different character types. 8 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 9 | \param s Null-terminated input string. 10 | \return Number of characters in the string. 11 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 12 | */ 13 | template 14 | inline SizeType StrLen(const Ch* s) { 15 | const Ch* p = s; 16 | while (*p != '\0') 17 | ++p; 18 | return SizeType(p - s); 19 | } 20 | 21 | } // namespace internal 22 | } // namespace rapidjson 23 | 24 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 25 | -------------------------------------------------------------------------------- /fflib/ext/rapidjson/stringbuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDJSON_STRINGBUFFER_H_ 2 | #define RAPIDJSON_STRINGBUFFER_H_ 3 | 4 | #include "rapidjson.h" 5 | #include "internal/stack.h" 6 | 7 | namespace rapidjson { 8 | 9 | //! Represents an in-memory output stream. 10 | /*! 11 | \tparam Encoding Encoding of the stream. 12 | \tparam Allocator type for allocating memory buffer. 13 | \implements Stream 14 | */ 15 | template 16 | struct GenericStringBuffer { 17 | typedef typename Encoding::Ch Ch; 18 | 19 | GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 20 | 21 | void Put(Ch c) { *stack_.template Push() = c; } 22 | void Flush() {} 23 | 24 | void Clear() { stack_.Clear(); } 25 | 26 | const Ch* GetString() const { 27 | // Push and pop a null terminator. This is safe. 28 | *stack_.template Push() = '\0'; 29 | stack_.template Pop(1); 30 | 31 | return stack_.template Bottom(); 32 | } 33 | 34 | size_t GetSize() const { return stack_.GetSize(); } 35 | 36 | static const size_t kDefaultCapacity = 256; 37 | mutable internal::Stack stack_; 38 | }; 39 | 40 | typedef GenericStringBuffer > StringBuffer; 41 | 42 | //! Implement specialized version of PutN() with memset() for better performance. 43 | template<> 44 | inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { 45 | memset(stream.stack_.Push(n), c, n * sizeof(c)); 46 | } 47 | 48 | } // namespace rapidjson 49 | 50 | #endif // RAPIDJSON_STRINGBUFFER_H_ 51 | -------------------------------------------------------------------------------- /fflib/gtest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /fflib/gtest/src/gtest-all.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /fflib/gtest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | std::cout << "Running main() from gtest_main.cc\n"; 36 | 37 | testing::InitGoogleTest(&argc, argv); 38 | return RUN_ALL_TESTS(); 39 | } 40 | -------------------------------------------------------------------------------- /fflib/net/acceptor_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _ACCEPTOR_I_ 2 | #define _ACCEPTOR_I_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | #include "netbase.h" 9 | 10 | namespace ff { 11 | 12 | class acceptor_i: public fd_i 13 | { 14 | public: 15 | virtual ~acceptor_i(){} 16 | virtual int open(const string& address_) = 0; 17 | 18 | int handle_epoll_write(){ return -1; } 19 | }; 20 | 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /fflib/net/acceptor_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef _ACCEPTOR_IMPL_H_ 2 | #define _ACCEPTOR_IMPL_H_ 3 | 4 | #include "net/acceptor_i.h" 5 | 6 | namespace ff { 7 | 8 | #define LISTEN_BACKLOG 5 9 | 10 | class epoll_i; 11 | class socket_i; 12 | class msg_handler_i; 13 | class task_queue_pool_t; 14 | 15 | class acceptor_impl_t: public acceptor_i 16 | { 17 | public: 18 | acceptor_impl_t(epoll_i*, msg_handler_i*, task_queue_pool_t* tq_); 19 | ~acceptor_impl_t(); 20 | int open(const string& address_); 21 | void close(); 22 | 23 | int socket() {return m_listen_fd;} 24 | int handle_epoll_read(); 25 | int handle_epoll_del() ; 26 | 27 | protected: 28 | virtual socket_i* create_socket(int); 29 | 30 | protected: 31 | int m_listen_fd; 32 | epoll_i* m_epoll; 33 | msg_handler_i* m_msg_handler; 34 | task_queue_pool_t* m_tq; 35 | }; 36 | 37 | } 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /fflib/net/common_socket_controller.cpp: -------------------------------------------------------------------------------- 1 | #include "net/common_socket_controller.h" 2 | #include "net/socket_i.h" 3 | #include "base/strtool.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | using namespace ff; 13 | 14 | common_socket_controller_t::common_socket_controller_t(msg_handler_ptr_t msg_handler_): 15 | m_msg_handler(msg_handler_), 16 | m_have_recv_size(0) 17 | { 18 | } 19 | 20 | common_socket_controller_t::~common_socket_controller_t() 21 | { 22 | } 23 | 24 | //! when socket broken(whenever), this function will be called 25 | //! this func just callback logic layer to process this event 26 | //! each socket broken event only can happen once 27 | //! logic layer has responsibily to deconstruct the socket object 28 | int common_socket_controller_t::handle_error(socket_i* sp_) 29 | { 30 | m_msg_handler->handle_broken(sp_); 31 | return 0; 32 | } 33 | 34 | int common_socket_controller_t::handle_read(socket_i* sp_, char* buff, size_t len) 35 | { 36 | size_t left_len = len; 37 | size_t tmp = 0; 38 | 39 | while (left_len > 0) 40 | { 41 | if (false == m_message.have_recv_head(m_have_recv_size)) 42 | { 43 | tmp = m_message.append_head(m_have_recv_size, buff, left_len); 44 | 45 | m_have_recv_size += tmp; 46 | left_len -= tmp; 47 | buff += tmp; 48 | } 49 | 50 | tmp = m_message.append_msg(buff, left_len); 51 | m_have_recv_size += tmp; 52 | left_len -= tmp; 53 | buff += tmp; 54 | 55 | if (m_message.get_body().size() == m_message.size()) 56 | { 57 | m_msg_handler->handle_msg(m_message, sp_); 58 | m_have_recv_size = 0; 59 | m_message.clear(); 60 | } 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | //! 当数据全部发送完毕后,此函数会被回调 67 | int common_socket_controller_t::handle_write_completed(socket_i* sp_) 68 | { 69 | return 0; 70 | } 71 | 72 | int common_socket_controller_t::check_pre_send(socket_i* sp_, string& buff_) 73 | { 74 | if (sp_->socket() < 0) 75 | { 76 | return -1; 77 | } 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /fflib/net/common_socket_controller.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_SOCKET_CONTROLLER_H_ 2 | #define _COMMON_SOCKET_CONTROLLER_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "net/socket_controller_i.h" 8 | #include "net/message.h" 9 | #include "net/msg_handler_i.h" 10 | 11 | namespace ff { 12 | 13 | class socket_i; 14 | 15 | class common_socket_controller_t: public socket_controller_i 16 | { 17 | public: 18 | common_socket_controller_t(msg_handler_ptr_t msg_handler_); 19 | ~common_socket_controller_t(); 20 | virtual int handle_error(socket_i*); 21 | virtual int handle_read(socket_i*, char* buff, size_t len); 22 | virtual int handle_write_completed(socket_i*); 23 | 24 | virtual int check_pre_send(socket_i*, string& buff_); 25 | 26 | protected: 27 | msg_handler_ptr_t m_msg_handler; 28 | size_t m_have_recv_size; 29 | message_t m_message; 30 | }; 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /fflib/net/connector.h: -------------------------------------------------------------------------------- 1 | 2 | //!  连接器 3 | #ifndef _CONNECTOR_H_ 4 | #define _CONNECTOR_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "net/socket_impl.h" 16 | #include "base/strtool.h" 17 | #include "net/msg_handler_i.h" 18 | #include "net/common_socket_controller.h" 19 | 20 | namespace ff { 21 | 22 | class connector_t 23 | { 24 | public: 25 | static socket_ptr_t connect(const string& host_, epoll_i* e_, msg_handler_i* msg_handler_, task_queue_i* tq_) 26 | { 27 | socket_ptr_t ret = NULL; 28 | //! example tcp://192.168.1.1:1024 29 | vector vt; 30 | strtool::split(host_, vt, "://"); 31 | assert(vt.size() == 2); 32 | 33 | vector vt2; 34 | strtool::split(vt[1], vt2, ":"); 35 | assert(vt2.size() == 2); 36 | 37 | int s; 38 | struct sockaddr_in addr; 39 | 40 | if((s = socket(AF_INET,SOCK_STREAM,0)) < 0) 41 | { 42 | perror("socket"); 43 | return ret; 44 | } 45 | /* 填写sockaddr_in结构*/ 46 | bzero(&addr,sizeof(addr)); 47 | addr.sin_family = AF_INET; 48 | addr.sin_port = htons(atoi(vt2[1].c_str())); 49 | addr.sin_addr.s_addr = inet_addr(vt2[0].c_str()); 50 | /* 尝试连线*/ 51 | if(::connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) 52 | { 53 | perror("connect"); 54 | return ret; 55 | } 56 | 57 | ret = new socket_impl_t(e_, new common_socket_controller_t(msg_handler_), s, tq_); 58 | ret->open(); 59 | return ret; 60 | } 61 | 62 | }; 63 | 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /fflib/net/epoll_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _EPOLL_I_ 2 | #define _EPOLL_I_ 3 | 4 | #include "net/netbase.h" 5 | namespace ff { 6 | 7 | 8 | class epoll_i: public io_demultiplexer_i 9 | { 10 | }; 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /fflib/net/epoll_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef _EPOLL_IMPL_H_ 2 | #define _EPOLL_IMPL_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "net/epoll_i.h" 8 | #include "base/task_queue_i.h" 9 | #include "base/lock.h" 10 | 11 | namespace ff { 12 | 13 | #define CREATE_EPOLL_SIZE 4096 14 | #define EPOLL_EVENTS_SIZE 128 15 | //! 100 ms 16 | #define EPOLL_WAIT_TIME 100 17 | 18 | class epoll_impl_t: public epoll_i 19 | { 20 | public: 21 | epoll_impl_t(); 22 | ~epoll_impl_t(); 23 | 24 | virtual int event_loop(); 25 | virtual int close(); 26 | virtual int register_fd(fd_i*); 27 | virtual int unregister_fd(fd_i*); 28 | virtual int mod_fd(fd_i*); 29 | 30 | int interupt_loop();//! 中断事件循环 31 | protected: 32 | void fd_del_callback(); 33 | 34 | private: 35 | volatile bool m_running; 36 | int m_efd; 37 | task_queue_i* m_task_queue; 38 | int m_interupt_sockets[2]; 39 | //! 待销毁的error socket 40 | list m_error_fd_set; 41 | mutex_t m_mutex; 42 | }; 43 | 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /fflib/net/gateway_acceptor.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "net/gateway_acceptor.h" 3 | #include "net/socket_impl.h" 4 | #include "net/gateway_socket_controller.h" 5 | #include "base/arg_helper.h" 6 | 7 | using namespace ff; 8 | 9 | gateway_acceptor_t::gateway_acceptor_t(epoll_i* e_, msg_handler_i* mh_, task_queue_pool_t* tq_): 10 | acceptor_impl_t(e_, mh_, tq_) 11 | { 12 | 13 | } 14 | 15 | gateway_acceptor_t::~gateway_acceptor_t() 16 | { 17 | 18 | } 19 | 20 | int gateway_acceptor_t::open(const string& args_) 21 | { 22 | arg_helper_t arg_helper(args_); 23 | m_net_stat.start(arg_helper); 24 | 25 | return acceptor_impl_t::open(arg_helper.get_option_value("-gateway_listen")); 26 | } 27 | 28 | socket_i* gateway_acceptor_t::create_socket(int new_fd_) 29 | { 30 | return new socket_impl_t(m_epoll, new gateway_socket_controller_t(m_msg_handler, &m_net_stat), new_fd_, m_tq->alloc(new_fd_)); 31 | } 32 | -------------------------------------------------------------------------------- /fflib/net/gateway_acceptor.h: -------------------------------------------------------------------------------- 1 | #ifndef _GATEWAY_ACCEPTOR_H_ 2 | #define _GATEWAY_ACCEPTOR_H_ 3 | 4 | #include "net/acceptor_impl.h" 5 | #include "net/common_socket_controller.h" 6 | #include "net/net_stat.h" 7 | 8 | namespace ff { 9 | 10 | class gateway_acceptor_t: public acceptor_impl_t 11 | { 12 | public: 13 | gateway_acceptor_t(epoll_i*, msg_handler_i*, task_queue_pool_t* tq_); 14 | ~gateway_acceptor_t(); 15 | 16 | int open(const string& address_); 17 | 18 | protected: 19 | virtual socket_i* create_socket(int new_fd_); 20 | 21 | private: 22 | //! data field 23 | net_stat_t m_net_stat; 24 | }; 25 | 26 | } 27 | #endif 28 | -------------------------------------------------------------------------------- /fflib/net/gateway_socket_controller.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "net/gateway_socket_controller.h" 3 | #include "net/net_stat.h" 4 | 5 | using namespace ff; 6 | 7 | gateway_socket_controller_t::gateway_socket_controller_t(msg_handler_ptr_t msg_handler_, net_stat_t* ns_): 8 | common_socket_controller_t(msg_handler_), 9 | m_net_stat(ns_), 10 | m_last_update_tm(0) 11 | { 12 | 13 | } 14 | 15 | gateway_socket_controller_t::~gateway_socket_controller_t() 16 | { 17 | 18 | } 19 | 20 | int gateway_socket_controller_t::handle_open(socket_i* s_) 21 | { 22 | m_last_update_tm = m_net_stat->get_heartbeat().tick(); 23 | m_net_stat->get_heartbeat().add(s_); 24 | return 0; 25 | } 26 | 27 | int gateway_socket_controller_t::handle_read(socket_i* s_, char* buff, size_t len) 28 | { 29 | common_socket_controller_t::handle_read(s_, buff, len); 30 | 31 | //! 判断消息包是否超过限制 32 | if (true == m_message.have_recv_head(m_have_recv_size) && m_message.size() > (size_t)m_net_stat->get_max_packet_size()) 33 | { 34 | s_->close(); 35 | } 36 | 37 | //! 更新心跳 38 | if (m_last_update_tm != m_net_stat->get_heartbeat().tick()) 39 | { 40 | m_last_update_tm = m_net_stat->get_heartbeat().tick(); 41 | m_net_stat->get_heartbeat().update(s_); 42 | } 43 | return 0; 44 | } 45 | 46 | int gateway_socket_controller_t::handle_error(socket_i* s_) 47 | { 48 | m_net_stat->get_heartbeat().del(s_); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /fflib/net/gateway_socket_controller.h: -------------------------------------------------------------------------------- 1 | #ifndef _GATEWAY_SOCKET_CONTROLLER_H_ 2 | #define _GATEWAY_SOCKET_CONTROLLER_H_ 3 | 4 | #include "net/common_socket_controller.h" 5 | 6 | namespace ff { 7 | 8 | class net_stat_t; 9 | 10 | class gateway_socket_controller_t: public common_socket_controller_t 11 | { 12 | public: 13 | gateway_socket_controller_t(msg_handler_ptr_t msg_handler_, net_stat_t*); 14 | ~gateway_socket_controller_t(); 15 | 16 | virtual int handle_open(socket_i*); 17 | virtual int handle_read(socket_i*, char* buff, size_t len); 18 | virtual int handle_error(socket_i*); 19 | 20 | private: 21 | net_stat_t* m_net_stat; 22 | time_t m_last_update_tm; 23 | }; 24 | 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /fflib/net/http_acceptor.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "net/http_acceptor.h" 3 | #include "net/socket_impl.h" 4 | #include "net/text_socket_controller_impl.h" 5 | #include "base/arg_helper.h" 6 | 7 | using namespace ff; 8 | 9 | http_acceptor_t::http_acceptor_t(epoll_i* e_, msg_handler_i* mh_, task_queue_pool_t* tq_): 10 | acceptor_impl_t(e_, mh_, tq_) 11 | { 12 | 13 | } 14 | 15 | http_acceptor_t::~http_acceptor_t() 16 | { 17 | 18 | } 19 | 20 | socket_i* http_acceptor_t::create_socket(int new_fd_) 21 | { 22 | return new socket_impl_t(m_epoll, new text_socket_controller_impl_t(m_msg_handler), new_fd_, m_tq->alloc(new_fd_)); 23 | } 24 | -------------------------------------------------------------------------------- /fflib/net/http_acceptor.h: -------------------------------------------------------------------------------- 1 | #ifndef _HTTP_ACCEPTOR_H_ 2 | #define _HTTP_ACCEPTOR_H_ 3 | 4 | #include "net/acceptor_impl.h" 5 | #include "net/common_socket_controller.h" 6 | #include "net/net_stat.h" 7 | 8 | namespace ff { 9 | 10 | class http_acceptor_t: public acceptor_impl_t 11 | { 12 | public: 13 | http_acceptor_t(epoll_i*, msg_handler_i*, task_queue_pool_t* tq_); 14 | ~http_acceptor_t(); 15 | 16 | protected: 17 | virtual socket_i* create_socket(int new_fd_); 18 | 19 | private: 20 | }; 21 | 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /fflib/net/message.h: -------------------------------------------------------------------------------- 1 | #ifndef _MESSAGE_H_ 2 | #define _MESSAGE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | namespace ff { 10 | 11 | struct message_head_t 12 | { 13 | message_head_t(): 14 | size(0), 15 | cmd(0), 16 | flag(0) 17 | {} 18 | explicit message_head_t(uint16_t cmd_): 19 | size(0), 20 | cmd(cmd_), 21 | flag(0) 22 | {} 23 | uint32_t size; 24 | uint16_t cmd; 25 | uint16_t flag; 26 | }; 27 | 28 | class message_t 29 | { 30 | public: 31 | message_t() 32 | { 33 | } 34 | 35 | uint16_t get_cmd() const { return m_head.cmd; } 36 | const string& get_body() const { return m_body;} 37 | size_t size() const { return m_head.size; } 38 | uint16_t get_flag() const { return m_head.flag; } 39 | 40 | size_t append_head(size_t index_, char* buff, size_t len) 41 | { 42 | size_t will_append = sizeof(m_head) - index_; 43 | if (will_append > len) will_append = len; 44 | ::memcpy((char*)&m_head + index_, buff, will_append); 45 | return will_append; 46 | } 47 | size_t append_msg(char* buff, size_t len) 48 | { 49 | size_t will_append = m_head.size - m_body.size(); 50 | if (will_append > len) will_append = len; 51 | m_body.append(buff, will_append); 52 | return will_append; 53 | } 54 | void clear() 55 | { 56 | ::memset(&m_head, 0, sizeof(m_head)); 57 | m_body.clear(); 58 | } 59 | void append_to_body(const char* buff, size_t len) 60 | { 61 | m_body.append(buff, len); 62 | } 63 | //! for parse 64 | bool have_recv_head(size_t have_recv_size_) { return have_recv_size_ >= sizeof(message_head_t);} 65 | private: 66 | message_head_t m_head; 67 | string m_body; 68 | }; 69 | 70 | } 71 | #endif 72 | -------------------------------------------------------------------------------- /fflib/net/msg_handler_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _MSG_HANDLER_XX_H_ 2 | #define _MSG_HANDLER_XX_H_ 3 | 4 | #include "net/message.h" 5 | #include "net/socket_i.h" 6 | 7 | namespace ff { 8 | 9 | class msg_handler_i 10 | { 11 | public: 12 | virtual ~msg_handler_i() {} ; 13 | 14 | virtual int handle_broken(socket_ptr_t sock_) = 0; 15 | virtual int handle_msg(const message_t& msg_, socket_ptr_t sock_) = 0; 16 | 17 | }; 18 | 19 | typedef msg_handler_i* msg_handler_ptr_t; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /fflib/net/msg_sender.h: -------------------------------------------------------------------------------- 1 | //! 消息发送器 2 | 3 | #ifndef _MSG_SENDER_H_ 4 | #define _MSG_SENDER_H_ 5 | 6 | namespace ff { 7 | 8 | #include "net/socket_i.h" 9 | #include "net/message.h" 10 | #include "net/codec.h" 11 | //! #include "zlib_util.h" 12 | 13 | class msg_sender_t 14 | { 15 | public: 16 | static void send(socket_ptr_t socket_ptr_, uint16_t cmd_, const string& str_) 17 | { 18 | if (socket_ptr_) 19 | { 20 | message_head_t h(cmd_); 21 | h.size = str_.size(); 22 | string dest((const char*)&h, sizeof(h)); 23 | dest += str_; 24 | socket_ptr_->async_send(dest); 25 | } 26 | } 27 | static void send(socket_ptr_t socket_ptr_, uint16_t cmd_, codec_i& msg_) 28 | { 29 | if (socket_ptr_) 30 | { 31 | string body = msg_.encode(); 32 | message_head_t h(cmd_); 33 | h.size = body.size(); 34 | string dest((const char*)&h, sizeof(h)); 35 | dest += body; 36 | 37 | socket_ptr_->async_send(dest); 38 | } 39 | } 40 | static void send(socket_ptr_t socket_ptr_, const string& str_) 41 | { 42 | if (socket_ptr_) 43 | { 44 | socket_ptr_->async_send(str_); 45 | } 46 | } 47 | static void send_to_client(socket_ptr_t socket_ptr_, codec_i& msg_) 48 | { 49 | if (socket_ptr_) 50 | { 51 | string body = msg_.encode(); 52 | message_head_t h(0); 53 | h.size = body.size(); 54 | string dest((const char*)&h, sizeof(h)); 55 | dest += body; 56 | socket_ptr_->async_send(dest); 57 | } 58 | } 59 | }; 60 | 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /fflib/net/net_stat.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "net/net_stat.h" 3 | using namespace ff; 4 | 5 | net_stat_t::net_stat_t(): 6 | m_timer_service(NULL), 7 | m_max_packet_size(1000) 8 | { 9 | } 10 | 11 | net_stat_t::~net_stat_t() 12 | { 13 | if (m_timer_service) 14 | { 15 | delete m_timer_service; 16 | m_timer_service = NULL; 17 | } 18 | } 19 | 20 | static void timer_close(socket_ptr_t s_) 21 | { 22 | s_->close(); 23 | } 24 | 25 | static void timer_check(void* p_) 26 | { 27 | ((net_stat_t*)p_)->handle_timer_check(); 28 | } 29 | 30 | int net_stat_t::start(arg_helper_t& arg_helper_) 31 | { 32 | if (arg_helper_.is_enable_option("-max_packet_size")) 33 | { 34 | m_max_packet_size = ::atoi(arg_helper_.get_option_value("-max_packet_size").c_str()); 35 | } 36 | 37 | m_heartbeat.set_option(arg_helper_, timer_close); 38 | 39 | m_timer_service = new timer_service_t(1); //! 1s tick 40 | 41 | m_timer_service->timer_callback(m_heartbeat.timeout(), task_t(&timer_check, (void*)this)); 42 | return 0; 43 | } 44 | 45 | void net_stat_t::handle_timer_check() 46 | { 47 | m_heartbeat.timer_check(); 48 | if (m_timer_service) 49 | { 50 | m_timer_service->timer_callback(m_heartbeat.timeout(), task_t(&timer_check, (void*)this)); 51 | } 52 | } 53 | 54 | int net_stat_t::stop() 55 | { 56 | if (m_timer_service) 57 | { 58 | delete m_timer_service; 59 | m_timer_service = NULL; 60 | } 61 | return 0; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /fflib/net/net_stat.h: -------------------------------------------------------------------------------- 1 | #ifndef _NET_STAT_H_ 2 | #define _NET_STAT_H_ 3 | 4 | #include "net/socket_i.h" 5 | #include "base/arg_helper.h" 6 | #include "base/timer_service.h" 7 | #include "base_heartbeat.h" 8 | 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | namespace ff { 14 | 15 | class net_stat_t 16 | { 17 | public: 18 | net_stat_t(); 19 | ~net_stat_t(); 20 | 21 | int start(arg_helper_t& arg_helper_); 22 | int stop(); 23 | 24 | //! 最大消息包大小 25 | int get_max_packet_size() const { return m_max_packet_size; } 26 | 27 | //! 获取心跳模块引用 28 | base_heartbeat_t& get_heartbeat() { return m_heartbeat;} 29 | 30 | //! 处理timer 回调 31 | void handle_timer_check(); 32 | private: 33 | timer_service_t* m_timer_service; 34 | int m_max_packet_size; 35 | base_heartbeat_t m_heartbeat; 36 | }; 37 | 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /fflib/net/netbase.h: -------------------------------------------------------------------------------- 1 | #ifndef _NET_BASE_H_ 2 | #define _NET_BASE_H_ 3 | 4 | namespace ff { 5 | 6 | //! 文件描述符相关接口 7 | typedef int socket_fd_t; 8 | class fd_i 9 | { 10 | public: 11 | virtual ~fd_i(){} 12 | 13 | virtual socket_fd_t socket() = 0; 14 | virtual int handle_epoll_read() = 0; 15 | virtual int handle_epoll_write() = 0; 16 | virtual int handle_epoll_del() = 0; 17 | 18 | virtual void close() = 0; 19 | }; 20 | 21 | //! 事件分发器 22 | class io_demultiplexer_i 23 | { 24 | public: 25 | virtual ~io_demultiplexer_i(){} 26 | 27 | virtual int event_loop() = 0; 28 | virtual int close() = 0; 29 | virtual int register_fd(fd_i*) = 0; 30 | virtual int unregister_fd(fd_i*) = 0; 31 | virtual int mod_fd(fd_i*) = 0; 32 | }; 33 | 34 | //typedef fd_i epoll_fd_i; 35 | } 36 | 37 | #endif 38 | 39 | 40 | -------------------------------------------------------------------------------- /fflib/net/socket_controller_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOCKET_CONTROLLER_I_ 2 | #define _SOCKET_CONTROLLER_I_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | namespace ff { 8 | 9 | class socket_i; 10 | 11 | class socket_controller_i 12 | { 13 | public: 14 | virtual ~socket_controller_i(){} 15 | 16 | virtual int handle_open(socket_i*) {return 0;} 17 | virtual int check_pre_send(socket_i*, string& buff_) {return 0;} 18 | 19 | virtual int handle_error(socket_i*) = 0; 20 | virtual int handle_read(socket_i*, char* buff, size_t len) = 0; 21 | virtual int handle_write_completed(socket_i*) {return 0;} 22 | 23 | }; 24 | 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /fflib/net/socket_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOCKET_I_ 2 | #define _SOCKET_I_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | #include "netbase.h" 9 | 10 | namespace ff { 11 | 12 | class socket_i: public fd_i 13 | { 14 | public: 15 | socket_i(): 16 | m_data(NULL) {} 17 | virtual ~socket_i(){} 18 | 19 | virtual void open() = 0; 20 | virtual void async_send(const string& buff_) = 0; 21 | virtual void async_recv() = 0; 22 | virtual void safe_delete() { delete this; } 23 | virtual void set_data(void* p) { m_data = p; } 24 | template 25 | T* get_data() const { return (T*)m_data; } 26 | 27 | private: 28 | void* m_data; 29 | }; 30 | 31 | typedef socket_i* socket_ptr_t; 32 | 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /fflib/net/socket_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOCKET_IMPL_H_ 2 | #define _SOCKET_IMPL_H_ 3 | 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | #include "net/socket_i.h" 9 | 10 | namespace ff { 11 | 12 | class epoll_i; 13 | class socket_controller_i; 14 | class task_queue_i; 15 | 16 | #define RECV_BUFFER_SIZE 8096 17 | 18 | class socket_impl_t: public socket_i 19 | { 20 | public: 21 | typedef list send_buffer_t; 22 | 23 | public: 24 | socket_impl_t(epoll_i*, socket_controller_i*, int fd, task_queue_i* tq_); 25 | ~socket_impl_t(); 26 | 27 | virtual int socket() { return m_fd; } 28 | virtual void close(); 29 | virtual void open(); 30 | 31 | virtual int handle_epoll_read(); 32 | virtual int handle_epoll_write(); 33 | virtual int handle_epoll_del(); 34 | 35 | virtual void async_send(const string& buff_); 36 | virtual void async_recv(); 37 | virtual void safe_delete(); 38 | 39 | int handle_epoll_read_impl(); 40 | int handle_epoll_write_impl(); 41 | int handle_epoll_error_impl(); 42 | void send_impl(const string& buff_); 43 | void close_impl(); 44 | 45 | socket_controller_i* get_sc() { return m_sc; } 46 | private: 47 | bool is_open() { return m_fd > 0; } 48 | 49 | int do_send(const string& msg, string& left_); 50 | private: 51 | epoll_i* m_epoll; 52 | socket_controller_i* m_sc; 53 | int m_fd; 54 | task_queue_i* m_tq; 55 | send_buffer_t m_send_buffer; 56 | }; 57 | 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /fflib/net/socket_op.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOCKET_OP_H_ 2 | #define _SOCKET_OP_H_ 3 | 4 | #include 5 | #include 6 | 7 | namespace ff { 8 | 9 | struct socket_op_t 10 | { 11 | static int set_nonblock(int fd_) 12 | { 13 | int flags; 14 | flags = fcntl(fd_, F_GETFL, 0); 15 | if ((flags = fcntl(fd_, F_SETFL, flags | O_NONBLOCK)) < 0) 16 | { 17 | return -1; 18 | } 19 | 20 | return 0; 21 | } 22 | }; 23 | 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /fflib/net/text_socket_controller_impl.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEXT_SOCKET_CONTROLLER_IMPL_H_ 2 | #define _TEXT_SOCKET_CONTROLLER_IMPL_H_ 3 | 4 | #include 5 | using namespace std; 6 | 7 | #include "net/socket_controller_i.h" 8 | #include "net/message.h" 9 | #include "net/msg_handler_i.h" 10 | 11 | namespace ff { 12 | 13 | class socket_i; 14 | 15 | class text_socket_controller_impl_t: public socket_controller_i 16 | { 17 | enum protocol_e 18 | { 19 | TXT_PROTOCOL = 0, 20 | HTTP_PROTOCOL, 21 | UNKNOWN_PROTOCOL, 22 | }; 23 | public: 24 | text_socket_controller_impl_t(msg_handler_ptr_t msg_handler_); 25 | ~text_socket_controller_impl_t(); 26 | virtual int handle_error(socket_i*); 27 | virtual int handle_read(socket_i*, char* buff, size_t len); 28 | virtual int handle_write_completed(socket_i*); 29 | 30 | virtual int check_pre_send(socket_i*, string& buff_); 31 | private: 32 | int parse_msg_head(); 33 | int append_msg_body(socket_i* sp_, char* buff_begin_, size_t& left_); 34 | 35 | //! check which protocol does peer use 36 | protocol_e analyze_protocol(char* buff, size_t len); 37 | //! parse http protocol request 38 | int parse_http_protocol(socket_i* sp_, char* buff, size_t len); 39 | //! parse simple text protocol request 40 | int parse_text_protocol(socket_i* sp_, char* buff, size_t len); 41 | private: 42 | protocol_e m_protocol; 43 | msg_handler_ptr_t m_msg_handler; 44 | bool m_head_end_flag; 45 | size_t m_body_size; 46 | string m_head; 47 | message_t m_message; 48 | }; 49 | 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /fflib/rpc/broker_application.h: -------------------------------------------------------------------------------- 1 | #ifndef _BROKER_APPLICATION_H_ 2 | #define _BROKER_APPLICATION_H_ 3 | 4 | #include "rpc/broker_service.h" 5 | #include "net/net_factory.h" 6 | #include "base/arg_helper.h" 7 | 8 | namespace ff { 9 | 10 | class broker_application_t 11 | { 12 | public: 13 | struct app_info_t 14 | { 15 | app_info_t():acceptor(NULL) 16 | {} 17 | broker_service_t broker_service; 18 | acceptor_i* acceptor; 19 | }; 20 | static int run(int argc, char** argv) 21 | { 22 | arg_helper_t arg(argc, argv); 23 | 24 | if (arg.get_option_value("-l").empty()) 25 | { 26 | cerr <<"usage: app -l tcp://127.0.0.1:10241\n"; 27 | exit(-1); 28 | } 29 | 30 | net_factory_t::start(1); 31 | 32 | singleton_t::instance().acceptor = net_factory_t::listen(arg.get_option_value("-l"), &(singleton_t::instance().broker_service)); 33 | 34 | assert(singleton_t::instance().acceptor && "can not listen this address"); 35 | 36 | if (arg.get_option_value("-node") == "slave") 37 | { 38 | singleton_t::instance().broker_service.init_slave(arg.get_option_value("-master_host"), arg.get_option_value("-l")); 39 | } 40 | return 0; 41 | } 42 | }; 43 | 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /fflib/rpc/gateway_service_i.h: -------------------------------------------------------------------------------- 1 | #ifndef _GATEWAY_SERVICE_I_H_ 2 | #define _GATEWAY_SERVICE_I_H_ 3 | 4 | #include "net/codec.h" 5 | #include "net/socket_i.h" 6 | #include "net/msg_handler_i.h" 7 | 8 | namespace ff { 9 | 10 | class gateway_service_i: public msg_handler_i 11 | { 12 | public: 13 | virtual ~gateway_service_i() {} 14 | 15 | virtual int handle_login(gate_msg_tool_t& msg_, socket_ptr_t sock_) = 0; 16 | virtual int handle_logout(socket_ptr_t sock_) = 0; 17 | virtual int handle_common_logic(gate_msg_tool_t& msg_, socket_ptr_t sock_) = 0; 18 | 19 | virtual int handle_broken(socket_ptr_t sock_) 20 | { 21 | handle_logout(sock_); 22 | sock_->safe_delete(); 23 | return 0; 24 | } 25 | virtual int handle_msg(const message_t& msg_, socket_ptr_t sock_) 26 | { 27 | try 28 | { 29 | gate_msg_tool_t msg_tool; 30 | msg_tool.gate_decode(msg_.get_body()); 31 | if (msg_tool.get_name() == "login_t::in_t") 32 | { 33 | handle_login(msg_tool, sock_); 34 | } 35 | else 36 | { 37 | handle_common_logic(msg_tool, sock_); 38 | } 39 | } 40 | catch (exception& e_) 41 | { 42 | sock_->close(); 43 | } 44 | return 0; 45 | } 46 | }; 47 | 48 | } 49 | #endif 50 | -------------------------------------------------------------------------------- /fflib/rpc/rpc_future.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _RPC_FUTURE_H_ 3 | #define _RPC_FUTURE_H_ 4 | 5 | namespace ff { 6 | 7 | #include "rpc/rpc_callback.h" 8 | #include "rpc/rpc_service.h" 9 | #include "base/lock.h" 10 | 11 | template 12 | class rpc_future_t 13 | { 14 | public: 15 | rpc_future_t():m_cond(m_mutex),m_flag(false) 16 | {} 17 | void callback(RET& out_) 18 | { 19 | m_msg = out_; 20 | lock_guard_t lock(m_mutex); 21 | m_flag = true; 22 | m_cond.signal(); 23 | } 24 | 25 | template 26 | RET call(rpc_service_t* rs_, MSGT& in_) 27 | { 28 | rs_->async_call(in_, singleton_t >::instance().get_id(), 29 | binder_t::callback(&rpc_future_t::callback, this)); 30 | lock_guard_t lock(m_mutex); 31 | while(false == m_flag) 32 | { 33 | m_cond.wait(); 34 | } 35 | m_flag = false; 36 | return m_msg; 37 | } 38 | 39 | private: 40 | RET m_msg; 41 | condition_var_t m_cond; 42 | mutex_t m_mutex; 43 | bool m_flag; 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /fflib/rpc/rpc_reg.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _FF_RPC_REG_I_ 3 | #define _FF_RPC_REG_I_ 4 | 5 | #include "net/msg_handler_i.h" 6 | #include "net/net_factory.h" 7 | 8 | namespace ff { 9 | 10 | class rpc_reg_i: public msg_handler_i 11 | { 12 | public: 13 | virtual ~rpc_reg_i(){} 14 | 15 | virtual int register_interface(const string& in_name_, const string& out_name_, uint16_t gid_, uint16_t id_, uint16_t& in_alloc_id_, uint16_t& out_alloc_id_) { return -1; } 16 | 17 | virtual socket_ptr_t get_socket(const rpc_service_t* rs_) = 0; 18 | }; 19 | 20 | } 21 | #endif 22 | -------------------------------------------------------------------------------- /fflib/rpc/rpc_service_group.cpp: -------------------------------------------------------------------------------- 1 | #include "rpc/rpc_service_group.h" 2 | #include "rpc/ffrpc.h" 3 | 4 | using namespace ff; 5 | 6 | rpc_service_group_t::rpc_service_group_t(const string& name_, uint16_t id_): 7 | m_id(id_), 8 | m_name(name_) 9 | {} 10 | 11 | rpc_service_group_t::~rpc_service_group_t() 12 | { 13 | rpc_service_map_t::iterator it = m_all_rpc_service.begin(); 14 | for (; it != m_all_rpc_service.end(); ++it) 15 | { 16 | delete it->second; 17 | } 18 | m_all_rpc_service.clear(); 19 | } 20 | 21 | uint16_t rpc_service_group_t::get_id() const 22 | { 23 | return m_id; 24 | } 25 | 26 | const string& rpc_service_group_t::get_name() const 27 | { 28 | return m_name; 29 | } 30 | 31 | rpc_service_t* rpc_service_group_t::get_service(uint16_t id_) 32 | { 33 | rpc_service_map_t::iterator it = m_all_rpc_service.find(id_); 34 | if (it != m_all_rpc_service.end()) 35 | { 36 | return it->second; 37 | } 38 | return NULL; 39 | } 40 | 41 | int rpc_service_group_t::add_service(uint16_t id_, rpc_service_t* service_) 42 | { 43 | return m_all_rpc_service.insert(make_pair(id_, service_)).second == true? 0: -1; 44 | } 45 | -------------------------------------------------------------------------------- /fflib/rpc/rpc_service_group.h: -------------------------------------------------------------------------------- 1 | //! rpc 服务组 2 | #ifndef _RPC_SERVICE_GROUP_H_ 3 | #define _RPC_SERVICE_GROUP_H_ 4 | 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | #include "rpc/rpc_service.h" 11 | 12 | namespace ff { 13 | 14 | class ffrpc_t; 15 | 16 | class rpc_service_group_t 17 | { 18 | typedef map rpc_service_map_t; 19 | public: 20 | rpc_service_group_t(const string& name_, uint16_t id_); 21 | ~rpc_service_group_t(); 22 | 23 | uint16_t get_id() const; 24 | const string& get_name() const; 25 | 26 | rpc_service_t* get_service(uint16_t id_); 27 | 28 | int add_service(uint16_t id_, rpc_service_t* service_); 29 | 30 | size_t size() const { return m_all_rpc_service.size(); } 31 | 32 | template 33 | void foreach(T func_); 34 | private: 35 | uint16_t m_id; 36 | string m_name; 37 | rpc_service_map_t m_all_rpc_service; 38 | }; 39 | 40 | 41 | template 42 | void rpc_service_group_t::foreach(T func_) 43 | { 44 | typename rpc_service_group_t::rpc_service_map_t::iterator it = m_all_rpc_service.begin(); 45 | for (; it != m_all_rpc_service.end(); ++it) 46 | { 47 | func_(it->second); 48 | } 49 | } 50 | 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /fflib/xml/ffxml.h: -------------------------------------------------------------------------------- 1 | #ifndef _FF_XML_H_ 2 | #define _FF_XML_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | using namespace std; 9 | 10 | #include 11 | 12 | namespace ff 13 | { 14 | 15 | class ffxml_t 16 | { 17 | public: 18 | ffxml_t(); 19 | ~ffxml_t(); 20 | int load(const string& file_); 21 | //! root.a 22 | //! root.{b} 23 | //! root.@1.{b} root.@2.c 24 | const char* get(const string& node_name_); 25 | size_t size(const string& node_name_); 26 | 27 | protected: 28 | pair get_node(const string& node_name_); 29 | private: 30 | TiXmlDocument m_xml_doc; 31 | }; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /fflib/xml/tinyxmlerror.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | www.sourceforge.net/projects/tinyxml 3 | Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any 7 | damages arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any 10 | purpose, including commercial applications, and to alter it and 11 | redistribute it freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must 14 | not claim that you wrote the original software. If you use this 15 | software in a product, an acknowledgment in the product documentation 16 | would be appreciated but is not required. 17 | 18 | 2. Altered source versions must be plainly marked as such, and 19 | must not be misrepresented as being the original software. 20 | 21 | 3. This notice may not be removed or altered from any source 22 | distribution. 23 | */ 24 | 25 | #include "xml/tinyxml.h" 26 | 27 | // The goal of the seperate error file is to make the first 28 | // step towards localization. tinyxml (currently) only supports 29 | // english error messages, but the could now be translated. 30 | // 31 | // It also cleans up the code a bit. 32 | // 33 | 34 | const char* TiXmlBase::errorString[ TiXmlBase::TIXML_ERROR_STRING_COUNT ] = 35 | { 36 | "No error", 37 | "Error", 38 | "Failed to open file", 39 | "Error parsing Element.", 40 | "Failed to read Element name", 41 | "Error reading Element value.", 42 | "Error reading Attributes.", 43 | "Error: empty tag.", 44 | "Error reading end tag.", 45 | "Error parsing Unknown.", 46 | "Error parsing Comment.", 47 | "Error parsing Declaration.", 48 | "Error document empty.", 49 | "Error null (0) or unexpected EOF found in input stream.", 50 | "Error parsing CDATA.", 51 | "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", 52 | }; 53 | --------------------------------------------------------------------------------