临时保存
This commit is contained in:
		
							parent
							
								
									7ed7033716
								
							
						
					
					
						commit
						43515d8058
					
				
							
								
								
									
										93
									
								
								.idea/flutter_openim_sdk.iml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										93
									
								
								.idea/flutter_openim_sdk.iml
									
									
									
										generated
									
									
									
								
							| @ -30,6 +30,99 @@ | |||||||
|       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/.dart_tool" /> |       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/.pub" /> |       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/.pub" /> | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/build" /> |       <excludeFolder url="file://$MODULE_DIR$/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/ios/.symlinks/plugins/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.dart_tool" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/.pub" /> | ||||||
|  |       <excludeFolder url="file://$MODULE_DIR$/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/windows/flutter/ephemeral/.plugin_symlinks/flutter_openim_sdk/example/build" /> | ||||||
|     </content> |     </content> | ||||||
|     <orderEntry type="inheritedJdk" /> |     <orderEntry type="inheritedJdk" /> | ||||||
|     <orderEntry type="sourceFolder" forTests="false" /> |     <orderEntry type="sourceFolder" forTests="false" /> | ||||||
|  | |||||||
							
								
								
									
										44
									
								
								.idea/libraries/Dart_SDK.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										44
									
								
								.idea/libraries/Dart_SDK.xml
									
									
									
										generated
									
									
									
								
							| @ -1,27 +1,29 @@ | |||||||
| <component name="libraryTable"> | <component name="libraryTable"> | ||||||
|   <library name="Dart SDK"> |   <library name="Dart SDK"> | ||||||
|     <CLASSES> |     <CLASSES> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/async" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/_internal" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/cli" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/async" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/collection" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/cli" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/convert" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/collection" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/core" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/concurrent" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/developer" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/convert" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/ffi" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/core" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/html" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/developer" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/indexed_db" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/ffi" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/io" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/html" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/isolate" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/indexed_db" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/js" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/io" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/js_interop" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/isolate" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/js_interop_unsafe" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/js" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/js_util" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/js_interop" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/math" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/js_interop_unsafe" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/mirrors" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/js_util" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/svg" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/math" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/typed_data" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/mirrors" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/web_audio" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/svg" /> | ||||||
|       <root url="file://$PROJECT_DIR$/../../install/flutter_sdk/bin/cache/dart-sdk/lib/web_gl" /> |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/typed_data" /> | ||||||
|  |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/web_audio" /> | ||||||
|  |       <root url="file://$PROJECT_DIR$/../../../../fvm/versions/3.29.2/bin/cache/dart-sdk/lib/web_gl" /> | ||||||
|     </CLASSES> |     </CLASSES> | ||||||
|     <JAVADOC /> |     <JAVADOC /> | ||||||
|     <SOURCES /> |     <SOURCES /> | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							| @ -3,4 +3,7 @@ | |||||||
|     <type id="android" /> |     <type id="android" /> | ||||||
|   </component> |   </component> | ||||||
|   <component name="ProjectRootManager" version="2" project-jdk-name="Android API 25 Platform" project-jdk-type="Android SDK" /> |   <component name="ProjectRootManager" version="2" project-jdk-name="Android API 25 Platform" project-jdk-type="Android SDK" /> | ||||||
|  |   <component name="ProjectType"> | ||||||
|  |     <option name="id" value="io.flutter" /> | ||||||
|  |   </component> | ||||||
| </project> | </project> | ||||||
| @ -0,0 +1,35 @@ | |||||||
|  | package io.openim.flutter_openim_sdk | ||||||
|  | 
 | ||||||
|  | import androidx.annotation.NonNull | ||||||
|  | 
 | ||||||
|  | import io.flutter.embedding.engine.plugins.FlutterPlugin | ||||||
|  | import io.flutter.plugin.common.MethodCall | ||||||
|  | import io.flutter.plugin.common.MethodChannel | ||||||
|  | import io.flutter.plugin.common.MethodChannel.MethodCallHandler | ||||||
|  | import io.flutter.plugin.common.MethodChannel.Result | ||||||
|  | 
 | ||||||
|  | /** FlutterOpenimSdkPlugin */ | ||||||
|  | class FlutterOpenimSdkPlugin: FlutterPlugin, MethodCallHandler { | ||||||
|  |   /// The MethodChannel that will the communication between Flutter and native Android | ||||||
|  |   /// | ||||||
|  |   /// This local reference serves to register the plugin with the Flutter Engine and unregister it | ||||||
|  |   /// when the Flutter Engine is detached from the Activity | ||||||
|  |   private lateinit var channel : MethodChannel | ||||||
|  | 
 | ||||||
|  |   override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { | ||||||
|  |     channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_openim_sdk") | ||||||
|  |     channel.setMethodCallHandler(this) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   override fun onMethodCall(call: MethodCall, result: Result) { | ||||||
|  |     if (call.method == "getPlatformVersion") { | ||||||
|  |       result.success("Android ${android.os.Build.VERSION.RELEASE}") | ||||||
|  |     } else { | ||||||
|  |       result.notImplemented() | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { | ||||||
|  |     channel.setMethodCallHandler(null) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | package io.openim.flutter_openim_sdk | ||||||
|  | 
 | ||||||
|  | import io.flutter.plugin.common.MethodCall | ||||||
|  | import io.flutter.plugin.common.MethodChannel | ||||||
|  | import kotlin.test.Test | ||||||
|  | import org.mockito.Mockito | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation. | ||||||
|  |  * | ||||||
|  |  * Once you have built the plugin's example app, you can run these tests from the command | ||||||
|  |  * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or | ||||||
|  |  * you can run them directly from IDEs that support JUnit such as Android Studio. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | internal class FlutterOpenimSdkPluginTest { | ||||||
|  |   @Test | ||||||
|  |   fun onMethodCall_getPlatformVersion_returnsExpectedValue() { | ||||||
|  |     val plugin = FlutterOpenimSdkPlugin() | ||||||
|  | 
 | ||||||
|  |     val call = MethodCall("getPlatformVersion", null) | ||||||
|  |     val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java) | ||||||
|  |     plugin.onMethodCall(call, mockResult) | ||||||
|  | 
 | ||||||
|  |     Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								example/OpenIM_v3_3e8b8fb2ecd8414db50838d9f7bcb19d.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								example/OpenIM_v3_3e8b8fb2ecd8414db50838d9f7bcb19d.db
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | package io.openim.flutter_openim_sdk_example | ||||||
|  | 
 | ||||||
|  | import io.flutter.embedding.android.FlutterActivity | ||||||
|  | 
 | ||||||
|  | class MainActivity: FlutterActivity() | ||||||
							
								
								
									
										25
									
								
								example/integration_test/plugin_integration_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								example/integration_test/plugin_integration_test.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | // This is a basic Flutter integration test. | ||||||
|  | // | ||||||
|  | // Since integration tests run in a full Flutter application, they can interact | ||||||
|  | // with the host side of a plugin implementation, unlike Dart unit tests. | ||||||
|  | // | ||||||
|  | // For more information about Flutter integration tests, please see | ||||||
|  | // https://flutter.dev/to/integration-testing | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import 'package:flutter_test/flutter_test.dart'; | ||||||
|  | import 'package:integration_test/integration_test.dart'; | ||||||
|  | 
 | ||||||
|  | import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; | ||||||
|  | 
 | ||||||
|  | void main() { | ||||||
|  |   IntegrationTestWidgetsFlutterBinding.ensureInitialized(); | ||||||
|  | 
 | ||||||
|  |   testWidgets('getPlatformVersion test', (WidgetTester tester) async { | ||||||
|  |     final FlutterOpenimSdk plugin = FlutterOpenimSdk(); | ||||||
|  |     final String? version = await plugin.getPlatformVersion(); | ||||||
|  |     // The version string depends on the host platform running the test, so | ||||||
|  |     // just assert that some non-empty string is returned. | ||||||
|  |     expect(version?.isNotEmpty, true); | ||||||
|  |   }); | ||||||
|  | } | ||||||
| @ -2,7 +2,12 @@ import 'package:flutter/material.dart'; | |||||||
| import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; | import 'package:flutter_openim_sdk/flutter_openim_sdk.dart'; | ||||||
| 
 | 
 | ||||||
| void main() { | void main() { | ||||||
|  |   try { | ||||||
|     runApp(MyApp()); |     runApp(MyApp()); | ||||||
|  |   } catch (e, stackTrace) { | ||||||
|  |     print('Error during app startup: $e'); | ||||||
|  |     print('Stack trace: $stackTrace'); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class MyApp extends StatefulWidget { | class MyApp extends StatefulWidget { | ||||||
| @ -14,12 +19,26 @@ class _MyAppState extends State<MyApp> { | |||||||
|   @override |   @override | ||||||
|   void initState() { |   void initState() { | ||||||
|     super.initState(); |     super.initState(); | ||||||
|     OpenIM.iMManager.initSDK( |     OpenIM.iMManager | ||||||
|  |         .initSDK( | ||||||
|             platformID: 1, |             platformID: 1, | ||||||
|         apiAddr: '', |             apiAddr: 'http://192.168.77.135:10002', | ||||||
|         wsAddr: '', |             wsAddr: 'ws://192.168.77.135:10001', | ||||||
|         dataDir: '/', |             dataDir: './', | ||||||
|         listener: OnConnectListener()); |             listener: OnConnectListener()) | ||||||
|  |         .then((value) { | ||||||
|  |       print('SDK initialized successfully'); | ||||||
|  |       OpenIM.iMManager | ||||||
|  |           .login( | ||||||
|  |               userID: "3e8b8fb2ecd8414db50838d9f7bcb19d", | ||||||
|  |               token: | ||||||
|  |                   "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOiIzZThiOGZiMmVjZDg0MTRkYjUwODM4ZDlmN2JjYjE5ZCIsIlBsYXRmb3JtSUQiOjIsImV4cCI6MTc1Mzc1MTYyNywiaWF0IjoxNzQ1OTc1NjIyfQ.S-CxfETXYyLFe2VqStwbrVCRcB5j2T2qi-52y1L-3OI") | ||||||
|  |           .then((value) { | ||||||
|  |         print('Login successful'); | ||||||
|  |       }).catchError((error) { | ||||||
|  |         print('Login failed: $error'); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|  | |||||||
| @ -5,42 +5,42 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: async |       name: async | ||||||
|       sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" |       sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.11.0" |     version: "2.12.0" | ||||||
|   boolean_selector: |   boolean_selector: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: boolean_selector |       name: boolean_selector | ||||||
|       sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" |       sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.1.1" |     version: "2.1.2" | ||||||
|   characters: |   characters: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: characters |       name: characters | ||||||
|       sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" |       sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.3.0" |     version: "1.4.0" | ||||||
|   clock: |   clock: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: clock |       name: clock | ||||||
|       sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf |       sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.1.1" |     version: "1.1.2" | ||||||
|   collection: |   collection: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: collection |       name: collection | ||||||
|       sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a |       sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.18.0" |     version: "1.19.1" | ||||||
|   cupertino_icons: |   cupertino_icons: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
| @ -53,10 +53,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: fake_async |       name: fake_async | ||||||
|       sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" |       sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.3.1" |     version: "1.3.2" | ||||||
|   flutter: |   flutter: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: flutter |     description: flutter | ||||||
| @ -86,18 +86,18 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: leak_tracker |       name: leak_tracker | ||||||
|       sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" |       sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "10.0.5" |     version: "10.0.8" | ||||||
|   leak_tracker_flutter_testing: |   leak_tracker_flutter_testing: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: leak_tracker_flutter_testing |       name: leak_tracker_flutter_testing | ||||||
|       sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" |       sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.0.5" |     version: "3.0.9" | ||||||
|   leak_tracker_testing: |   leak_tracker_testing: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @ -118,10 +118,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: matcher |       name: matcher | ||||||
|       sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb |       sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.12.16+1" |     version: "0.12.17" | ||||||
|   material_color_utilities: |   material_color_utilities: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @ -134,71 +134,71 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: meta |       name: meta | ||||||
|       sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 |       sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.15.0" |     version: "1.16.0" | ||||||
|   path: |   path: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: path |       name: path | ||||||
|       sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" |       sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.9.0" |     version: "1.9.1" | ||||||
|   sky_engine: |   sky_engine: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: flutter |     description: flutter | ||||||
|     source: sdk |     source: sdk | ||||||
|     version: "0.0.99" |     version: "0.0.0" | ||||||
|   source_span: |   source_span: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: source_span |       name: source_span | ||||||
|       sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" |       sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.10.0" |     version: "1.10.1" | ||||||
|   stack_trace: |   stack_trace: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: stack_trace |       name: stack_trace | ||||||
|       sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" |       sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.11.1" |     version: "1.12.1" | ||||||
|   stream_channel: |   stream_channel: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: stream_channel |       name: stream_channel | ||||||
|       sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 |       sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "2.1.2" |     version: "2.1.4" | ||||||
|   string_scanner: |   string_scanner: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: string_scanner |       name: string_scanner | ||||||
|       sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" |       sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.2.0" |     version: "1.4.1" | ||||||
|   term_glyph: |   term_glyph: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: term_glyph |       name: term_glyph | ||||||
|       sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 |       sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.2.1" |     version: "1.2.2" | ||||||
|   test_api: |   test_api: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: test_api |       name: test_api | ||||||
|       sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" |       sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "0.7.2" |     version: "0.7.4" | ||||||
|   vector_math: |   vector_math: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
| @ -211,10 +211,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: vm_service |       name: vm_service | ||||||
|       sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" |       sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "14.2.5" |     version: "14.3.1" | ||||||
| sdks: | sdks: | ||||||
|   dart: ">=3.4.4 <4.0.0" |   dart: ">=3.7.0-0 <4.0.0" | ||||||
|   flutter: ">=3.18.0-18.0.pre.54" |   flutter: ">=3.18.0-18.0.pre.54" | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								example/windows/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								example/windows/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | flutter/ephemeral/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio user-specific files. | ||||||
|  | *.suo | ||||||
|  | *.user | ||||||
|  | *.userosscache | ||||||
|  | *.sln.docstates | ||||||
|  | 
 | ||||||
|  | # Visual Studio build-related files. | ||||||
|  | x64/ | ||||||
|  | x86/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio cache files | ||||||
|  | # files ending in .cache can be ignored | ||||||
|  | *.[Cc]ache | ||||||
|  | # but keep track of directories ending in .cache | ||||||
|  | !*.[Cc]ache/ | ||||||
							
								
								
									
										110
									
								
								example/windows/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								example/windows/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | # Project-level configuration. | ||||||
|  | cmake_minimum_required(VERSION 3.14) | ||||||
|  | project(flutter_openim_sdk_example LANGUAGES CXX) | ||||||
|  | 
 | ||||||
|  | # The name of the executable created for the application. Change this to change | ||||||
|  | # the on-disk name of your application. | ||||||
|  | set(BINARY_NAME "flutter_openim_sdk_example") | ||||||
|  | 
 | ||||||
|  | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent | ||||||
|  | # versions of CMake. | ||||||
|  | cmake_policy(VERSION 3.14...3.25) | ||||||
|  | 
 | ||||||
|  | # Define build configuration option. | ||||||
|  | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | ||||||
|  | if(IS_MULTICONFIG) | ||||||
|  |   set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" | ||||||
|  |     CACHE STRING "" FORCE) | ||||||
|  | else() | ||||||
|  |   if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) | ||||||
|  |     set(CMAKE_BUILD_TYPE "Debug" CACHE | ||||||
|  |       STRING "Flutter build mode" FORCE) | ||||||
|  |     set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS | ||||||
|  |       "Debug" "Profile" "Release") | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  | # Define settings for the Profile build mode. | ||||||
|  | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") | ||||||
|  | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") | ||||||
|  | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") | ||||||
|  | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") | ||||||
|  | 
 | ||||||
|  | # Use Unicode for all projects. | ||||||
|  | add_definitions(-DUNICODE -D_UNICODE) | ||||||
|  | 
 | ||||||
|  | # Compilation settings that should be applied to most targets. | ||||||
|  | # | ||||||
|  | # Be cautious about adding new options here, as plugins use this function by | ||||||
|  | # default. In most cases, you should add new options to specific targets instead | ||||||
|  | # of modifying this function. | ||||||
|  | function(APPLY_STANDARD_SETTINGS TARGET) | ||||||
|  |   target_compile_features(${TARGET} PUBLIC cxx_std_17) | ||||||
|  |   target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") | ||||||
|  |   target_compile_options(${TARGET} PRIVATE /EHsc) | ||||||
|  |   target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") | ||||||
|  |   target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>") | ||||||
|  | endfunction() | ||||||
|  | 
 | ||||||
|  | # Flutter library and tool build rules. | ||||||
|  | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") | ||||||
|  | add_subdirectory(${FLUTTER_MANAGED_DIR}) | ||||||
|  | 
 | ||||||
|  | # Application build; see runner/CMakeLists.txt. | ||||||
|  | add_subdirectory("runner") | ||||||
|  | 
 | ||||||
|  | # Enable the test target. | ||||||
|  | set(include_flutter_openim_sdk_tests TRUE) | ||||||
|  | 
 | ||||||
|  | # Generated plugin build rules, which manage building the plugins and adding | ||||||
|  | # them to the application. | ||||||
|  | include(flutter/generated_plugins.cmake) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # === Installation === | ||||||
|  | # Support files are copied into place next to the executable, so that it can | ||||||
|  | # run in place. This is done instead of making a separate bundle (as on Linux) | ||||||
|  | # so that building and running from within Visual Studio will work. | ||||||
|  | set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>") | ||||||
|  | # Make the "install" step default, as it's required to run. | ||||||
|  | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) | ||||||
|  | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) | ||||||
|  |   set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) | ||||||
|  | endif() | ||||||
|  | 
 | ||||||
|  | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") | ||||||
|  | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") | ||||||
|  | 
 | ||||||
|  | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" | ||||||
|  |   COMPONENT Runtime) | ||||||
|  | 
 | ||||||
|  | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" | ||||||
|  |   COMPONENT Runtime) | ||||||
|  | 
 | ||||||
|  | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" | ||||||
|  |   COMPONENT Runtime) | ||||||
|  | 
 | ||||||
|  | if(PLUGIN_BUNDLED_LIBRARIES) | ||||||
|  |   install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" | ||||||
|  |     DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" | ||||||
|  |     COMPONENT Runtime) | ||||||
|  | endif() | ||||||
|  | 
 | ||||||
|  | # Copy the native assets provided by the build.dart from all packages. | ||||||
|  | set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") | ||||||
|  | install(DIRECTORY "${NATIVE_ASSETS_DIR}" | ||||||
|  |    DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" | ||||||
|  |    COMPONENT Runtime) | ||||||
|  | 
 | ||||||
|  | # Fully re-copy the assets directory on each build to avoid having stale files | ||||||
|  | # from a previous install. | ||||||
|  | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") | ||||||
|  | install(CODE " | ||||||
|  |   file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") | ||||||
|  |   " COMPONENT Runtime) | ||||||
|  | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" | ||||||
|  |   DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) | ||||||
|  | 
 | ||||||
|  | # Install the AOT library on non-Debug builds only. | ||||||
|  | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" | ||||||
|  |   CONFIGURATIONS Profile;Release | ||||||
|  |   COMPONENT Runtime) | ||||||
							
								
								
									
										109
									
								
								example/windows/flutter/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								example/windows/flutter/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | # This file controls Flutter-level build steps. It should not be edited. | ||||||
|  | cmake_minimum_required(VERSION 3.14) | ||||||
|  | 
 | ||||||
|  | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") | ||||||
|  | 
 | ||||||
|  | # Configuration provided via flutter tool. | ||||||
|  | include(${EPHEMERAL_DIR}/generated_config.cmake) | ||||||
|  | 
 | ||||||
|  | # TODO: Move the rest of this into files in ephemeral. See | ||||||
|  | # https://github.com/flutter/flutter/issues/57146. | ||||||
|  | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") | ||||||
|  | 
 | ||||||
|  | # Set fallback configurations for older versions of the flutter tool. | ||||||
|  | if (NOT DEFINED FLUTTER_TARGET_PLATFORM) | ||||||
|  |   set(FLUTTER_TARGET_PLATFORM "windows-x64") | ||||||
|  | endif() | ||||||
|  | 
 | ||||||
|  | # === Flutter Library === | ||||||
|  | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") | ||||||
|  | 
 | ||||||
|  | # Published to parent scope for install step. | ||||||
|  | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) | ||||||
|  | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) | ||||||
|  | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) | ||||||
|  | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) | ||||||
|  | 
 | ||||||
|  | list(APPEND FLUTTER_LIBRARY_HEADERS | ||||||
|  |   "flutter_export.h" | ||||||
|  |   "flutter_windows.h" | ||||||
|  |   "flutter_messenger.h" | ||||||
|  |   "flutter_plugin_registrar.h" | ||||||
|  |   "flutter_texture_registrar.h" | ||||||
|  | ) | ||||||
|  | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") | ||||||
|  | add_library(flutter INTERFACE) | ||||||
|  | target_include_directories(flutter INTERFACE | ||||||
|  |   "${EPHEMERAL_DIR}" | ||||||
|  | ) | ||||||
|  | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") | ||||||
|  | add_dependencies(flutter flutter_assemble) | ||||||
|  | 
 | ||||||
|  | # === Wrapper === | ||||||
|  | list(APPEND CPP_WRAPPER_SOURCES_CORE | ||||||
|  |   "core_implementations.cc" | ||||||
|  |   "standard_codec.cc" | ||||||
|  | ) | ||||||
|  | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") | ||||||
|  | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN | ||||||
|  |   "plugin_registrar.cc" | ||||||
|  | ) | ||||||
|  | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") | ||||||
|  | list(APPEND CPP_WRAPPER_SOURCES_APP | ||||||
|  |   "flutter_engine.cc" | ||||||
|  |   "flutter_view_controller.cc" | ||||||
|  | ) | ||||||
|  | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") | ||||||
|  | 
 | ||||||
|  | # Wrapper sources needed for a plugin. | ||||||
|  | add_library(flutter_wrapper_plugin STATIC | ||||||
|  |   ${CPP_WRAPPER_SOURCES_CORE} | ||||||
|  |   ${CPP_WRAPPER_SOURCES_PLUGIN} | ||||||
|  | ) | ||||||
|  | apply_standard_settings(flutter_wrapper_plugin) | ||||||
|  | set_target_properties(flutter_wrapper_plugin PROPERTIES | ||||||
|  |   POSITION_INDEPENDENT_CODE ON) | ||||||
|  | set_target_properties(flutter_wrapper_plugin PROPERTIES | ||||||
|  |   CXX_VISIBILITY_PRESET hidden) | ||||||
|  | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) | ||||||
|  | target_include_directories(flutter_wrapper_plugin PUBLIC | ||||||
|  |   "${WRAPPER_ROOT}/include" | ||||||
|  | ) | ||||||
|  | add_dependencies(flutter_wrapper_plugin flutter_assemble) | ||||||
|  | 
 | ||||||
|  | # Wrapper sources needed for the runner. | ||||||
|  | add_library(flutter_wrapper_app STATIC | ||||||
|  |   ${CPP_WRAPPER_SOURCES_CORE} | ||||||
|  |   ${CPP_WRAPPER_SOURCES_APP} | ||||||
|  | ) | ||||||
|  | apply_standard_settings(flutter_wrapper_app) | ||||||
|  | target_link_libraries(flutter_wrapper_app PUBLIC flutter) | ||||||
|  | target_include_directories(flutter_wrapper_app PUBLIC | ||||||
|  |   "${WRAPPER_ROOT}/include" | ||||||
|  | ) | ||||||
|  | add_dependencies(flutter_wrapper_app flutter_assemble) | ||||||
|  | 
 | ||||||
|  | # === Flutter tool backend === | ||||||
|  | # _phony_ is a non-existent file to force this command to run every time, | ||||||
|  | # since currently there's no way to get a full input/output list from the | ||||||
|  | # flutter tool. | ||||||
|  | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") | ||||||
|  | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) | ||||||
|  | add_custom_command( | ||||||
|  |   OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} | ||||||
|  |     ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} | ||||||
|  |     ${CPP_WRAPPER_SOURCES_APP} | ||||||
|  |     ${PHONY_OUTPUT} | ||||||
|  |   COMMAND ${CMAKE_COMMAND} -E env | ||||||
|  |     ${FLUTTER_TOOL_ENVIRONMENT} | ||||||
|  |     "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" | ||||||
|  |       ${FLUTTER_TARGET_PLATFORM} $<CONFIG> | ||||||
|  |   VERBATIM | ||||||
|  | ) | ||||||
|  | add_custom_target(flutter_assemble DEPENDS | ||||||
|  |   "${FLUTTER_LIBRARY}" | ||||||
|  |   ${FLUTTER_LIBRARY_HEADERS} | ||||||
|  |   ${CPP_WRAPPER_SOURCES_CORE} | ||||||
|  |   ${CPP_WRAPPER_SOURCES_PLUGIN} | ||||||
|  |   ${CPP_WRAPPER_SOURCES_APP} | ||||||
|  | ) | ||||||
							
								
								
									
										14
									
								
								example/windows/flutter/generated_plugin_registrant.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								example/windows/flutter/generated_plugin_registrant.cc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | //
 | ||||||
|  | //  Generated file. Do not edit.
 | ||||||
|  | //
 | ||||||
|  | 
 | ||||||
|  | // clang-format off
 | ||||||
|  | 
 | ||||||
|  | #include "generated_plugin_registrant.h" | ||||||
|  | 
 | ||||||
|  | #include <flutter_openim_sdk/flutter_openim_sdk_plugin.h> | ||||||
|  | 
 | ||||||
|  | void RegisterPlugins(flutter::PluginRegistry* registry) { | ||||||
|  |   FlutterOpenimSdkPluginRegisterWithRegistrar( | ||||||
|  |       registry->GetRegistrarForPlugin("FlutterOpenimSdkPlugin")); | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								example/windows/flutter/generated_plugin_registrant.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								example/windows/flutter/generated_plugin_registrant.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | //
 | ||||||
|  | //  Generated file. Do not edit.
 | ||||||
|  | //
 | ||||||
|  | 
 | ||||||
|  | // clang-format off
 | ||||||
|  | 
 | ||||||
|  | #ifndef GENERATED_PLUGIN_REGISTRANT_ | ||||||
|  | #define GENERATED_PLUGIN_REGISTRANT_ | ||||||
|  | 
 | ||||||
|  | #include <flutter/plugin_registry.h> | ||||||
|  | 
 | ||||||
|  | // Registers Flutter plugins.
 | ||||||
|  | void RegisterPlugins(flutter::PluginRegistry* registry); | ||||||
|  | 
 | ||||||
|  | #endif  // GENERATED_PLUGIN_REGISTRANT_
 | ||||||
							
								
								
									
										24
									
								
								example/windows/flutter/generated_plugins.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								example/windows/flutter/generated_plugins.cmake
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | # | ||||||
|  | # Generated file, do not edit. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | list(APPEND FLUTTER_PLUGIN_LIST | ||||||
|  |   flutter_openim_sdk | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | list(APPEND FLUTTER_FFI_PLUGIN_LIST | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | set(PLUGIN_BUNDLED_LIBRARIES) | ||||||
|  | 
 | ||||||
|  | foreach(plugin ${FLUTTER_PLUGIN_LIST}) | ||||||
|  |   add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) | ||||||
|  |   target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) | ||||||
|  |   list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>) | ||||||
|  |   list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) | ||||||
|  | endforeach(plugin) | ||||||
|  | 
 | ||||||
|  | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) | ||||||
|  |   add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) | ||||||
|  |   list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) | ||||||
|  | endforeach(ffi_plugin) | ||||||
							
								
								
									
										40
									
								
								example/windows/runner/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								example/windows/runner/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | cmake_minimum_required(VERSION 3.14) | ||||||
|  | project(runner LANGUAGES CXX) | ||||||
|  | 
 | ||||||
|  | # Define the application target. To change its name, change BINARY_NAME in the | ||||||
|  | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer | ||||||
|  | # work. | ||||||
|  | # | ||||||
|  | # Any new source files that you add to the application should be added here. | ||||||
|  | add_executable(${BINARY_NAME} WIN32 | ||||||
|  |   "flutter_window.cpp" | ||||||
|  |   "main.cpp" | ||||||
|  |   "utils.cpp" | ||||||
|  |   "win32_window.cpp" | ||||||
|  |   "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" | ||||||
|  |   "Runner.rc" | ||||||
|  |   "runner.exe.manifest" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | # Apply the standard set of build settings. This can be removed for applications | ||||||
|  | # that need different build settings. | ||||||
|  | apply_standard_settings(${BINARY_NAME}) | ||||||
|  | 
 | ||||||
|  | # Add preprocessor definitions for the build version. | ||||||
|  | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") | ||||||
|  | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") | ||||||
|  | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") | ||||||
|  | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") | ||||||
|  | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") | ||||||
|  | 
 | ||||||
|  | # Disable Windows macros that collide with C++ standard library functions. | ||||||
|  | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") | ||||||
|  | 
 | ||||||
|  | # Add dependency libraries and include directories. Add any application-specific | ||||||
|  | # dependencies here. | ||||||
|  | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) | ||||||
|  | target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") | ||||||
|  | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") | ||||||
|  | 
 | ||||||
|  | # Run the Flutter tool portions of the build. This must not be removed. | ||||||
|  | add_dependencies(${BINARY_NAME} flutter_assemble) | ||||||
							
								
								
									
										121
									
								
								example/windows/runner/Runner.rc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								example/windows/runner/Runner.rc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,121 @@ | |||||||
|  | // Microsoft Visual C++ generated resource script. | ||||||
|  | // | ||||||
|  | #pragma code_page(65001) | ||||||
|  | #include "resource.h" | ||||||
|  | 
 | ||||||
|  | #define APSTUDIO_READONLY_SYMBOLS | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | // | ||||||
|  | // Generated from the TEXTINCLUDE 2 resource. | ||||||
|  | // | ||||||
|  | #include "winres.h" | ||||||
|  | 
 | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | #undef APSTUDIO_READONLY_SYMBOLS | ||||||
|  | 
 | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | // English (United States) resources | ||||||
|  | 
 | ||||||
|  | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) | ||||||
|  | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US | ||||||
|  | 
 | ||||||
|  | #ifdef APSTUDIO_INVOKED | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | // | ||||||
|  | // TEXTINCLUDE | ||||||
|  | // | ||||||
|  | 
 | ||||||
|  | 1 TEXTINCLUDE | ||||||
|  | BEGIN | ||||||
|  |     "resource.h\0" | ||||||
|  | END | ||||||
|  | 
 | ||||||
|  | 2 TEXTINCLUDE | ||||||
|  | BEGIN | ||||||
|  |     "#include ""winres.h""\r\n" | ||||||
|  |     "\0" | ||||||
|  | END | ||||||
|  | 
 | ||||||
|  | 3 TEXTINCLUDE | ||||||
|  | BEGIN | ||||||
|  |     "\r\n" | ||||||
|  |     "\0" | ||||||
|  | END | ||||||
|  | 
 | ||||||
|  | #endif    // APSTUDIO_INVOKED | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | // | ||||||
|  | // Icon | ||||||
|  | // | ||||||
|  | 
 | ||||||
|  | // Icon with lowest ID value placed first to ensure application icon | ||||||
|  | // remains consistent on all systems. | ||||||
|  | IDI_APP_ICON            ICON                    "resources\\app_icon.ico" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | // | ||||||
|  | // Version | ||||||
|  | // | ||||||
|  | 
 | ||||||
|  | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) | ||||||
|  | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD | ||||||
|  | #else | ||||||
|  | #define VERSION_AS_NUMBER 1,0,0,0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(FLUTTER_VERSION) | ||||||
|  | #define VERSION_AS_STRING FLUTTER_VERSION | ||||||
|  | #else | ||||||
|  | #define VERSION_AS_STRING "1.0.0" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | VS_VERSION_INFO VERSIONINFO | ||||||
|  |  FILEVERSION VERSION_AS_NUMBER | ||||||
|  |  PRODUCTVERSION VERSION_AS_NUMBER | ||||||
|  |  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK | ||||||
|  | #ifdef _DEBUG | ||||||
|  |  FILEFLAGS VS_FF_DEBUG | ||||||
|  | #else | ||||||
|  |  FILEFLAGS 0x0L | ||||||
|  | #endif | ||||||
|  |  FILEOS VOS__WINDOWS32 | ||||||
|  |  FILETYPE VFT_APP | ||||||
|  |  FILESUBTYPE 0x0L | ||||||
|  | BEGIN | ||||||
|  |     BLOCK "StringFileInfo" | ||||||
|  |     BEGIN | ||||||
|  |         BLOCK "040904e4" | ||||||
|  |         BEGIN | ||||||
|  |             VALUE "CompanyName", "io.openim" "\0" | ||||||
|  |             VALUE "FileDescription", "flutter_openim_sdk_example" "\0" | ||||||
|  |             VALUE "FileVersion", VERSION_AS_STRING "\0" | ||||||
|  |             VALUE "InternalName", "flutter_openim_sdk_example" "\0" | ||||||
|  |             VALUE "LegalCopyright", "Copyright (C) 2025 io.openim. All rights reserved." "\0" | ||||||
|  |             VALUE "OriginalFilename", "flutter_openim_sdk_example.exe" "\0" | ||||||
|  |             VALUE "ProductName", "flutter_openim_sdk_example" "\0" | ||||||
|  |             VALUE "ProductVersion", VERSION_AS_STRING "\0" | ||||||
|  |         END | ||||||
|  |     END | ||||||
|  |     BLOCK "VarFileInfo" | ||||||
|  |     BEGIN | ||||||
|  |         VALUE "Translation", 0x409, 1252 | ||||||
|  |     END | ||||||
|  | END | ||||||
|  | 
 | ||||||
|  | #endif    // English (United States) resources | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef APSTUDIO_INVOKED | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | // | ||||||
|  | // Generated from the TEXTINCLUDE 3 resource. | ||||||
|  | // | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ///////////////////////////////////////////////////////////////////////////// | ||||||
|  | #endif    // not APSTUDIO_INVOKED | ||||||
							
								
								
									
										71
									
								
								example/windows/runner/flutter_window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								example/windows/runner/flutter_window.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | #include "flutter_window.h" | ||||||
|  | 
 | ||||||
|  | #include <optional> | ||||||
|  | 
 | ||||||
|  | #include "flutter/generated_plugin_registrant.h" | ||||||
|  | 
 | ||||||
|  | FlutterWindow::FlutterWindow(const flutter::DartProject& project) | ||||||
|  |     : project_(project) {} | ||||||
|  | 
 | ||||||
|  | FlutterWindow::~FlutterWindow() {} | ||||||
|  | 
 | ||||||
|  | bool FlutterWindow::OnCreate() { | ||||||
|  |   if (!Win32Window::OnCreate()) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   RECT frame = GetClientArea(); | ||||||
|  | 
 | ||||||
|  |   // The size here must match the window dimensions to avoid unnecessary surface
 | ||||||
|  |   // creation / destruction in the startup path.
 | ||||||
|  |   flutter_controller_ = std::make_unique<flutter::FlutterViewController>( | ||||||
|  |       frame.right - frame.left, frame.bottom - frame.top, project_); | ||||||
|  |   // Ensure that basic setup of the controller was successful.
 | ||||||
|  |   if (!flutter_controller_->engine() || !flutter_controller_->view()) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |   RegisterPlugins(flutter_controller_->engine()); | ||||||
|  |   SetChildContent(flutter_controller_->view()->GetNativeWindow()); | ||||||
|  | 
 | ||||||
|  |   flutter_controller_->engine()->SetNextFrameCallback([&]() { | ||||||
|  |     this->Show(); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   // Flutter can complete the first frame before the "show window" callback is
 | ||||||
|  |   // registered. The following call ensures a frame is pending to ensure the
 | ||||||
|  |   // window is shown. It is a no-op if the first frame hasn't completed yet.
 | ||||||
|  |   flutter_controller_->ForceRedraw(); | ||||||
|  | 
 | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FlutterWindow::OnDestroy() { | ||||||
|  |   if (flutter_controller_) { | ||||||
|  |     flutter_controller_ = nullptr; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   Win32Window::OnDestroy(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | LRESULT | ||||||
|  | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, | ||||||
|  |                               WPARAM const wparam, | ||||||
|  |                               LPARAM const lparam) noexcept { | ||||||
|  |   // Give Flutter, including plugins, an opportunity to handle window messages.
 | ||||||
|  |   if (flutter_controller_) { | ||||||
|  |     std::optional<LRESULT> result = | ||||||
|  |         flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, | ||||||
|  |                                                       lparam); | ||||||
|  |     if (result) { | ||||||
|  |       return *result; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   switch (message) { | ||||||
|  |     case WM_FONTCHANGE: | ||||||
|  |       flutter_controller_->engine()->ReloadSystemFonts(); | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Win32Window::MessageHandler(hwnd, message, wparam, lparam); | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								example/windows/runner/flutter_window.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								example/windows/runner/flutter_window.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | #ifndef RUNNER_FLUTTER_WINDOW_H_ | ||||||
|  | #define RUNNER_FLUTTER_WINDOW_H_ | ||||||
|  | 
 | ||||||
|  | #include <flutter/dart_project.h> | ||||||
|  | #include <flutter/flutter_view_controller.h> | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | #include "win32_window.h" | ||||||
|  | 
 | ||||||
|  | // A window that does nothing but host a Flutter view.
 | ||||||
|  | class FlutterWindow : public Win32Window { | ||||||
|  |  public: | ||||||
|  |   // Creates a new FlutterWindow hosting a Flutter view running |project|.
 | ||||||
|  |   explicit FlutterWindow(const flutter::DartProject& project); | ||||||
|  |   virtual ~FlutterWindow(); | ||||||
|  | 
 | ||||||
|  |  protected: | ||||||
|  |   // Win32Window:
 | ||||||
|  |   bool OnCreate() override; | ||||||
|  |   void OnDestroy() override; | ||||||
|  |   LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, | ||||||
|  |                          LPARAM const lparam) noexcept override; | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   // The project to run.
 | ||||||
|  |   flutter::DartProject project_; | ||||||
|  | 
 | ||||||
|  |   // The Flutter instance hosted by this window.
 | ||||||
|  |   std::unique_ptr<flutter::FlutterViewController> flutter_controller_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // RUNNER_FLUTTER_WINDOW_H_
 | ||||||
							
								
								
									
										43
									
								
								example/windows/runner/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								example/windows/runner/main.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | #include <flutter/dart_project.h> | ||||||
|  | #include <flutter/flutter_view_controller.h> | ||||||
|  | #include <windows.h> | ||||||
|  | 
 | ||||||
|  | #include "flutter_window.h" | ||||||
|  | #include "utils.h" | ||||||
|  | 
 | ||||||
|  | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, | ||||||
|  |                       _In_ wchar_t *command_line, _In_ int show_command) { | ||||||
|  |   // Attach to console when present (e.g., 'flutter run') or create a
 | ||||||
|  |   // new console when running with a debugger.
 | ||||||
|  |   if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { | ||||||
|  |     CreateAndAttachConsole(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Initialize COM, so that it is available for use in the library and/or
 | ||||||
|  |   // plugins.
 | ||||||
|  |   ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); | ||||||
|  | 
 | ||||||
|  |   flutter::DartProject project(L"data"); | ||||||
|  | 
 | ||||||
|  |   std::vector<std::string> command_line_arguments = | ||||||
|  |       GetCommandLineArguments(); | ||||||
|  | 
 | ||||||
|  |   project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); | ||||||
|  | 
 | ||||||
|  |   FlutterWindow window(project); | ||||||
|  |   Win32Window::Point origin(10, 10); | ||||||
|  |   Win32Window::Size size(1280, 720); | ||||||
|  |   if (!window.Create(L"flutter_openim_sdk_example", origin, size)) { | ||||||
|  |     return EXIT_FAILURE; | ||||||
|  |   } | ||||||
|  |   window.SetQuitOnClose(true); | ||||||
|  | 
 | ||||||
|  |   ::MSG msg; | ||||||
|  |   while (::GetMessage(&msg, nullptr, 0, 0)) { | ||||||
|  |     ::TranslateMessage(&msg); | ||||||
|  |     ::DispatchMessage(&msg); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ::CoUninitialize(); | ||||||
|  |   return EXIT_SUCCESS; | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								example/windows/runner/resource.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								example/windows/runner/resource.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | //{{NO_DEPENDENCIES}}
 | ||||||
|  | // Microsoft Visual C++ generated include file.
 | ||||||
|  | // Used by Runner.rc
 | ||||||
|  | //
 | ||||||
|  | #define IDI_APP_ICON                    101 | ||||||
|  | 
 | ||||||
|  | // Next default values for new objects
 | ||||||
|  | //
 | ||||||
|  | #ifdef APSTUDIO_INVOKED | ||||||
|  | #ifndef APSTUDIO_READONLY_SYMBOLS | ||||||
|  | #define _APS_NEXT_RESOURCE_VALUE        102 | ||||||
|  | #define _APS_NEXT_COMMAND_VALUE         40001 | ||||||
|  | #define _APS_NEXT_CONTROL_VALUE         1001 | ||||||
|  | #define _APS_NEXT_SYMED_VALUE           101 | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
							
								
								
									
										
											BIN
										
									
								
								example/windows/runner/resources/app_icon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								example/windows/runner/resources/app_icon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 33 KiB | 
							
								
								
									
										14
									
								
								example/windows/runner/runner.exe.manifest
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								example/windows/runner/runner.exe.manifest
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||||||
|  | <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> | ||||||
|  |   <application xmlns="urn:schemas-microsoft-com:asm.v3"> | ||||||
|  |     <windowsSettings> | ||||||
|  |       <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness> | ||||||
|  |     </windowsSettings> | ||||||
|  |   </application> | ||||||
|  |   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> | ||||||
|  |     <application> | ||||||
|  |       <!-- Windows 10 and Windows 11 --> | ||||||
|  |       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> | ||||||
|  |     </application> | ||||||
|  |   </compatibility> | ||||||
|  | </assembly> | ||||||
							
								
								
									
										65
									
								
								example/windows/runner/utils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								example/windows/runner/utils.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | |||||||
|  | #include "utils.h" | ||||||
|  | 
 | ||||||
|  | #include <flutter_windows.h> | ||||||
|  | #include <io.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <windows.h> | ||||||
|  | 
 | ||||||
|  | #include <iostream> | ||||||
|  | 
 | ||||||
|  | void CreateAndAttachConsole() { | ||||||
|  |   if (::AllocConsole()) { | ||||||
|  |     FILE *unused; | ||||||
|  |     if (freopen_s(&unused, "CONOUT$", "w", stdout)) { | ||||||
|  |       _dup2(_fileno(stdout), 1); | ||||||
|  |     } | ||||||
|  |     if (freopen_s(&unused, "CONOUT$", "w", stderr)) { | ||||||
|  |       _dup2(_fileno(stdout), 2); | ||||||
|  |     } | ||||||
|  |     std::ios::sync_with_stdio(); | ||||||
|  |     FlutterDesktopResyncOutputStreams(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<std::string> GetCommandLineArguments() { | ||||||
|  |   // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
 | ||||||
|  |   int argc; | ||||||
|  |   wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); | ||||||
|  |   if (argv == nullptr) { | ||||||
|  |     return std::vector<std::string>(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   std::vector<std::string> command_line_arguments; | ||||||
|  | 
 | ||||||
|  |   // Skip the first argument as it's the binary name.
 | ||||||
|  |   for (int i = 1; i < argc; i++) { | ||||||
|  |     command_line_arguments.push_back(Utf8FromUtf16(argv[i])); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ::LocalFree(argv); | ||||||
|  | 
 | ||||||
|  |   return command_line_arguments; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string Utf8FromUtf16(const wchar_t* utf16_string) { | ||||||
|  |   if (utf16_string == nullptr) { | ||||||
|  |     return std::string(); | ||||||
|  |   } | ||||||
|  |   unsigned int target_length = ::WideCharToMultiByte( | ||||||
|  |       CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, | ||||||
|  |       -1, nullptr, 0, nullptr, nullptr) | ||||||
|  |     -1; // remove the trailing null character
 | ||||||
|  |   int input_length = (int)wcslen(utf16_string); | ||||||
|  |   std::string utf8_string; | ||||||
|  |   if (target_length == 0 || target_length > utf8_string.max_size()) { | ||||||
|  |     return utf8_string; | ||||||
|  |   } | ||||||
|  |   utf8_string.resize(target_length); | ||||||
|  |   int converted_length = ::WideCharToMultiByte( | ||||||
|  |       CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, | ||||||
|  |       input_length, utf8_string.data(), target_length, nullptr, nullptr); | ||||||
|  |   if (converted_length == 0) { | ||||||
|  |     return std::string(); | ||||||
|  |   } | ||||||
|  |   return utf8_string; | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								example/windows/runner/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								example/windows/runner/utils.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | #ifndef RUNNER_UTILS_H_ | ||||||
|  | #define RUNNER_UTILS_H_ | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | // Creates a console for the process, and redirects stdout and stderr to
 | ||||||
|  | // it for both the runner and the Flutter library.
 | ||||||
|  | void CreateAndAttachConsole(); | ||||||
|  | 
 | ||||||
|  | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
 | ||||||
|  | // encoded in UTF-8. Returns an empty std::string on failure.
 | ||||||
|  | std::string Utf8FromUtf16(const wchar_t* utf16_string); | ||||||
|  | 
 | ||||||
|  | // Gets the command line arguments passed in as a std::vector<std::string>,
 | ||||||
|  | // encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
 | ||||||
|  | std::vector<std::string> GetCommandLineArguments(); | ||||||
|  | 
 | ||||||
|  | #endif  // RUNNER_UTILS_H_
 | ||||||
							
								
								
									
										288
									
								
								example/windows/runner/win32_window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								example/windows/runner/win32_window.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,288 @@ | |||||||
|  | #include "win32_window.h" | ||||||
|  | 
 | ||||||
|  | #include <dwmapi.h> | ||||||
|  | #include <flutter_windows.h> | ||||||
|  | 
 | ||||||
|  | #include "resource.h" | ||||||
|  | 
 | ||||||
|  | namespace { | ||||||
|  | 
 | ||||||
|  | /// Window attribute that enables dark mode window decorations.
 | ||||||
|  | ///
 | ||||||
|  | /// Redefined in case the developer's machine has a Windows SDK older than
 | ||||||
|  | /// version 10.0.22000.0.
 | ||||||
|  | /// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
 | ||||||
|  | #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE | ||||||
|  | #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; | ||||||
|  | 
 | ||||||
|  | /// Registry key for app theme preference.
 | ||||||
|  | ///
 | ||||||
|  | /// A value of 0 indicates apps should use dark mode. A non-zero or missing
 | ||||||
|  | /// value indicates apps should use light mode.
 | ||||||
|  | constexpr const wchar_t kGetPreferredBrightnessRegKey[] = | ||||||
|  |   L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; | ||||||
|  | constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; | ||||||
|  | 
 | ||||||
|  | // The number of Win32Window objects that currently exist.
 | ||||||
|  | static int g_active_window_count = 0; | ||||||
|  | 
 | ||||||
|  | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); | ||||||
|  | 
 | ||||||
|  | // Scale helper to convert logical scaler values to physical using passed in
 | ||||||
|  | // scale factor
 | ||||||
|  | int Scale(int source, double scale_factor) { | ||||||
|  |   return static_cast<int>(source * scale_factor); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
 | ||||||
|  | // This API is only needed for PerMonitor V1 awareness mode.
 | ||||||
|  | void EnableFullDpiSupportIfAvailable(HWND hwnd) { | ||||||
|  |   HMODULE user32_module = LoadLibraryA("User32.dll"); | ||||||
|  |   if (!user32_module) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   auto enable_non_client_dpi_scaling = | ||||||
|  |       reinterpret_cast<EnableNonClientDpiScaling*>( | ||||||
|  |           GetProcAddress(user32_module, "EnableNonClientDpiScaling")); | ||||||
|  |   if (enable_non_client_dpi_scaling != nullptr) { | ||||||
|  |     enable_non_client_dpi_scaling(hwnd); | ||||||
|  |   } | ||||||
|  |   FreeLibrary(user32_module); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | }  // namespace
 | ||||||
|  | 
 | ||||||
|  | // Manages the Win32Window's window class registration.
 | ||||||
|  | class WindowClassRegistrar { | ||||||
|  |  public: | ||||||
|  |   ~WindowClassRegistrar() = default; | ||||||
|  | 
 | ||||||
|  |   // Returns the singleton registrar instance.
 | ||||||
|  |   static WindowClassRegistrar* GetInstance() { | ||||||
|  |     if (!instance_) { | ||||||
|  |       instance_ = new WindowClassRegistrar(); | ||||||
|  |     } | ||||||
|  |     return instance_; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Returns the name of the window class, registering the class if it hasn't
 | ||||||
|  |   // previously been registered.
 | ||||||
|  |   const wchar_t* GetWindowClass(); | ||||||
|  | 
 | ||||||
|  |   // Unregisters the window class. Should only be called if there are no
 | ||||||
|  |   // instances of the window.
 | ||||||
|  |   void UnregisterWindowClass(); | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   WindowClassRegistrar() = default; | ||||||
|  | 
 | ||||||
|  |   static WindowClassRegistrar* instance_; | ||||||
|  | 
 | ||||||
|  |   bool class_registered_ = false; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; | ||||||
|  | 
 | ||||||
|  | const wchar_t* WindowClassRegistrar::GetWindowClass() { | ||||||
|  |   if (!class_registered_) { | ||||||
|  |     WNDCLASS window_class{}; | ||||||
|  |     window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); | ||||||
|  |     window_class.lpszClassName = kWindowClassName; | ||||||
|  |     window_class.style = CS_HREDRAW | CS_VREDRAW; | ||||||
|  |     window_class.cbClsExtra = 0; | ||||||
|  |     window_class.cbWndExtra = 0; | ||||||
|  |     window_class.hInstance = GetModuleHandle(nullptr); | ||||||
|  |     window_class.hIcon = | ||||||
|  |         LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); | ||||||
|  |     window_class.hbrBackground = 0; | ||||||
|  |     window_class.lpszMenuName = nullptr; | ||||||
|  |     window_class.lpfnWndProc = Win32Window::WndProc; | ||||||
|  |     RegisterClass(&window_class); | ||||||
|  |     class_registered_ = true; | ||||||
|  |   } | ||||||
|  |   return kWindowClassName; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void WindowClassRegistrar::UnregisterWindowClass() { | ||||||
|  |   UnregisterClass(kWindowClassName, nullptr); | ||||||
|  |   class_registered_ = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Win32Window::Win32Window() { | ||||||
|  |   ++g_active_window_count; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Win32Window::~Win32Window() { | ||||||
|  |   --g_active_window_count; | ||||||
|  |   Destroy(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Win32Window::Create(const std::wstring& title, | ||||||
|  |                          const Point& origin, | ||||||
|  |                          const Size& size) { | ||||||
|  |   Destroy(); | ||||||
|  | 
 | ||||||
|  |   const wchar_t* window_class = | ||||||
|  |       WindowClassRegistrar::GetInstance()->GetWindowClass(); | ||||||
|  | 
 | ||||||
|  |   const POINT target_point = {static_cast<LONG>(origin.x), | ||||||
|  |                               static_cast<LONG>(origin.y)}; | ||||||
|  |   HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); | ||||||
|  |   UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); | ||||||
|  |   double scale_factor = dpi / 96.0; | ||||||
|  | 
 | ||||||
|  |   HWND window = CreateWindow( | ||||||
|  |       window_class, title.c_str(), WS_OVERLAPPEDWINDOW, | ||||||
|  |       Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), | ||||||
|  |       Scale(size.width, scale_factor), Scale(size.height, scale_factor), | ||||||
|  |       nullptr, nullptr, GetModuleHandle(nullptr), this); | ||||||
|  | 
 | ||||||
|  |   if (!window) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   UpdateTheme(window); | ||||||
|  | 
 | ||||||
|  |   return OnCreate(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Win32Window::Show() { | ||||||
|  |   return ShowWindow(window_handle_, SW_SHOWNORMAL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // static
 | ||||||
|  | LRESULT CALLBACK Win32Window::WndProc(HWND const window, | ||||||
|  |                                       UINT const message, | ||||||
|  |                                       WPARAM const wparam, | ||||||
|  |                                       LPARAM const lparam) noexcept { | ||||||
|  |   if (message == WM_NCCREATE) { | ||||||
|  |     auto window_struct = reinterpret_cast<CREATESTRUCT*>(lparam); | ||||||
|  |     SetWindowLongPtr(window, GWLP_USERDATA, | ||||||
|  |                      reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams)); | ||||||
|  | 
 | ||||||
|  |     auto that = static_cast<Win32Window*>(window_struct->lpCreateParams); | ||||||
|  |     EnableFullDpiSupportIfAvailable(window); | ||||||
|  |     that->window_handle_ = window; | ||||||
|  |   } else if (Win32Window* that = GetThisFromHandle(window)) { | ||||||
|  |     return that->MessageHandler(window, message, wparam, lparam); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return DefWindowProc(window, message, wparam, lparam); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | LRESULT | ||||||
|  | Win32Window::MessageHandler(HWND hwnd, | ||||||
|  |                             UINT const message, | ||||||
|  |                             WPARAM const wparam, | ||||||
|  |                             LPARAM const lparam) noexcept { | ||||||
|  |   switch (message) { | ||||||
|  |     case WM_DESTROY: | ||||||
|  |       window_handle_ = nullptr; | ||||||
|  |       Destroy(); | ||||||
|  |       if (quit_on_close_) { | ||||||
|  |         PostQuitMessage(0); | ||||||
|  |       } | ||||||
|  |       return 0; | ||||||
|  | 
 | ||||||
|  |     case WM_DPICHANGED: { | ||||||
|  |       auto newRectSize = reinterpret_cast<RECT*>(lparam); | ||||||
|  |       LONG newWidth = newRectSize->right - newRectSize->left; | ||||||
|  |       LONG newHeight = newRectSize->bottom - newRectSize->top; | ||||||
|  | 
 | ||||||
|  |       SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, | ||||||
|  |                    newHeight, SWP_NOZORDER | SWP_NOACTIVATE); | ||||||
|  | 
 | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     case WM_SIZE: { | ||||||
|  |       RECT rect = GetClientArea(); | ||||||
|  |       if (child_content_ != nullptr) { | ||||||
|  |         // Size and position the child window.
 | ||||||
|  |         MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, | ||||||
|  |                    rect.bottom - rect.top, TRUE); | ||||||
|  |       } | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     case WM_ACTIVATE: | ||||||
|  |       if (child_content_ != nullptr) { | ||||||
|  |         SetFocus(child_content_); | ||||||
|  |       } | ||||||
|  |       return 0; | ||||||
|  | 
 | ||||||
|  |     case WM_DWMCOLORIZATIONCOLORCHANGED: | ||||||
|  |       UpdateTheme(hwnd); | ||||||
|  |       return 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return DefWindowProc(window_handle_, message, wparam, lparam); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Win32Window::Destroy() { | ||||||
|  |   OnDestroy(); | ||||||
|  | 
 | ||||||
|  |   if (window_handle_) { | ||||||
|  |     DestroyWindow(window_handle_); | ||||||
|  |     window_handle_ = nullptr; | ||||||
|  |   } | ||||||
|  |   if (g_active_window_count == 0) { | ||||||
|  |     WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { | ||||||
|  |   return reinterpret_cast<Win32Window*>( | ||||||
|  |       GetWindowLongPtr(window, GWLP_USERDATA)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Win32Window::SetChildContent(HWND content) { | ||||||
|  |   child_content_ = content; | ||||||
|  |   SetParent(content, window_handle_); | ||||||
|  |   RECT frame = GetClientArea(); | ||||||
|  | 
 | ||||||
|  |   MoveWindow(content, frame.left, frame.top, frame.right - frame.left, | ||||||
|  |              frame.bottom - frame.top, true); | ||||||
|  | 
 | ||||||
|  |   SetFocus(child_content_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RECT Win32Window::GetClientArea() { | ||||||
|  |   RECT frame; | ||||||
|  |   GetClientRect(window_handle_, &frame); | ||||||
|  |   return frame; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | HWND Win32Window::GetHandle() { | ||||||
|  |   return window_handle_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Win32Window::SetQuitOnClose(bool quit_on_close) { | ||||||
|  |   quit_on_close_ = quit_on_close; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Win32Window::OnCreate() { | ||||||
|  |   // No-op; provided for subclasses.
 | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Win32Window::OnDestroy() { | ||||||
|  |   // No-op; provided for subclasses.
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Win32Window::UpdateTheme(HWND const window) { | ||||||
|  |   DWORD light_mode; | ||||||
|  |   DWORD light_mode_size = sizeof(light_mode); | ||||||
|  |   LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, | ||||||
|  |                                kGetPreferredBrightnessRegValue, | ||||||
|  |                                RRF_RT_REG_DWORD, nullptr, &light_mode, | ||||||
|  |                                &light_mode_size); | ||||||
|  | 
 | ||||||
|  |   if (result == ERROR_SUCCESS) { | ||||||
|  |     BOOL enable_dark_mode = light_mode == 0; | ||||||
|  |     DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, | ||||||
|  |                           &enable_dark_mode, sizeof(enable_dark_mode)); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										102
									
								
								example/windows/runner/win32_window.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								example/windows/runner/win32_window.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | #ifndef RUNNER_WIN32_WINDOW_H_ | ||||||
|  | #define RUNNER_WIN32_WINDOW_H_ | ||||||
|  | 
 | ||||||
|  | #include <windows.h> | ||||||
|  | 
 | ||||||
|  | #include <functional> | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | // A class abstraction for a high DPI-aware Win32 Window. Intended to be
 | ||||||
|  | // inherited from by classes that wish to specialize with custom
 | ||||||
|  | // rendering and input handling
 | ||||||
|  | class Win32Window { | ||||||
|  |  public: | ||||||
|  |   struct Point { | ||||||
|  |     unsigned int x; | ||||||
|  |     unsigned int y; | ||||||
|  |     Point(unsigned int x, unsigned int y) : x(x), y(y) {} | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   struct Size { | ||||||
|  |     unsigned int width; | ||||||
|  |     unsigned int height; | ||||||
|  |     Size(unsigned int width, unsigned int height) | ||||||
|  |         : width(width), height(height) {} | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   Win32Window(); | ||||||
|  |   virtual ~Win32Window(); | ||||||
|  | 
 | ||||||
|  |   // Creates a win32 window with |title| that is positioned and sized using
 | ||||||
|  |   // |origin| and |size|. New windows are created on the default monitor. Window
 | ||||||
|  |   // sizes are specified to the OS in physical pixels, hence to ensure a
 | ||||||
|  |   // consistent size this function will scale the inputted width and height as
 | ||||||
|  |   // as appropriate for the default monitor. The window is invisible until
 | ||||||
|  |   // |Show| is called. Returns true if the window was created successfully.
 | ||||||
|  |   bool Create(const std::wstring& title, const Point& origin, const Size& size); | ||||||
|  | 
 | ||||||
|  |   // Show the current window. Returns true if the window was successfully shown.
 | ||||||
|  |   bool Show(); | ||||||
|  | 
 | ||||||
|  |   // Release OS resources associated with window.
 | ||||||
|  |   void Destroy(); | ||||||
|  | 
 | ||||||
|  |   // Inserts |content| into the window tree.
 | ||||||
|  |   void SetChildContent(HWND content); | ||||||
|  | 
 | ||||||
|  |   // Returns the backing Window handle to enable clients to set icon and other
 | ||||||
|  |   // window properties. Returns nullptr if the window has been destroyed.
 | ||||||
|  |   HWND GetHandle(); | ||||||
|  | 
 | ||||||
|  |   // If true, closing this window will quit the application.
 | ||||||
|  |   void SetQuitOnClose(bool quit_on_close); | ||||||
|  | 
 | ||||||
|  |   // Return a RECT representing the bounds of the current client area.
 | ||||||
|  |   RECT GetClientArea(); | ||||||
|  | 
 | ||||||
|  |  protected: | ||||||
|  |   // Processes and route salient window messages for mouse handling,
 | ||||||
|  |   // size change and DPI. Delegates handling of these to member overloads that
 | ||||||
|  |   // inheriting classes can handle.
 | ||||||
|  |   virtual LRESULT MessageHandler(HWND window, | ||||||
|  |                                  UINT const message, | ||||||
|  |                                  WPARAM const wparam, | ||||||
|  |                                  LPARAM const lparam) noexcept; | ||||||
|  | 
 | ||||||
|  |   // Called when CreateAndShow is called, allowing subclass window-related
 | ||||||
|  |   // setup. Subclasses should return false if setup fails.
 | ||||||
|  |   virtual bool OnCreate(); | ||||||
|  | 
 | ||||||
|  |   // Called when Destroy is called.
 | ||||||
|  |   virtual void OnDestroy(); | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   friend class WindowClassRegistrar; | ||||||
|  | 
 | ||||||
|  |   // OS callback called by message pump. Handles the WM_NCCREATE message which
 | ||||||
|  |   // is passed when the non-client area is being created and enables automatic
 | ||||||
|  |   // non-client DPI scaling so that the non-client area automatically
 | ||||||
|  |   // responds to changes in DPI. All other messages are handled by
 | ||||||
|  |   // MessageHandler.
 | ||||||
|  |   static LRESULT CALLBACK WndProc(HWND const window, | ||||||
|  |                                   UINT const message, | ||||||
|  |                                   WPARAM const wparam, | ||||||
|  |                                   LPARAM const lparam) noexcept; | ||||||
|  | 
 | ||||||
|  |   // Retrieves a class instance pointer for |window|
 | ||||||
|  |   static Win32Window* GetThisFromHandle(HWND const window) noexcept; | ||||||
|  | 
 | ||||||
|  |   // Update the window frame's theme to match the system theme.
 | ||||||
|  |   static void UpdateTheme(HWND const window); | ||||||
|  | 
 | ||||||
|  |   bool quit_on_close_ = false; | ||||||
|  | 
 | ||||||
|  |   // window handle for top level window.
 | ||||||
|  |   HWND window_handle_ = nullptr; | ||||||
|  | 
 | ||||||
|  |   // window handle for hosted content.
 | ||||||
|  |   HWND child_content_ = nullptr; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // RUNNER_WIN32_WINDOW_H_
 | ||||||
							
								
								
									
										38
									
								
								ios/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								ios/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | |||||||
|  | .idea/ | ||||||
|  | .vagrant/ | ||||||
|  | .sconsign.dblite | ||||||
|  | .svn/ | ||||||
|  | 
 | ||||||
|  | .DS_Store | ||||||
|  | *.swp | ||||||
|  | profile | ||||||
|  | 
 | ||||||
|  | DerivedData/ | ||||||
|  | build/ | ||||||
|  | GeneratedPluginRegistrant.h | ||||||
|  | GeneratedPluginRegistrant.m | ||||||
|  | 
 | ||||||
|  | .generated/ | ||||||
|  | 
 | ||||||
|  | *.pbxuser | ||||||
|  | *.mode1v3 | ||||||
|  | *.mode2v3 | ||||||
|  | *.perspectivev3 | ||||||
|  | 
 | ||||||
|  | !default.pbxuser | ||||||
|  | !default.mode1v3 | ||||||
|  | !default.mode2v3 | ||||||
|  | !default.perspectivev3 | ||||||
|  | 
 | ||||||
|  | xcuserdata | ||||||
|  | 
 | ||||||
|  | *.moved-aside | ||||||
|  | 
 | ||||||
|  | *.pyc | ||||||
|  | *sync/ | ||||||
|  | Icon? | ||||||
|  | .tags* | ||||||
|  | 
 | ||||||
|  | /Flutter/Generated.xcconfig | ||||||
|  | /Flutter/ephemeral/ | ||||||
|  | /Flutter/flutter_export_environment.sh | ||||||
| @ -32,7 +32,8 @@ flutter: | |||||||
|         pluginClass: FlutterOpenimSdkPlugin |         pluginClass: FlutterOpenimSdkPlugin | ||||||
|       ios: |       ios: | ||||||
|         pluginClass: FlutterOpenimSdkPlugin |         pluginClass: FlutterOpenimSdkPlugin | ||||||
| 
 |       windows: | ||||||
|  |         pluginClass: FlutterOpenimSdkPlugin | ||||||
|   # To add assets to your plugin package, add an assets section, like this: |   # To add assets to your plugin package, add an assets section, like this: | ||||||
|   # assets: |   # assets: | ||||||
|   #   - images/a_dot_burr.jpeg |   #   - images/a_dot_burr.jpeg | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								windows/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								windows/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | flutter/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio user-specific files. | ||||||
|  | *.suo | ||||||
|  | *.user | ||||||
|  | *.userosscache | ||||||
|  | *.sln.docstates | ||||||
|  | 
 | ||||||
|  | # Visual Studio build-related files. | ||||||
|  | x64/ | ||||||
|  | x86/ | ||||||
|  | 
 | ||||||
|  | # Visual Studio cache files | ||||||
|  | # files ending in .cache can be ignored | ||||||
|  | *.[Cc]ache | ||||||
|  | # but keep track of directories ending in .cache | ||||||
|  | !*.[Cc]ache/ | ||||||
							
								
								
									
										105
									
								
								windows/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								windows/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | # The Flutter tooling requires that developers have a version of Visual Studio | ||||||
|  | # installed that includes CMake 3.14 or later. You should not increase this | ||||||
|  | # version, as doing so will cause the plugin to fail to compile for some | ||||||
|  | # customers of the plugin. | ||||||
|  | cmake_minimum_required(VERSION 3.14) | ||||||
|  | 
 | ||||||
|  | # Project-level configuration. | ||||||
|  | set(PROJECT_NAME "flutter_openim_sdk") | ||||||
|  | project(${PROJECT_NAME} LANGUAGES CXX) | ||||||
|  | 
 | ||||||
|  | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent | ||||||
|  | # versions of CMake. | ||||||
|  | cmake_policy(VERSION 3.14...3.25) | ||||||
|  | 
 | ||||||
|  | # This value is used when generating builds using this plugin, so it must | ||||||
|  | # not be changed | ||||||
|  | set(PLUGIN_NAME "flutter_openim_sdk_plugin") | ||||||
|  | set(PCH_HEADER_FILE ${CMAKE_CURRENT_LIST_DIR}/src/common/stable.h) | ||||||
|  | 
 | ||||||
|  | # third_party_libs | ||||||
|  | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/third_party/alog/include") | ||||||
|  | link_directories("${CMAKE_CURRENT_SOURCE_DIR}/third_party/alog/lib/x64/${CMAKE_BUILD_TYPE}") | ||||||
|  | 
 | ||||||
|  | FILE(GLOB SELF_TEMP_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/*.cpp src/*.h) | ||||||
|  | source_group(src FILES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | list(APPEND NIM_CORE_SOURCES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | 
 | ||||||
|  | FILE(GLOB SELF_TEMP_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/common/*.cpp src/common/*.h) | ||||||
|  | source_group(src/common FILES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | list(APPEND NIM_CORE_SOURCES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | 
 | ||||||
|  | FILE(GLOB SELF_TEMP_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/common/services/*.cpp src/common/services/*.h) | ||||||
|  | source_group(src/common/services FILES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | list(APPEND NIM_CORE_SOURCES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | 
 | ||||||
|  | FILE(GLOB SELF_TEMP_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/common/utils/*.cpp src/common/utils/*.h src/common/utils/*.hpp) | ||||||
|  | source_group(src/common/utils FILES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | list(APPEND NIM_CORE_SOURCES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | 
 | ||||||
|  | FILE(GLOB SELF_TEMP_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/utils/*.cpp src/utils/*.h) | ||||||
|  | source_group(src/utils FILES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | list(APPEND NIM_CORE_SOURCES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | 
 | ||||||
|  | FILE(GLOB SELF_TEMP_SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/utils/dump/*.cpp src/utils/dump/*.h) | ||||||
|  | source_group(src/utils/dump FILES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | list(APPEND NIM_CORE_SOURCES ${SELF_TEMP_SRC_FILES}) | ||||||
|  | 
 | ||||||
|  | # Any new source files that you add to the plugin should be added here. | ||||||
|  | list(APPEND PLUGIN_SOURCES | ||||||
|  |         ${CMAKE_CURRENT_LIST_DIR}/flutter_openim_sdk_plugin.cpp | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | add_library(${PLUGIN_NAME} SHARED | ||||||
|  |         ${PLUGIN_SOURCES} | ||||||
|  |         ${NIM_CORE_SOURCES} | ||||||
|  | ) | ||||||
|  | target_precompile_headers(${PLUGIN_NAME} PRIVATE ${PCH_HEADER_FILE}) | ||||||
|  | target_link_libraries(${PLUGIN_NAME} PRIVATE yx_alog) | ||||||
|  | 
 | ||||||
|  | # Apply a standard set of build settings that are configured in the | ||||||
|  | # application-level CMakeLists.txt. This can be removed for plugins that want | ||||||
|  | # full control over build settings. | ||||||
|  | apply_standard_settings(${PLUGIN_NAME}) | ||||||
|  | 
 | ||||||
|  | # Symbols are hidden by default to reduce the chance of accidental conflicts | ||||||
|  | # between plugins. This should not be removed; any symbols that should be | ||||||
|  | # exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro. | ||||||
|  | set_target_properties(${PLUGIN_NAME} PROPERTIES | ||||||
|  |   CXX_VISIBILITY_PRESET hidden) | ||||||
|  | target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) | ||||||
|  | target_compile_options(${PLUGIN_NAME} PRIVATE /W4 /WX- /wd4100 /wd4267 /wd4189 /wd4244 /wd4996 /bigobj /utf-8) | ||||||
|  | 
 | ||||||
|  | target_include_directories(${PLUGIN_NAME} PUBLIC | ||||||
|  |         "${CMAKE_CURRENT_LIST_DIR}/include" | ||||||
|  |         "${CMAKE_CURRENT_LIST_DIR}/" | ||||||
|  |         "${CMAKE_CURRENT_LIST_DIR}/openlib/x64/include" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | target_link_libraries(${PLUGIN_NAME} PRIVATE | ||||||
|  |         flutter | ||||||
|  |         flutter_wrapper_plugin | ||||||
|  |         ${CMAKE_CURRENT_LIST_DIR}/openlib/x64/libopenimsdk.lib | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | file(GLOB flutter_openim_sdk_bundled_libraries | ||||||
|  |         "${CMAKE_CURRENT_LIST_DIR}/openlib/x64/*.dll" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | file(GLOB LIBRARY_FILES "${CMAKE_CURRENT_LIST_DIR}/openlib/x64/*") | ||||||
|  | foreach(LIB_FILE ${LIBRARY_FILES}) | ||||||
|  |     if(LIB_FILE MATCHES "cacert\.pem") | ||||||
|  |         # 添加库文件路径到变量 | ||||||
|  |         list(APPEND flutter_openim_sdk_bundled_libraries ${LIB_FILE}) | ||||||
|  |     endif() | ||||||
|  | endforeach() | ||||||
|  | 
 | ||||||
|  | set(flutter_openim_sdk_bundled_libraries ${flutter_openim_sdk_bundled_libraries} PARENT_SCOPE) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/openlib/libopenimsdk.dll | ||||||
|  | #        DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" | ||||||
|  | #) | ||||||
							
								
								
									
										104
									
								
								windows/flutter_openim_sdk_plugin.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								windows/flutter_openim_sdk_plugin.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | #include "include/flutter_openim_sdk/flutter_openim_sdk_plugin.h" | ||||||
|  | 
 | ||||||
|  | // This must be included before many other Windows headers.
 | ||||||
|  | #include <windows.h> | ||||||
|  | 
 | ||||||
|  | // For getPlatformVersion; remove unless needed for your plugin implementation.
 | ||||||
|  | #include <VersionHelpers.h> | ||||||
|  | 
 | ||||||
|  | #include <flutter/method_channel.h> | ||||||
|  | #include <flutter/plugin_registrar_windows.h> | ||||||
|  | #include <flutter/standard_method_codec.h> | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <sstream> | ||||||
|  | #include "src/MethodCallHandlerImpl.h" | ||||||
|  | #include "src/common/stable.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FlutterOpenimSdkPlugin : public flutter::Plugin { | ||||||
|  | public: | ||||||
|  |     static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar); | ||||||
|  | 
 | ||||||
|  |     FlutterOpenimSdkPlugin(); | ||||||
|  | 
 | ||||||
|  |     virtual ~FlutterOpenimSdkPlugin(); | ||||||
|  | 
 | ||||||
|  |     // Disallow copy and assign.
 | ||||||
|  |     FlutterOpenimSdkPlugin(const FlutterOpenimSdkPlugin &) = delete; | ||||||
|  | 
 | ||||||
|  |     FlutterOpenimSdkPlugin &operator=(const FlutterOpenimSdkPlugin &) = delete; | ||||||
|  | 
 | ||||||
|  |     // Called when a method is called on this plugin's channel from Dart.
 | ||||||
|  |     void HandleMethodCall( | ||||||
|  |             const flutter::MethodCall <flutter::EncodableValue> &method_call, | ||||||
|  |             std::unique_ptr <flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     std::unique_ptr<MethodCallHandlerImpl> m_channel; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //std::string ws2s(const std::wstring& wstr) {
 | ||||||
|  | //    using convert_typeX = std::codecvt_utf8<wchar_t>;
 | ||||||
|  | //    std::wstring_convert<convert_typeX, wchar_t> converterX;
 | ||||||
|  | //    return converterX.to_bytes(wstr);
 | ||||||
|  | //}
 | ||||||
|  | 
 | ||||||
|  | // static
 | ||||||
|  | void FlutterOpenimSdkPlugin::RegisterWithRegistrar( | ||||||
|  |         flutter::PluginRegistrarWindows *registrar) { | ||||||
|  | 
 | ||||||
|  |     //std::string filePath = ws2s(_wgetenv(L"LOCALAPPDATA"));
 | ||||||
|  |     std::string filePath = std::getenv("LOCALAPPDATA"); | ||||||
|  |     std::string filePathApp; | ||||||
|  |     if (!filePath.empty()) { | ||||||
|  |         filePath.append("/OpenIM/OpenimPlugin"); | ||||||
|  |     } else { | ||||||
|  |         std::cout << "log filePath empty!" << std::endl; | ||||||
|  |     } | ||||||
|  |     filePathApp = filePath; | ||||||
|  |     filePathApp.append("/app"); | ||||||
|  |     std::cout << "log filePath: " << filePathApp.c_str() << std::endl; | ||||||
|  |     ALog::CreateInstance(filePathApp, "nim_core_plugin", Info); | ||||||
|  |     ALog::GetInstance()->setShortFileName(true); | ||||||
|  |     YXLOG(Info) << "===================start===================" << YXLOGEnd; | ||||||
|  |     YXLOG_API(Info) << "RegisterWithRegistrar, logPath: " << filePathApp | ||||||
|  |                     << YXLOGEnd; | ||||||
|  |     //InitDumpInfo("");
 | ||||||
|  | 
 | ||||||
|  |     NimCore::getInstance()->setLogDir(filePath); | ||||||
|  | 
 | ||||||
|  |     auto plugin = std::make_unique<FlutterOpenimSdkPlugin>(); | ||||||
|  |     auto channel = plugin->m_channel->startListening(registrar); | ||||||
|  |     channel->SetMethodCallHandler( | ||||||
|  |             [plugin_pointer = plugin.get()](const auto &call, auto result) { | ||||||
|  |                 plugin_pointer->HandleMethodCall(call, std::move(result)); | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     registrar->AddPlugin(std::move(plugin)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FlutterOpenimSdkPlugin::FlutterOpenimSdkPlugin() { | ||||||
|  |     m_channel = std::make_unique<MethodCallHandlerImpl>(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FlutterOpenimSdkPlugin::~FlutterOpenimSdkPlugin() { | ||||||
|  |     m_channel.reset(nullptr); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void FlutterOpenimSdkPlugin::HandleMethodCall( | ||||||
|  |         const flutter::MethodCall <flutter::EncodableValue> &method_call, | ||||||
|  |         std::unique_ptr <flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |         m_channel->onMethodCall(method_call, std::move(result)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void FlutterOpenimSdkPluginRegisterWithRegistrar(FlutterDesktopPluginRegistrarRef registrar) { | ||||||
|  |     FlutterOpenimSdkPlugin::RegisterWithRegistrar( | ||||||
|  |             flutter::PluginRegistrarManager::GetInstance() | ||||||
|  |                     ->GetRegistrar<flutter::PluginRegistrarWindows>(registrar)); | ||||||
|  | } | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | #ifndef FLUTTER_PLUGIN_FLUTTER_OPENIM_SDK_PLUGIN_H_ | ||||||
|  | #define FLUTTER_PLUGIN_FLUTTER_OPENIM_SDK_PLUGIN_H_ | ||||||
|  | 
 | ||||||
|  | #include <flutter/plugin_registrar_windows.h> | ||||||
|  | #include <flutter_plugin_registrar.h> | ||||||
|  | 
 | ||||||
|  | #ifdef FLUTTER_PLUGIN_IMPL | ||||||
|  | #define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) | ||||||
|  | #else | ||||||
|  | #define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | FLUTTER_PLUGIN_EXPORT void FlutterOpenimSdkPluginRegisterWithRegistrar( | ||||||
|  |         FlutterDesktopPluginRegistrarRef registrar); | ||||||
|  | 
 | ||||||
|  | #if defined(__cplusplus) | ||||||
|  | }  // extern "C"
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif  // FLUTTER_PLUGIN_FLUTTER_OPENIM_SDK_PLUGIN_H_
 | ||||||
							
								
								
									
										46
									
								
								windows/src/FLTConvert.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								windows/src/FLTConvert.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #include "FLTConvert.h" | ||||||
|  | 
 | ||||||
|  | Convert::Convert() {} | ||||||
|  | 
 | ||||||
|  | std::string Convert::getStringFormMapForLog( | ||||||
|  |     const flutter::EncodableMap* arguments) const { | ||||||
|  |   if (!arguments) { | ||||||
|  |     return ""; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // todo
 | ||||||
|  |   return ""; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Convert::getLogList(const std::string& strLog, | ||||||
|  |                          std::list<std::string>& listLog) const { | ||||||
|  |   listLog.clear(); | ||||||
|  |   int num = 15 * 1024;        // 分割定长大小
 | ||||||
|  |   int len = strLog.length();  // 字符串长度
 | ||||||
|  |   int end = num; | ||||||
|  |   for (int start = 0; start < len;) { | ||||||
|  |     if (end > len)  // 针对最后一个分割串
 | ||||||
|  |     { | ||||||
|  |       listLog.emplace_back( | ||||||
|  |           strLog.substr(start, len - start));  // 最后一个字符串的原始部分
 | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |     listLog.emplace_back( | ||||||
|  |         strLog.substr(start, num));  // 从0开始,分割num位字符串
 | ||||||
|  |     start = end; | ||||||
|  |     end = end + num; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string Convert::getStringFormListForLog( | ||||||
|  |     const flutter::EncodableList* arguments) const { | ||||||
|  |   if (!arguments) { | ||||||
|  |     return ""; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return ""; | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								windows/src/FLTConvert.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								windows/src/FLTConvert.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef FLTCONVERT_H | ||||||
|  | #define FLTCONVERT_H | ||||||
|  | 
 | ||||||
|  | #include <string> | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | #include "common/FLTService.h" | ||||||
|  | #include "common/utils/singleton.h" | ||||||
|  | 
 | ||||||
|  | class Convert { | ||||||
|  |  public: | ||||||
|  |   SINGLETONG(Convert) | ||||||
|  | 
 | ||||||
|  |   std::string getStringFormMapForLog( | ||||||
|  |       const flutter::EncodableMap* arguments) const; | ||||||
|  |   void getLogList(const std::string& strLog, | ||||||
|  |                   std::list<std::string>& listLog) const; | ||||||
|  |   std::string getStringFormListForLog( | ||||||
|  |       const flutter::EncodableList* arguments) const; | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   Convert(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // FLTCONVERT_H
 | ||||||
							
								
								
									
										45
									
								
								windows/src/MethodCallHandlerImpl.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								windows/src/MethodCallHandlerImpl.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #include "MethodCallHandlerImpl.h" | ||||||
|  | 
 | ||||||
|  | #include <flutter/method_channel.h> | ||||||
|  | #include <flutter/plugin_registrar_windows.h> | ||||||
|  | #include <flutter/standard_method_codec.h> | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | #include "NimCore.h" | ||||||
|  | 
 | ||||||
|  | MethodCallHandlerImpl::MethodCallHandlerImpl() {} | ||||||
|  | 
 | ||||||
|  | void MethodCallHandlerImpl::onMethodCall( | ||||||
|  |         const flutter::MethodCall <flutter::EncodableValue> &method_call, | ||||||
|  |         std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     const auto *arguments = | ||||||
|  |             std::get_if<flutter::EncodableMap>(method_call.arguments()); | ||||||
|  |     if (arguments) { | ||||||
|  |         NimCore::getInstance()->onMethodCall(method_call.method_name(), arguments, | ||||||
|  |                                              result); | ||||||
|  |     } else { | ||||||
|  |         if (result) { | ||||||
|  |             result->NotImplemented(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | flutter::MethodChannel <flutter::EncodableValue> * | ||||||
|  | MethodCallHandlerImpl::startListening(flutter::PluginRegistrar *registrar) { | ||||||
|  |     m_methodChannel = | ||||||
|  |             std::make_unique < flutter::MethodChannel < flutter::EncodableValue >> ( | ||||||
|  |                     registrar->messenger(), "flutter_openim_sdk", | ||||||
|  |                             &flutter::StandardMethodCodec::GetInstance()); | ||||||
|  | 
 | ||||||
|  |     NimCore::getInstance()->setMethodChannel(m_methodChannel.get()); | ||||||
|  |     return m_methodChannel.get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void MethodCallHandlerImpl::stopListening() { | ||||||
|  |     NimCore::getInstance()->setMethodChannel(nullptr); | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								windows/src/MethodCallHandlerImpl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								windows/src/MethodCallHandlerImpl.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef METHODCALLHANDLERIMPL_H | ||||||
|  | #define METHODCALLHANDLERIMPL_H | ||||||
|  | 
 | ||||||
|  | #include <flutter/method_channel.h> | ||||||
|  | #include <flutter/plugin_registrar_windows.h> | ||||||
|  | #include <flutter/standard_method_codec.h> | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | #include "NimCore.h" | ||||||
|  | 
 | ||||||
|  | class MethodCallHandlerImpl { | ||||||
|  |  public: | ||||||
|  |   MethodCallHandlerImpl(); | ||||||
|  | 
 | ||||||
|  |   void onMethodCall( | ||||||
|  |       const flutter::MethodCall<flutter::EncodableValue>& method_call, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   flutter::MethodChannel<flutter::EncodableValue>* startListening( | ||||||
|  |       flutter::PluginRegistrar* registrar); | ||||||
|  | 
 | ||||||
|  |   void stopListening(); | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> | ||||||
|  |       m_methodChannel; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // METHODCALLHANDLERIMPL_H
 | ||||||
							
								
								
									
										252
									
								
								windows/src/NimCore.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								windows/src/NimCore.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,252 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #include "NimCore.h" | ||||||
|  | 
 | ||||||
|  | #include <flutter/encodable_value.h> | ||||||
|  | #include <flutter/method_channel.h> | ||||||
|  | #include <flutter/plugin_registrar_windows.h> | ||||||
|  | #include <flutter/standard_method_codec.h> | ||||||
|  | 
 | ||||||
|  | #include "FLTConvert.h" | ||||||
|  | 
 | ||||||
|  | #include "common/services/IMManager.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const std::string kFLTNimCoreService = "serviceName"; | ||||||
|  | 
 | ||||||
|  | NimCore::NimCore() { regService(); } | ||||||
|  | 
 | ||||||
|  | NimCore::~NimCore() {} | ||||||
|  | 
 | ||||||
|  | void NimCore::regService() { | ||||||
|  |   addService(new IMManagerService()); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NimCore::cleanService() { | ||||||
|  |  // m_services.clear();
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NimCore::addService(FLTService* service) { | ||||||
|  |   m_services[service->getServiceName()] = service; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // FLTMessageService* NimCore::getFLTMessageService() const {
 | ||||||
|  | //   return dynamic_cast<FLTMessageService*>(getService("MessageService"));
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | FLTService* NimCore::getService(const std::string& serviceName) const { | ||||||
|  |   auto service = m_services.find(serviceName); | ||||||
|  |   if (m_services.end() == service) { | ||||||
|  |     return nullptr; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return service->second; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NimCore::onMethodCall( | ||||||
|  |     const std::string& method, const flutter::EncodableMap* arguments, | ||||||
|  |     std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |   if (nullptr == arguments) { | ||||||
|  |     if (result) { | ||||||
|  |       result->NotImplemented(); | ||||||
|  |     } | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   auto serviceName_iter = | ||||||
|  |       arguments->find(flutter::EncodableValue("ManagerName")); | ||||||
|  |   if (serviceName_iter != arguments->end() && | ||||||
|  |       !serviceName_iter->second.IsNull()) { | ||||||
|  |     std::string serviceName = std::get<std::string>(serviceName_iter->second); | ||||||
|  |     auto* service = getService(serviceName); | ||||||
|  |     if (service) { | ||||||
|  |       std::shared_ptr<MockMethodResult> mockResult = | ||||||
|  |           std::make_shared<MockMethodResult>(serviceName, method, result); | ||||||
|  |       YXLOG_API(Info) << "mn: " << method << ", args: " | ||||||
|  |                       << Convert::getInstance()->getStringFormMapForLog( | ||||||
|  |                              arguments) | ||||||
|  |                       << YXLOGEnd; | ||||||
|  |       service->onMethodCalled(method, arguments, mockResult); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     YXLOG_API(Warn) << "sn not found, mn: " << method << YXLOGEnd; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (result) { | ||||||
|  |     result->NotImplemented(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NimCore::invokeMethod(const std::string& method, | ||||||
|  |                            const flutter::EncodableMap& arguments) { | ||||||
|  |   if (m_channel) { | ||||||
|  |     m_channel->InvokeMethod( | ||||||
|  |         method, std::make_unique<flutter::EncodableValue>(arguments)); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | class InterResult : public flutter::MethodResult<T> { | ||||||
|  |  protected: | ||||||
|  |   void SuccessInternal(const T* result) override { | ||||||
|  |     if (result != nullptr) { | ||||||
|  |       NimCore::getInstance()->invokeCallback(flutter::EncodableValue(*result)); | ||||||
|  |     } else { | ||||||
|  |       NimCore::getInstance()->invokeCallback(std::nullopt); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Implementation of the public interface, to be provided by subclasses.
 | ||||||
|  |   void ErrorInternal(const std::string& error_code, | ||||||
|  |                      const std::string& error_message, | ||||||
|  |                      const T* error_details) override {} | ||||||
|  | 
 | ||||||
|  |   // Implementation of the public interface, to be provided by subclasses.
 | ||||||
|  |   void NotImplementedInternal() override {} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void NimCore::invokeMethod(const std::string& eventName, | ||||||
|  |                            const flutter::EncodableMap& arguments, | ||||||
|  |                            const InvokeMehtodCallback& callback) { | ||||||
|  |   invokeCallback = callback; | ||||||
|  |   if (m_channel) { | ||||||
|  |     m_channel->InvokeMethod( | ||||||
|  |         eventName, std::make_unique<flutter::EncodableValue>(arguments), | ||||||
|  |         std::make_unique<InterResult<flutter::EncodableValue>>()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NimCore::setMethodChannel(NimMethodChannel* channel) { | ||||||
|  |   m_channel = channel; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | NimCore::NimMethodChannel* NimCore::getMethodChannel() { return m_channel; } | ||||||
|  | 
 | ||||||
|  | void NimCore::setAppkey(const std::string& appkey) { m_appKey = appkey; } | ||||||
|  | 
 | ||||||
|  | std::string NimCore::getAppkey() const { return m_appKey; } | ||||||
|  | 
 | ||||||
|  | void NimCore::setLogDir(const std::string& logDir) { m_logDir = logDir; } | ||||||
|  | 
 | ||||||
|  | std::string NimCore::getLogDir() const { return m_logDir; } | ||||||
|  | 
 | ||||||
|  | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | MockMethodResult::MockMethodResult( | ||||||
|  |     const std::string serviceName, const std::string methodName, | ||||||
|  |     std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) | ||||||
|  |     : m_serviceName(serviceName), | ||||||
|  |       m_methodName(methodName), | ||||||
|  |       m_result(std::move(result)) {} | ||||||
|  | 
 | ||||||
|  | void MockMethodResult::ErrorInternal(const std::string& error_code, | ||||||
|  |                                      const std::string& error_message, | ||||||
|  |                                      const flutter::EncodableValue* details) { | ||||||
|  |   YXLOG_API(Warn) << "cb error, sn: " << m_serviceName | ||||||
|  |                   << ", mn: " << m_methodName << ", error_code: " << error_code | ||||||
|  |                   << ", error_msg: " << error_message | ||||||
|  |                   << ", details: " << getStringFormEncodableValue(details) | ||||||
|  |                   << YXLOGEnd; | ||||||
|  |   if (m_result) m_result->Success(*details); | ||||||
|  |   // //失败情况下, 也调用success接口,避免dart层抛出异常
 | ||||||
|  |   // m_result->Error(error_code, error_message, *details);
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void MockMethodResult::NotImplementedInternal() { | ||||||
|  |   YXLOG_API(Warn) << "cb notImplemented, sn: " << m_serviceName | ||||||
|  |                   << ", mn: " << m_methodName << YXLOGEnd; | ||||||
|  |   if (m_result) m_result->NotImplemented(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void MockMethodResult::SuccessInternal(const flutter::EncodableValue* result) { | ||||||
|  |   std::string strLog; | ||||||
|  |   strLog.append("cb succ, sn: ") | ||||||
|  |       .append(m_serviceName) | ||||||
|  |       .append(", mn: ") | ||||||
|  |       .append(m_methodName) | ||||||
|  |       .append(", result: ") | ||||||
|  |       .append(getStringFormEncodableValue(result)); | ||||||
|  |   std::list<std::string> logList; | ||||||
|  |   Convert::getInstance()->getLogList(strLog, logList); | ||||||
|  |   for (auto& it : logList) { | ||||||
|  |     YXLOG_API(Info) << it << YXLOGEnd; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (m_result) m_result->Success(*result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::string MockMethodResult::getStringFormEncodableValue( | ||||||
|  |     const flutter::EncodableValue* value) const { | ||||||
|  |   if (!value) { | ||||||
|  |     return ""; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   std::string result; | ||||||
|  |   if (auto it = std::get_if<bool>(value); it) { | ||||||
|  |     result = *it ? "true" : "false"; | ||||||
|  |   } else if (auto it1 = std::get_if<int32_t>(value); it1) { | ||||||
|  |     result = std::to_string(*it1); | ||||||
|  |   } else if (auto it2 = std::get_if<int64_t>(value); it2) { | ||||||
|  |     result = std::to_string(*it2); | ||||||
|  |   } else if (auto it3 = std::get_if<double>(value); it3) { | ||||||
|  |     result = std::to_string(*it3); | ||||||
|  |   } else if (auto it4 = std::get_if<std::string>(value); it4) { | ||||||
|  |     result = *it4; | ||||||
|  |   } else if (auto it5 = std::get_if<std::vector<uint8_t>>(value); it5) { | ||||||
|  |     result.append("["); | ||||||
|  |     bool bFirst = true; | ||||||
|  |     for (auto& it5Tmp : *it5) { | ||||||
|  |       if (!bFirst) { | ||||||
|  |         result.append(","); | ||||||
|  |       } | ||||||
|  |       result.append(std::to_string(it5Tmp)); | ||||||
|  |       bFirst = false; | ||||||
|  |     } | ||||||
|  |     result.append("]"); | ||||||
|  |   } else if (auto it6 = std::get_if<std::vector<int32_t>>(value); it6) { | ||||||
|  |     result.append("["); | ||||||
|  |     bool bFirst = true; | ||||||
|  |     for (auto& it6Tmp : *it6) { | ||||||
|  |       if (!bFirst) { | ||||||
|  |         result.append(","); | ||||||
|  |       } | ||||||
|  |       result.append(std::to_string(it6Tmp)); | ||||||
|  |       bFirst = false; | ||||||
|  |     } | ||||||
|  |     result.append("]"); | ||||||
|  |   } else if (auto it7 = std::get_if<std::vector<int64_t>>(value); it7) { | ||||||
|  |     result.append("["); | ||||||
|  |     bool bFirst = true; | ||||||
|  |     for (auto& it7Tmp : *it7) { | ||||||
|  |       if (!bFirst) { | ||||||
|  |         result.append(","); | ||||||
|  |       } | ||||||
|  |       result.append(std::to_string(it7Tmp)); | ||||||
|  |       bFirst = false; | ||||||
|  |     } | ||||||
|  |     result.append("]"); | ||||||
|  |   } else if (auto it8 = std::get_if<std::vector<double>>(value); it8) { | ||||||
|  |     result.append("["); | ||||||
|  |     bool bFirst = true; | ||||||
|  |     for (auto& it8Tmp : *it8) { | ||||||
|  |       if (!bFirst) { | ||||||
|  |         result.append(","); | ||||||
|  |       } | ||||||
|  |       result.append(std::to_string(it8Tmp)); | ||||||
|  |       bFirst = false; | ||||||
|  |     } | ||||||
|  |     result.append("]"); | ||||||
|  |   } else if (auto it9 = std::get_if<EncodableList>(value); it9) { | ||||||
|  |     result = Convert::getInstance()->getStringFormListForLog(it9); | ||||||
|  |   } else if (auto it10 = std::get_if<EncodableMap>(value); it10) { | ||||||
|  |     result = Convert::getInstance()->getStringFormMapForLog(it10); | ||||||
|  |   } else { | ||||||
|  |     // wjzh
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return result; | ||||||
|  | } | ||||||
							
								
								
									
										105
									
								
								windows/src/NimCore.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								windows/src/NimCore.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef NIMCORE_H | ||||||
|  | #define NIMCORE_H | ||||||
|  | 
 | ||||||
|  | #include <flutter/encodable_value.h> | ||||||
|  | #include <flutter/method_channel.h> | ||||||
|  | #include <flutter/plugin_registrar_windows.h> | ||||||
|  | #include <flutter/standard_method_codec.h> | ||||||
|  | 
 | ||||||
|  | class FLTService; | ||||||
|  | 
 | ||||||
|  | class FLTAuthService; | ||||||
|  | 
 | ||||||
|  | class FLTMessageService; | ||||||
|  | 
 | ||||||
|  | class NimCore { | ||||||
|  | public: | ||||||
|  |     using NimMethodChannel = flutter::MethodChannel<flutter::EncodableValue>; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     SINGLETONG(NimCore) | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     NimCore(); | ||||||
|  | 
 | ||||||
|  |     ~NimCore(); | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     using InvokeMehtodCallback = | ||||||
|  |             std::function<void(const std::optional <flutter::EncodableValue> &)>; | ||||||
|  | 
 | ||||||
|  |     InvokeMehtodCallback invokeCallback; | ||||||
|  | 
 | ||||||
|  |     void regService(); | ||||||
|  | 
 | ||||||
|  |     void cleanService(); | ||||||
|  | 
 | ||||||
|  |     void addService(FLTService *service); | ||||||
|  | 
 | ||||||
|  |     //  FLTAuthService* getFLTAuthService() const;
 | ||||||
|  |     //  FLTMessageService* getFLTMessageService() const;
 | ||||||
|  |     FLTService *getService(const std::string &serviceName) const; | ||||||
|  | 
 | ||||||
|  |     void onMethodCall( | ||||||
|  |             const std::string &method, const flutter::EncodableMap *arguments, | ||||||
|  |             std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |     void invokeMethod(const std::string &method, | ||||||
|  |                       const flutter::EncodableMap &arguments); | ||||||
|  | 
 | ||||||
|  |     void invokeMethod(const std::string &eventName, | ||||||
|  |                       const flutter::EncodableMap &arguments, | ||||||
|  |                       const InvokeMehtodCallback &callback); | ||||||
|  | 
 | ||||||
|  |     void setMethodChannel(NimMethodChannel *channel); | ||||||
|  | 
 | ||||||
|  |     NimMethodChannel *getMethodChannel(); | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     void setAppkey(const std::string &appkey); | ||||||
|  | 
 | ||||||
|  |     std::string getAppkey() const; | ||||||
|  | 
 | ||||||
|  |     void setLogDir(const std::string &logDir); | ||||||
|  | 
 | ||||||
|  |     std::string getLogDir() const; | ||||||
|  | 
 | ||||||
|  |     std::string getAccountId() const; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::unordered_map<std::string, FLTService *> m_services; | ||||||
|  |     NimMethodChannel *m_channel = nullptr; | ||||||
|  |     std::string m_appKey = ""; | ||||||
|  |     std::string m_logDir; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | class MockMethodResult : public flutter::MethodResult<> { | ||||||
|  | public: | ||||||
|  |     MockMethodResult( | ||||||
|  |             const std::string serviceName, const std::string methodName, | ||||||
|  |             std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |     virtual void ErrorInternal(const std::string &error_code, | ||||||
|  |                                const std::string &error_message, | ||||||
|  |                                const flutter::EncodableValue *details) override; | ||||||
|  | 
 | ||||||
|  |     virtual void NotImplementedInternal() override; | ||||||
|  | 
 | ||||||
|  |     virtual void SuccessInternal(const flutter::EncodableValue *result) override; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::string getStringFormEncodableValue( | ||||||
|  |             const flutter::EncodableValue *value) const; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::string m_serviceName; | ||||||
|  |     std::string m_methodName; | ||||||
|  |     std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> m_result; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // NIMCORE
 | ||||||
							
								
								
									
										65
									
								
								windows/src/common/FLTService.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								windows/src/common/FLTService.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #include "FLTService.h" | ||||||
|  | 
 | ||||||
|  | #include "../FLTConvert.h" | ||||||
|  | 
 | ||||||
|  | std::string FLTService::getServiceName() const { return m_serviceName; } | ||||||
|  | 
 | ||||||
|  | void notifyEvent(const std::string& eventName, | ||||||
|  |                              flutter::EncodableMap& arguments) { | ||||||
|  |   arguments.insert(std::make_pair(flutter::EncodableValue("serviceName"), | ||||||
|  |                                   flutter::EncodableValue(""))); | ||||||
|  |   std::string strLog; | ||||||
|  |   strLog.append("en: ") | ||||||
|  |       .append(eventName) | ||||||
|  |       .append(", args: ") | ||||||
|  |       .append(Convert::getInstance()->getStringFormMapForLog(&arguments)); | ||||||
|  |   std::list<std::string> logList; | ||||||
|  |   Convert::getInstance()->getLogList(strLog, logList); | ||||||
|  |   for (auto& it : logList) { | ||||||
|  |     YXLOG_API(Info) << it << YXLOGEnd; | ||||||
|  |   } | ||||||
|  |   NimCore::getInstance()->invokeMethod(eventName, arguments); | ||||||
|  |   YXLOG_API(Info) << "notifyEvent invoke completation." << YXLOGEnd; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //void FLTService::notifyEvent(const std::string& eventName,
 | ||||||
|  | //                             flutter::EncodableMap& arguments,
 | ||||||
|  | //                             const NimCore::InvokeMehtodCallback& callback) {
 | ||||||
|  | //  arguments.insert(std::make_pair(flutter::EncodableValue("serviceName"),
 | ||||||
|  | //                                  flutter::EncodableValue(m_serviceName)));
 | ||||||
|  | //  std::string strLog;
 | ||||||
|  | //  strLog.append("en: ")
 | ||||||
|  | //      .append(eventName)
 | ||||||
|  | //      .append(", args: ")
 | ||||||
|  | //      .append(Convert::getInstance()->getStringFormMapForLog(&arguments));
 | ||||||
|  | //  std::list<std::string> logList;
 | ||||||
|  | //  Convert::getInstance()->getLogList(strLog, logList);
 | ||||||
|  | //  for (auto& it : logList) {
 | ||||||
|  | //    YXLOG_API(Info) << it << YXLOGEnd;
 | ||||||
|  | //  }
 | ||||||
|  | //  NimCore::getInstance()->invokeMethod(eventName, arguments, callback);
 | ||||||
|  | //  YXLOG_API(Info) << "notifyEvent invoke completation." << YXLOGEnd;
 | ||||||
|  | //}
 | ||||||
|  | 
 | ||||||
|  | void FLTService::notifyEventEx(const std::string& serviceName, | ||||||
|  |                                const std::string& eventName, | ||||||
|  |                                flutter::EncodableMap& arguments) { | ||||||
|  |   arguments.insert(std::make_pair(flutter::EncodableValue("serviceName"), | ||||||
|  |                                   flutter::EncodableValue(serviceName))); | ||||||
|  |   std::string strLog; | ||||||
|  |   strLog.append("en: ") | ||||||
|  |       .append(eventName) | ||||||
|  |       .append(", args: ") | ||||||
|  |       .append(Convert::getInstance()->getStringFormMapForLog(&arguments)); | ||||||
|  |   std::list<std::string> logList; | ||||||
|  |   Convert::getInstance()->getLogList(strLog, logList); | ||||||
|  |   for (auto& it : logList) { | ||||||
|  |     YXLOG_API(Info) << it << YXLOGEnd; | ||||||
|  |   } | ||||||
|  |   NimCore::getInstance()->invokeMethod(eventName, arguments); | ||||||
|  |   YXLOG_API(Info) << "notifyEventEx invoke completation." << YXLOGEnd; | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								windows/src/common/FLTService.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								windows/src/common/FLTService.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef FLTSERVICE_H | ||||||
|  | #define FLTSERVICE_H | ||||||
|  | 
 | ||||||
|  | #include "../NimCore.h" | ||||||
|  | #include "NimResult.h" | ||||||
|  | #include "flutter/method_result.h" | ||||||
|  | 
 | ||||||
|  | #define DECLARE_FUN(fun)                           \ | ||||||
|  |   void fun(const flutter::EncodableMap* arguments, \ | ||||||
|  |            FLTService::MethodResult result); | ||||||
|  | 
 | ||||||
|  | void notifyEvent(const std::string& eventName, | ||||||
|  |     flutter::EncodableMap& arguments); | ||||||
|  | 
 | ||||||
|  | class FLTService { | ||||||
|  |  public: | ||||||
|  |   using MethodResult = | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>; | ||||||
|  | 
 | ||||||
|  |  public: | ||||||
|  |   virtual void onMethodCalled( | ||||||
|  |       const std::string& method, const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> | ||||||
|  |           result) = 0; | ||||||
|  | 
 | ||||||
|  |   std::string getServiceName() const; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   //void notifyEvent(const std::string& eventName,
 | ||||||
|  |   //                 flutter::EncodableMap& arguments,
 | ||||||
|  |   //                 const NimCore::InvokeMehtodCallback& callback);
 | ||||||
|  | 
 | ||||||
|  |   static void notifyEventEx(const std::string& serviceName, | ||||||
|  |                             const std::string& eventName, | ||||||
|  |                             flutter::EncodableMap& arguments); | ||||||
|  | 
 | ||||||
|  |  protected: | ||||||
|  |   std::string m_serviceName; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // FLTSERVICE_H
 | ||||||
							
								
								
									
										88
									
								
								windows/src/common/NimResult.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								windows/src/common/NimResult.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #include "NimResult.h" | ||||||
|  | 
 | ||||||
|  | using namespace flutter; | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getErrorResult(int code, const std::string& msg) { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(code))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(msg))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), EncodableValue())); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getErrorResult(int code, const std::string& msg, | ||||||
|  |                                          const EncodableMap& data) { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(code))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(msg))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), EncodableValue(data))); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult() { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(""))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), EncodableValue())); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(bool data) { | ||||||
|  |   return getSuccessResult(EncodableValue(data)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(int32_t data) { | ||||||
|  |   return getSuccessResult(EncodableValue(data)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(int64_t data) { | ||||||
|  |   return getSuccessResult(EncodableValue(data)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(const std::string& data) { | ||||||
|  |   return getSuccessResult(EncodableValue(data)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(const EncodableValue& data) { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(""))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), data)); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(const EncodableMap& data) { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(""))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), data)); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(const EncodableList& data) { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(""))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), data)); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EncodableValue NimResult::getSuccessResult(const std::string& msg, | ||||||
|  |                                            const EncodableMap& data) { | ||||||
|  |   EncodableMap result; | ||||||
|  |   result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0))); | ||||||
|  |   result.insert( | ||||||
|  |       std::make_pair(EncodableValue("errorDetails"), EncodableValue(msg))); | ||||||
|  |   result.insert(std::make_pair(EncodableValue("data"), EncodableValue(data))); | ||||||
|  |   return EncodableValue(result); | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								windows/src/common/NimResult.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								windows/src/common/NimResult.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef NIMRESULT_H | ||||||
|  | #define NIMRESULT_H | ||||||
|  | 
 | ||||||
|  | #include "flutter/encodable_value.h" | ||||||
|  | 
 | ||||||
|  | using namespace flutter; | ||||||
|  | 
 | ||||||
|  | class NimResult { | ||||||
|  |  public: | ||||||
|  |   static EncodableValue getErrorResult(int code, const std::string& msg); | ||||||
|  |   static EncodableValue getErrorResult(int code, const std::string& msg, | ||||||
|  |                                        const flutter::EncodableMap& data); | ||||||
|  | 
 | ||||||
|  |   static EncodableValue getSuccessResult(); | ||||||
|  |   static EncodableValue getSuccessResult(bool data); | ||||||
|  |   static EncodableValue getSuccessResult(int32_t data); | ||||||
|  |   static EncodableValue getSuccessResult(int64_t data); | ||||||
|  |   static EncodableValue getSuccessResult(const std::string& data); | ||||||
|  |   static EncodableValue getSuccessResult(const flutter::EncodableValue& data); | ||||||
|  |   static EncodableValue getSuccessResult(const flutter::EncodableMap& data); | ||||||
|  |   static EncodableValue getSuccessResult(const flutter::EncodableList& data); | ||||||
|  |   static EncodableValue getSuccessResult(const std::string& msg, | ||||||
|  |                                          const flutter::EncodableMap& data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif  // NIMRESULT_H
 | ||||||
							
								
								
									
										71
									
								
								windows/src/common/ZegoDataUtils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								windows/src/common/ZegoDataUtils.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | #include "ZegoDataUtils.h" | ||||||
|  | 
 | ||||||
|  | bool zego_value_is_null(flutter::EncodableValue value) { return value.IsNull(); } | ||||||
|  | 
 | ||||||
|  | int32_t zego_value_get_int(flutter::EncodableValue value) { | ||||||
|  |     // dart 没有 int32_t int64_t 区分,这里处理了 int32 最高位为 1(负数)的 case
 | ||||||
|  |     return (int32_t)zego_value_get_long(value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int64_t zego_value_get_long(flutter::EncodableValue value) { return value.LongValue(); } | ||||||
|  | 
 | ||||||
|  | bool zego_value_get_bool(flutter::EncodableValue value) { return std::get<bool>(value); } | ||||||
|  | 
 | ||||||
|  | double zego_value_get_double(flutter::EncodableValue value) { return std::get<double>(value); } | ||||||
|  | 
 | ||||||
|  | std::string zego_value_get_string(flutter::EncodableValue value) { | ||||||
|  |     return std::get<std::string>(value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<float> zego_value_get_vector_float(flutter::EncodableValue value) { | ||||||
|  |     return std::get<std::vector<float>>(value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::vector<uint8_t> zego_value_get_vector_uint8(flutter::EncodableValue value) { | ||||||
|  |     return std::get<std::vector<uint8_t>>(value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ZFMap zego_value_get_map(flutter::EncodableValue value) { return std::get<ZFMap>(value); } | ||||||
|  | 
 | ||||||
|  | ZFArray zego_value_get_list(flutter::EncodableValue value) { return std::get<ZFArray>(value); } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // 将 EncodableValue 转换为 nlohmann::json
 | ||||||
|  | nlohmann::json EncodableValueToJson(const flutter::EncodableValue& value) { | ||||||
|  |     if (std::holds_alternative<bool>(value)) { | ||||||
|  |         return std::get<bool>(value); | ||||||
|  |     } else if (std::holds_alternative<int32_t>(value)) { | ||||||
|  |         return std::get<int32_t>(value); | ||||||
|  |     } else if (std::holds_alternative<int64_t>(value)) { | ||||||
|  |         return std::get<int64_t>(value); | ||||||
|  |     } else if (std::holds_alternative<double>(value)) { | ||||||
|  |         return std::get<double>(value); | ||||||
|  |     } else if (std::holds_alternative<std::string>(value)) { | ||||||
|  |         return std::get<std::string>(value); | ||||||
|  |     } else if (std::holds_alternative<flutter::EncodableList>(value)) { | ||||||
|  |         nlohmann::json json_array = nlohmann::json::array(); | ||||||
|  |         for (const auto& item : std::get<flutter::EncodableList>(value)) { | ||||||
|  |             json_array.push_back(EncodableValueToJson(item)); | ||||||
|  |         } | ||||||
|  |         return json_array; | ||||||
|  |     } else if (std::holds_alternative<flutter::EncodableMap>(value)) { | ||||||
|  |         nlohmann::json json_object = nlohmann::json::object(); | ||||||
|  |         for (const auto& pair : std::get<flutter::EncodableMap>(value)) { | ||||||
|  |             std::string key = std::get<std::string>(pair.first); // 假设键是字符串
 | ||||||
|  |             json_object[key] = EncodableValueToJson(pair.second); | ||||||
|  |         } | ||||||
|  |         return json_object; | ||||||
|  |     } | ||||||
|  |     return nullptr; // 处理空值或不支持的类型
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 将 EncodableMap 转换为 JSON 字符串
 | ||||||
|  | std::string map_2_json(const flutter::EncodableMap& map) { | ||||||
|  |     nlohmann::json json_object = nlohmann::json::object(); | ||||||
|  |     for (const auto& pair : map) { | ||||||
|  |         std::string key = std::get<std::string>(pair.first); // 假设键是字符串
 | ||||||
|  |         json_object[key] = EncodableValueToJson(pair.second); | ||||||
|  |     } | ||||||
|  | 	auto json_string = json_object.dump(); // 序列化为 JSON 字符串
 | ||||||
|  |     return json_string; // 序列化为 JSON 字符串
 | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								windows/src/common/ZegoDataUtils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								windows/src/common/ZegoDataUtils.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <flutter/encodable_value.h> | ||||||
|  | #include <flutter/event_channel.h> | ||||||
|  | #include <memory> | ||||||
|  | #include "json.hpp" | ||||||
|  | 
 | ||||||
|  | #define ZFValue(varName) flutter::EncodableValue(varName) | ||||||
|  | #define ZFMap flutter::EncodableMap | ||||||
|  | #define ZFArray flutter::EncodableList | ||||||
|  | 
 | ||||||
|  | #define ZFArgument flutter::EncodableMap & | ||||||
|  | #define ZFResult std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> | ||||||
|  | #define ZFEventSink std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> | ||||||
|  | #define ZFMoveResult(result) std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result)) | ||||||
|  | 
 | ||||||
|  | #define ZFPluginRegistrar flutter::PluginRegistrarWindows | ||||||
|  | #define ZFBinaryMessenger flutter::BinaryMessenger | ||||||
|  | #define ZFTextureRegistrar flutter::TextureRegistrar | ||||||
|  | 
 | ||||||
|  | bool zego_value_is_null(flutter::EncodableValue value); | ||||||
|  | 
 | ||||||
|  | int32_t zego_value_get_int(flutter::EncodableValue value); | ||||||
|  | int64_t zego_value_get_long(flutter::EncodableValue value); | ||||||
|  | bool zego_value_get_bool(flutter::EncodableValue value); | ||||||
|  | double zego_value_get_double(flutter::EncodableValue value); | ||||||
|  | std::string zego_value_get_string(flutter::EncodableValue value); | ||||||
|  | 
 | ||||||
|  | std::vector<float> zego_value_get_vector_float(flutter::EncodableValue value); | ||||||
|  | std::vector<uint8_t> zego_value_get_vector_uint8(flutter::EncodableValue value); | ||||||
|  | ZFMap zego_value_get_map(flutter::EncodableValue value); | ||||||
|  | ZFArray zego_value_get_list(flutter::EncodableValue value); | ||||||
|  | std::string map_2_json(const flutter::EncodableMap& map); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										25526
									
								
								windows/src/common/json.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25526
									
								
								windows/src/common/json.hpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										70
									
								
								windows/src/common/services/ConstDefine.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								windows/src/common/services/ConstDefine.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | #ifndef CONST_DEFINE_H | ||||||
|  | #define CONST_DEFINE_H | ||||||
|  | 
 | ||||||
|  | enum class ConstDefine { | ||||||
|  |     CONNECTING = 0, | ||||||
|  |     CONNECT_SUCCESS, | ||||||
|  |     CONNECT_FAILED, | ||||||
|  |     KICKED_OFFLINE, | ||||||
|  |     USER_TOKEN_EXPIRED, | ||||||
|  |     JOINED_GROUP_ADDED, | ||||||
|  |     JOINED_GROUP_DELETED, | ||||||
|  |     GROUP_MEMBER_ADDED, | ||||||
|  |     GROUP_MEMBER_DELETED, | ||||||
|  |     GROUP_APPLICATION_ADDED, | ||||||
|  |     GROUP_APPLICATION_DELETED, | ||||||
|  |     GROUP_INFO_CHANGED, | ||||||
|  |     GROUP_DISMISSED, | ||||||
|  |     GROUP_MEMBER_INFO_CHANGED, | ||||||
|  |     GROUP_APPLICATION_ACCEPTED, | ||||||
|  |     GROUP_APPLICATION_REJECTED, | ||||||
|  |     FRIEND_APPLICATION_ADDED, | ||||||
|  |     FRIEND_APPLICATION_DELETED, | ||||||
|  |     FRIEND_APPLICATION_ACCEPTED, | ||||||
|  |     FRIEND_APPLICATION_REJECTED, | ||||||
|  |     FRIEND_ADDED, | ||||||
|  |     FRIEND_DELETED, | ||||||
|  |     FRIEND_INFO_CHANGED, | ||||||
|  |     BLACK_ADDED, | ||||||
|  |     BLACK_DELETED, | ||||||
|  |     SYNC_SERVER_START, | ||||||
|  |     SYNC_SERVER_FINISH, | ||||||
|  |     SYNC_SERVER_PROGRESS, | ||||||
|  |     SYNC_SERVER_FAILED, | ||||||
|  |     NEW_CONVERSATION, | ||||||
|  |     CONVERSATION_CHANGED, | ||||||
|  |     TOTAL_UNREAD_MESSAGE_COUNT_CHANGED, | ||||||
|  |     RECV_NEW_MESSAGE, | ||||||
|  |     RECV_C2C_READ_RECEIPT, | ||||||
|  |     RECV_GROUP_READ_RECEIPT, | ||||||
|  |     NEW_RECV_MESSAGE_REVOKED, | ||||||
|  |     RECV_MESSAGE_EXTENSIONS_CHANGED, | ||||||
|  |     RECV_MESSAGE_EXTENSIONS_DELETED, | ||||||
|  |     RECV_MESSAGE_EXTENSIONS_ADDED, | ||||||
|  |     RECV_OFFLINE_NEW_MESSAGE, | ||||||
|  |     MSG_DELETED, | ||||||
|  |     RECV_NEW_MESSAGES, | ||||||
|  |     RECV_OFFLINE_NEW_MESSAGES, | ||||||
|  |     SELF_INFO_UPDATED, | ||||||
|  |     USER_STATUS_CHANGED, | ||||||
|  |     RECV_CUSTOM_BUSINESS_MESSAGE, | ||||||
|  |     MESSAGE_KV_INFO_CHANGED, | ||||||
|  |     OPEN, | ||||||
|  |     PART_SIZE, | ||||||
|  |     HASH_PART_PROGRESS, | ||||||
|  |     HASH_PART_COMPLETE, | ||||||
|  |     UPLOAD_ID, | ||||||
|  |     UPLOAD_PART_COMPLETE, | ||||||
|  |     UPLOAD_COMPLETE, | ||||||
|  |     COMPLETE, | ||||||
|  |     CONVERSATION_USER_INPUT_STATUS_CHANGED, | ||||||
|  |     RECV_ONLINE_ONLY_MESSAGE, | ||||||
|  |     RECV_MESSAGE_EDIT, | ||||||
|  |     USER_TOKEN_INVALID, | ||||||
|  |     ON_PROGRESS | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif // EVENT_TYPES_H
 | ||||||
							
								
								
									
										339
									
								
								windows/src/common/services/IMManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								windows/src/common/services/IMManager.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,339 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #include "IMManager.h" | ||||||
|  | 
 | ||||||
|  | #if defined(_WIN32) | ||||||
|  | #include <windows.h> | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #include "../NimResult.h" | ||||||
|  | #include <libopenimsdk.h> | ||||||
|  | #include "../ZegoDataUtils.h" | ||||||
|  | #include "ConstDefine.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | IMManagerService::IMManagerService() { | ||||||
|  |     m_serviceName = "imManager"; | ||||||
|  | 
 | ||||||
|  |     _im_manager_listener.onInitSdk = [](int state, char *msg) { | ||||||
|  |         // friend added, handle friendInfo
 | ||||||
|  | 
 | ||||||
|  |         flutter::EncodableMap arguments; | ||||||
|  |         switch (ConstDefine(state)) { | ||||||
|  |             case ConstDefine::CONNECTING: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onConnecting")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::CONNECT_SUCCESS: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onConnectSuccess")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::CONNECT_FAILED: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onConnectFailed")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::KICKED_OFFLINE: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onKickedOffline")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::USER_TOKEN_EXPIRED: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onUserTokenExpired")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::USER_TOKEN_INVALID: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onUserTokenExpired")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |         notifyEvent("connectListener", arguments); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     _im_manager_listener.baseCallBack = [](char *opid, int errCode, char *errMsg, char *msg) { | ||||||
|  |         CallBaseCallBack(msg, errCode, errMsg, msg); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     _im_manager_listener.uploadCallback = [](int state, char *msg) { | ||||||
|  |         // upload progress
 | ||||||
|  | 
 | ||||||
|  |         flutter::EncodableMap arguments; | ||||||
|  |         switch (ConstDefine(state)) { | ||||||
|  |             case ConstDefine::OPEN: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onConnecting")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::PART_SIZE: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onConnectSuccess")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::HASH_PART_PROGRESS: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onConnectFailed")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::HASH_PART_COMPLETE: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onKickedOffline")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::UPLOAD_ID: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onUserTokenExpired")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::UPLOAD_PART_COMPLETE: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onUserTokenExpired")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::UPLOAD_COMPLETE: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onUserTokenExpired")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |             case ConstDefine::COMPLETE: | ||||||
|  |                 arguments.insert(std::make_pair("type", "onUserTokenExpired")); | ||||||
|  |                 arguments.insert(std::make_pair("data", *msg)); | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |         notifyEvent("uploadFileListener", arguments); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::onMethodCalled( | ||||||
|  |         const std::string &method, const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (method == "initSDK") { | ||||||
|  |         initializeSDK(arguments, result); | ||||||
|  |     } else if (method == "unInitSDK") { | ||||||
|  |         unInitSDK(arguments, result); | ||||||
|  |     } else if (method == "login") { | ||||||
|  |         login(arguments, result); | ||||||
|  |     } else if (method == "logout") { | ||||||
|  |         logout(arguments, result); | ||||||
|  |     } else if (method == "getLoginStatus") { | ||||||
|  |         getLoginStatus(arguments, result); | ||||||
|  |     } else if (method == "uploadFile") { | ||||||
|  |         uploadFile(arguments, result); | ||||||
|  |     } else if (method == "uploadLogs") { | ||||||
|  |         uploadLogs(arguments, result); | ||||||
|  |     } else if (method == "logs") { | ||||||
|  |         logs(arguments, result); | ||||||
|  |     } else if (method == "updateFcmToken") { | ||||||
|  |         updateFcmToken(arguments, result); | ||||||
|  |     } else if (method == "setAppBackgroundStatus") { | ||||||
|  |         setAppBackgroundStatus(arguments, result); | ||||||
|  |     } else if (method == "networkStatusChanged") { | ||||||
|  |         networkStatusChanged(arguments, result); | ||||||
|  | 
 | ||||||
|  |     } else { | ||||||
|  |         result->NotImplemented(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void IMManagerService::initializeSDK( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (arguments) { | ||||||
|  |         auto operationID = zego_value_get_string(arguments->at(ZFValue("operationID"))); | ||||||
|  |         char *operationID_cs = const_cast<char *>(operationID.c_str()); | ||||||
|  |         auto config = map_2_json(*arguments); | ||||||
|  |         char *config_cs = const_cast<char *>(config.c_str()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         auto error = init_sdk(_im_manager_listener.onInitSdk, | ||||||
|  |                               operationID_cs, | ||||||
|  |                               config_cs); | ||||||
|  |         if (error == 0) { | ||||||
|  |             // handle error
 | ||||||
|  |             std::string msg = "IM init failed"; | ||||||
|  |             result->Error("", "", | ||||||
|  |                           NimResult::getErrorResult(error, "")); | ||||||
|  |         } else { | ||||||
|  | 
 | ||||||
|  |             result->Success(EncodableValue(error == 0)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void IMManagerService::unInitSDK( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (arguments) { | ||||||
|  |         auto operationID = zego_value_get_string( | ||||||
|  |                 arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |         char *operationID_cs = const_cast<char *>(operationID.c_str()); | ||||||
|  | 
 | ||||||
|  |         un_init_sdk(operationID_cs); | ||||||
|  | 
 | ||||||
|  |     } else { | ||||||
|  |         result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::login( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (arguments) { | ||||||
|  |         auto operationID = zego_value_get_string( | ||||||
|  |                 arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |         auto userID = zego_value_get_string(arguments->at(flutter::EncodableValue("userID"))); | ||||||
|  |         auto token = zego_value_get_string(arguments->at(flutter::EncodableValue("token"))); | ||||||
|  |         char *operationID_cs = const_cast<char *>(operationID.c_str()); | ||||||
|  |         char *userID_cs = const_cast<char *>(userID.c_str()); | ||||||
|  |         char *token_cs = const_cast<char *>(token.c_str()); | ||||||
|  | 
 | ||||||
|  |         NewBaseCallBack(operationID, result); | ||||||
|  | 
 | ||||||
|  |         ::login(_im_manager_listener.baseCallBack, operationID_cs, userID_cs, token_cs); | ||||||
|  | 
 | ||||||
|  |     } else { | ||||||
|  |         result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::logout( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (arguments) { | ||||||
|  |         auto operationID = zego_value_get_string( | ||||||
|  |                 arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |         char *operationID_cs = const_cast<char *>(operationID.c_str()); | ||||||
|  |         NewBaseCallBack(operationID, result); | ||||||
|  |         ::logout(_im_manager_listener.baseCallBack, operationID_cs); | ||||||
|  | 
 | ||||||
|  |     } else { | ||||||
|  |         result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::getLoginStatus( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (arguments) { | ||||||
|  |         auto operationID = zego_value_get_string( | ||||||
|  |                 arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |         char *operationID_cs = const_cast<char *>(operationID.c_str()); | ||||||
|  | 
 | ||||||
|  |         int status = get_login_status(operationID_cs); | ||||||
|  |         flutter::EncodableMap statusMap; | ||||||
|  | 
 | ||||||
|  |         result->Success(flutter::EncodableValue(status)); | ||||||
|  |     } else { | ||||||
|  |         result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::uploadFile( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     //	if (arguments) {
 | ||||||
|  |     //		auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID")));
 | ||||||
|  |     //		auto id = zego_value_get_string(arguments->at(flutter::EncodableValue("id")));
 | ||||||
|  |     //		auto fileInfo = map_2_json(*arguments);
 | ||||||
|  |     //		char* operationID_cs = const_cast<char*>(operationID.c_str());
 | ||||||
|  |     //		char* fileInfo_cs = const_cast<char*>(fileInfo.c_str());
 | ||||||
|  |     //		uploadFileResult = result;
 | ||||||
|  |     //		upload_file(_im_manager_listener.onUploadFile, operationID_cs, fileInfo_cs, _im_manager_listener.uploadCallback);
 | ||||||
|  |     //	}
 | ||||||
|  |     //	else {
 | ||||||
|  |     //		result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
 | ||||||
|  |     //	}
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::uploadLogs( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  | //    if (arguments) {
 | ||||||
|  | //        auto operationID = zego_value_get_string(
 | ||||||
|  | //                arguments->at(flutter::EncodableValue("operationID")));
 | ||||||
|  | //        auto line = zego_value_get_int(arguments->at(flutter::EncodableValue("line")));
 | ||||||
|  | //        auto ex = zego_value_get_string(arguments->at(flutter::EncodableValue("ex")));
 | ||||||
|  | //        char *operationID_cs = const_cast<char *>(operationID.c_str());
 | ||||||
|  | //        char *ex_cs = const_cast<char *>(ex.c_str());
 | ||||||
|  | //
 | ||||||
|  | //        upload_logs(_im_manager_listener.onUploadLogs, operationID_cs, line, ex_cs);
 | ||||||
|  | //
 | ||||||
|  | //    } else {
 | ||||||
|  | //        result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
 | ||||||
|  | //    }
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::logs( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     //	if (arguments) {
 | ||||||
|  |     //		auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID")));
 | ||||||
|  |     //		auto logLevel = zego_value_get_int(arguments->at(flutter::EncodableValue("logLevel")));
 | ||||||
|  |     //		auto file = zego_value_get_string(arguments->at(flutter::EncodableValue("file")));
 | ||||||
|  |     //		auto line = zego_value_get_int(arguments->at(flutter::EncodableValue("line")));
 | ||||||
|  |     //		auto msgs = zego_value_get_string(arguments->at(flutter::EncodableValue("msgs")));
 | ||||||
|  |     //		auto err = zego_value_get_string(arguments->at(flutter::EncodableValue("err")));
 | ||||||
|  |     //		auto keyAndValue = zego_value_get_string(arguments->at(flutter::EncodableValue("keyAndValue")));
 | ||||||
|  |     //		char* operationID_cs = const_cast<char*>(operationID.c_str());
 | ||||||
|  |     //		char* file_cs = const_cast<char*>(file.c_str());
 | ||||||
|  |     //		char* msgs_cs = const_cast<char*>(msgs.c_str());
 | ||||||
|  |     //		char* err_cs = const_cast<char*>(err.c_str());
 | ||||||
|  |     //		char* keyAndValue_cs = const_cast<char*>(keyAndValue.c_str());
 | ||||||
|  |     //
 | ||||||
|  |     //		auto error = logs(_im_manager_listener.onLogs, operationID_cs, logLevel, file_cs, line, msgs_cs, err_cs, keyAndValue_cs);
 | ||||||
|  |     //		if (error != 0) {
 | ||||||
|  |     //			std::string msg = "Logging failed";
 | ||||||
|  |     //			result->Error("", "", NimResult::getErrorResult(error, msg));
 | ||||||
|  |     //		}
 | ||||||
|  |     //		else {
 | ||||||
|  |     //			result->Success(NimResult::getSuccessResult());
 | ||||||
|  |     //		}
 | ||||||
|  |     //	}
 | ||||||
|  |     //	else {
 | ||||||
|  |     //		result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
 | ||||||
|  |     //	}
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::updateFcmToken( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     if (arguments) { | ||||||
|  |         auto operationID = zego_value_get_string( | ||||||
|  |                 arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |         auto fcmToken = zego_value_get_string(arguments->at(flutter::EncodableValue("fcmToken"))); | ||||||
|  |         auto expireTime = zego_value_get_int(arguments->at(flutter::EncodableValue("expireTime"))); | ||||||
|  |         char *operationID_cs = const_cast<char *>(operationID.c_str()); | ||||||
|  |         char *fcmToken_cs = const_cast<char *>(fcmToken.c_str()); | ||||||
|  |         NewBaseCallBack(operationID, result); | ||||||
|  |         update_fcm_token(_im_manager_listener.baseCallBack, operationID_cs, fcmToken_cs, | ||||||
|  |                          expireTime); | ||||||
|  |     } else { | ||||||
|  |         result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::setAppBackgroundStatus( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     	if (arguments) { | ||||||
|  |     		auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |     		auto isBackground = zego_value_get_bool(arguments->at(flutter::EncodableValue("isBackground"))); | ||||||
|  |     		char* operationID_cs = const_cast<char*>(operationID.c_str()); | ||||||
|  |             NewBaseCallBack(operationID, result); | ||||||
|  |     		set_app_background_status(_im_manager_listener.baseCallBack, operationID_cs, isBackground); | ||||||
|  | 
 | ||||||
|  |     	} | ||||||
|  |     	else { | ||||||
|  |     		result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void IMManagerService::networkStatusChanged( | ||||||
|  |         const flutter::EncodableMap *arguments, | ||||||
|  |         std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     	if (arguments) { | ||||||
|  |     		auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID"))); | ||||||
|  |     		char* operationID_cs = const_cast<char*>(operationID.c_str()); | ||||||
|  |             NewBaseCallBack(operationID, result); | ||||||
|  |     		network_status_changed(_im_manager_listener.baseCallBack, operationID_cs); | ||||||
|  | 
 | ||||||
|  |     	} | ||||||
|  |     	else { | ||||||
|  |     		result->Error("INVALID_ARGUMENT", "Arguments cannot be null"); | ||||||
|  |     	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										75
									
								
								windows/src/common/services/IMManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								windows/src/common/services/IMManager.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef IMMANAGER_H | ||||||
|  | #define IMMANAGER_H | ||||||
|  | 
 | ||||||
|  | #include "../FLTService.h" | ||||||
|  | #include "Listen.h" | ||||||
|  | 
 | ||||||
|  | struct IMManagerServiceListener { | ||||||
|  |     CB_I_S onInitSdk; | ||||||
|  |     CB_S_I_S_S   baseCallBack; | ||||||
|  |     CB_I_S uploadCallback; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class IMManagerService : public FLTService { | ||||||
|  |  public: | ||||||
|  |     IMManagerService(); | ||||||
|  |   virtual void onMethodCalled( | ||||||
|  |       const std::string& method, const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) | ||||||
|  |       override; | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   void initializeSDK( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void unInitSDK( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void login( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void logout( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void getLoginStatus( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void uploadFile( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void uploadLogs( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void logs( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void updateFcmToken( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void setAppBackgroundStatus( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   void networkStatusChanged( | ||||||
|  |       const flutter::EncodableMap* arguments, | ||||||
|  |       std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | 
 | ||||||
|  |   IMManagerServiceListener _im_manager_listener; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif  // IMMANAGER_H
 | ||||||
							
								
								
									
										20
									
								
								windows/src/common/services/Listen.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								windows/src/common/services/Listen.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | #include "Listen.h" | ||||||
|  | #include <unordered_map> | ||||||
|  | 
 | ||||||
|  | std::unordered_map <std::string, std::unique_ptr<BaseCallBack>> g_baseCallBackMap; | ||||||
|  | std::mutex g_baseCallBackMapMutex; | ||||||
|  | 
 | ||||||
|  | void NewBaseCallBack(std::string opid, | ||||||
|  |                      std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  |     std::lock_guard <std::mutex> lock(g_baseCallBackMapMutex); | ||||||
|  |     g_baseCallBackMap[opid] = std::make_unique<BaseCallBack>(result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CallBaseCallBack(char *opid, int errCode, char *errMsg, char *msg) { | ||||||
|  |     std::lock_guard <std::mutex> lock(g_baseCallBackMapMutex); | ||||||
|  |     auto it = g_baseCallBackMap.find(std::string(opid)); | ||||||
|  |     if (it != g_baseCallBackMap.end()) { | ||||||
|  |         auto ctx = std::move(it->second);  //unique_ptr
 | ||||||
|  |         ctx->HandleCallback(opid, errCode, errMsg, msg); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								windows/src/common/services/Listen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								windows/src/common/services/Listen.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | #ifndef LISTEN_H | ||||||
|  | #define LISTEN_H | ||||||
|  | 
 | ||||||
|  | #include <libopenimsdk.h> | ||||||
|  | #include "flutter/encodable_value.h" | ||||||
|  | #include "flutter/method_result.h" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class BaseCallBack { | ||||||
|  | public: | ||||||
|  | 	BaseCallBack(std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) { | ||||||
|  | 		this->result = result; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result = nullptr; | ||||||
|  | 
 | ||||||
|  | 	void HandleCallback(char* opid, int errCode, char* errMsg, char* msg) { | ||||||
|  | 		if (result == nullptr) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (errCode == 0) { | ||||||
|  | 			result->Success(flutter::EncodableValue(std::string(msg))); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			result->Error(std::to_string(errCode), std::string(errMsg), flutter::EncodableValue(std::string(msg))); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 全局映射表
 | ||||||
|  | extern std::unordered_map<std::string, std::unique_ptr<BaseCallBack>> g_baseCallBackMap; | ||||||
|  | extern std::mutex g_baseCallBackMapMutex; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void NewBaseCallBack(std::string opid, std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result); | ||||||
|  | void CallBaseCallBack(char* opid, int errCode, char* errMsg, char* msg); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //todo 没想好怎么实现
 | ||||||
|  | class uploadFileCallBack { | ||||||
|  | public: | ||||||
|  |     uploadFileCallBack(std::string id) { | ||||||
|  |         this->id = id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::string id = ""; | ||||||
|  | 
 | ||||||
|  |     void HandleCallback(char* opid, int errCode, char* errMsg, char* msg) { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
							
								
								
									
										0
									
								
								windows/src/common/services/MessageManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								windows/src/common/services/MessageManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								windows/src/common/services/MessageManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								windows/src/common/services/MessageManager.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										311
									
								
								windows/src/common/services/wrapp_cpp_function.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								windows/src/common/services/wrapp_cpp_function.inc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,311 @@ | |||||||
|  | /* | ||||||
|  | Using C++ template functions and recursion to initialize a function pointer pool, | ||||||
|  | combined with lambda expressions, this implementation manages function pointers, | ||||||
|  | achieving acquisition and release of pointers.All wrappers are used to convert | ||||||
|  | and map C++ functions to C functions, and with the use of indexed locking, | ||||||
|  | a thread-safe function pointer pool is implemented.For example, the wrapping | ||||||
|  | functions essentially map C++ functions to C functions. When a C function callback is triggered, | ||||||
|  | the function pointer pool, initialized through template recursion, locates the corresponding C++ function and invokes it. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define MAX_NUM_OF_CB_S 10
 | ||||||
|  | #define MAX_NUM_OF_CB_I_S 10
 | ||||||
|  | #define MAX_NUM_OF_CB_S_I_S_S 10
 | ||||||
|  | #define MAX_NUM_OF_CB_S_I_S_S_I 10
 | ||||||
|  | #define SLEEP_TIME_FOR_GET_INDEX 100 //ms
 | ||||||
|  | 
 | ||||||
|  | // use recursive template to generate enough function pointer array
 | ||||||
|  | // and define c type function interface
 | ||||||
|  | // and define manager class to manage function pool
 | ||||||
|  | namespace { | ||||||
|  |   CB_S* _fps_cb_s=new CB_S[MAX_NUM_OF_CB_S]; | ||||||
|  |   CB_I_S* _fps_cb_i_s=new CB_I_S[MAX_NUM_OF_CB_I_S]; | ||||||
|  |   CB_S_I_S_S* _fps_cb_s_i_s_s=new CB_S_I_S_S[MAX_NUM_OF_CB_S_I_S_S]; | ||||||
|  |   CB_S_I_S_S_I* _fps_cb_s_i_s_s_i=new CB_S_I_S_S_I[MAX_NUM_OF_CB_S_I_S_S_I]; | ||||||
|  |   // c type func interface call cpp function
 | ||||||
|  |   std::function<void(const std::string&)>* _cpp_function_cb_s=new std::function<void(const std::string&)>[MAX_NUM_OF_CB_S]; | ||||||
|  |   std::function<void(int,const std::string&)>* _cpp_function_cb_i_s=new std::function<void(int,const std::string&)>[MAX_NUM_OF_CB_I_S]; | ||||||
|  |   std::function<void(const std::string&,int,const std::string&,const std::string&)>* _cpp_function_cb_s_i_s_s=new std::function<void(const std::string&,int,const std::string&,const std::string&)>[MAX_NUM_OF_CB_S_I_S_S]; | ||||||
|  |   std::function<void(const std::string&,int,const std::string&,const std::string&,int)>* _cpp_function_cb_s_i_s_s_i=new std::function<void(const std::string&,int,const std::string&,const std::string&,int)>[MAX_NUM_OF_CB_S_I_S_S_I]; | ||||||
|  | 
 | ||||||
|  |   template<int N> | ||||||
|  |   void _generate_cb_s(){ | ||||||
|  |     _fps_cb_s[N]=[](char* c_str){ | ||||||
|  |       _cpp_function_cb_s[N](std::string(c_str)); | ||||||
|  |     }; | ||||||
|  |     _generate_cb_s<N-1>(); | ||||||
|  |   } | ||||||
|  |   template<> | ||||||
|  |   void _generate_cb_s<0>(){ | ||||||
|  |     _fps_cb_s[0]=[](char* c_str){ | ||||||
|  |       _cpp_function_cb_s[0](std::string(c_str)); | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   template<int N> | ||||||
|  |   void _generate_cb_i_s(){ | ||||||
|  |     _fps_cb_i_s[N]=[](int code,char* c_str){ | ||||||
|  |       _cpp_function_cb_i_s[N](code,std::string(c_str)); | ||||||
|  |     }; | ||||||
|  |     _generate_cb_i_s<N-1>(); | ||||||
|  |   } | ||||||
|  |   template<> | ||||||
|  |   void _generate_cb_i_s<0>(){ | ||||||
|  |     _fps_cb_i_s[0]=[](int code,char* c_str){ | ||||||
|  |       _cpp_function_cb_i_s[0](code,std::string(c_str)); | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |   template<int N> | ||||||
|  |   void _generate_cb_s_i_s_s(){ | ||||||
|  |     _fps_cb_s_i_s_s[N]=[](char* operationID,int code,char* c_str,char* c_str2){ | ||||||
|  |       _cpp_function_cb_s_i_s_s[N](std::string(operationID),code,std::string(c_str),std::string(c_str2)); | ||||||
|  |     }; | ||||||
|  |     _generate_cb_s_i_s_s<N-1>(); | ||||||
|  |   } | ||||||
|  |   template<> | ||||||
|  |   void _generate_cb_s_i_s_s<0>(){ | ||||||
|  |     _fps_cb_s_i_s_s[0]=[](char* operationID,int code,char* c_str,char* c_str2){ | ||||||
|  |       _cpp_function_cb_s_i_s_s[0](std::string(operationID),code,std::string(c_str),std::string(c_str2)); | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |   template<int N> | ||||||
|  |   void _generate_cb_s_i_s_s_i(){ | ||||||
|  |     _fps_cb_s_i_s_s_i[N]=[](char* operationID,int code,char* c_str,char* c_str2,int c_int){ | ||||||
|  |       _cpp_function_cb_s_i_s_s_i[N](std::string(operationID),code,std::string(c_str),std::string(c_str2),c_int); | ||||||
|  |     }; | ||||||
|  |     _generate_cb_s_i_s_s_i<N-1>(); | ||||||
|  |   } | ||||||
|  |   template<> | ||||||
|  |   void _generate_cb_s_i_s_s_i<0>(){ | ||||||
|  |     _fps_cb_s_i_s_s_i[0]=[](char* operationID,int code,char* c_str,char* c_str2,int c_int){ | ||||||
|  |       _cpp_function_cb_s_i_s_s_i[0](std::string(operationID),code,std::string(c_str),std::string(c_str2),c_int); | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // init global function pointer array
 | ||||||
|  |   void init(){ | ||||||
|  |     _generate_cb_s<MAX_NUM_OF_CB_S-1>(); | ||||||
|  |     _generate_cb_i_s<MAX_NUM_OF_CB_I_S-1>(); | ||||||
|  |     _generate_cb_s_i_s_s<MAX_NUM_OF_CB_S_I_S_S-1>(); | ||||||
|  |     _generate_cb_s_i_s_s_i<MAX_NUM_OF_CB_S_I_S_S_I-1>(); | ||||||
|  |   } | ||||||
|  |   // define sigle instance class to manage function pool
 | ||||||
|  |   class FuncPoolManager{ | ||||||
|  |     private: | ||||||
|  |     // define a global bitmap, and support atomic operation, to manage cb_s pool
 | ||||||
|  |     std::bitset<MAX_NUM_OF_CB_S> _cb_s_bitmap; | ||||||
|  |     std::bitset<MAX_NUM_OF_CB_I_S> _cb_i_s_bitmap; | ||||||
|  |     std::bitset<MAX_NUM_OF_CB_S_I_S_S> _cb_s_i_s_s_bitmap; | ||||||
|  |     std::bitset<MAX_NUM_OF_CB_S_I_S_S_I> _cb_s_i_s_s_i_bitmap; | ||||||
|  |     std::mutex _cb_s_mutex; | ||||||
|  |     std::mutex _cb_i_s_mutex; | ||||||
|  |     std::mutex _cb_s_i_s_s_mutex; | ||||||
|  |     std::mutex _cb_s_i_s_s_i_mutex; | ||||||
|  |     FuncPoolManager(){ | ||||||
|  |       init(); | ||||||
|  |     } | ||||||
|  |     FuncPoolManager(const FuncPoolManager&){} | ||||||
|  |     public: | ||||||
|  |     static FuncPoolManager& get_instance(){ | ||||||
|  |       static FuncPoolManager instance; | ||||||
|  |       return instance; | ||||||
|  |     } | ||||||
|  |     // get a available cb_s function index
 | ||||||
|  |     int get_cb_s_index(){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_s_mutex); | ||||||
|  |       int index=-1; | ||||||
|  |       for(int i=0;i<_cb_s_bitmap.size();i++){ | ||||||
|  |         if(_cb_s_bitmap[i]==0){ | ||||||
|  |           _cb_s_bitmap[i]=1; | ||||||
|  |           index=i; | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return index; | ||||||
|  |     } | ||||||
|  |     // get a available cb_i_s function index
 | ||||||
|  |     int get_cb_i_s_index(){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_i_s_mutex); | ||||||
|  |       int index=-1; | ||||||
|  |       for(int i=0;i<_cb_i_s_bitmap.size();i++){ | ||||||
|  |         if(_cb_i_s_bitmap[i]==0){ | ||||||
|  |           _cb_i_s_bitmap[i]=1; | ||||||
|  |           index=i; | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return index; | ||||||
|  |     } | ||||||
|  |     // get a available cb_s_i_s_s function index
 | ||||||
|  |     int get_cb_s_i_s_s_index(){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_s_i_s_s_mutex); | ||||||
|  |       int index=-1; | ||||||
|  |       for(int i=0;i<_cb_s_i_s_s_bitmap.size();i++){ | ||||||
|  |         if(_cb_s_i_s_s_bitmap[i]==0){ | ||||||
|  |           _cb_s_i_s_s_bitmap[i]=1; | ||||||
|  |           index=i; | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return index; | ||||||
|  |     } | ||||||
|  |     // get a available cb_s_i_s_s_i function index
 | ||||||
|  |     int get_cb_s_i_s_s_i_index(){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_s_i_s_s_i_mutex); | ||||||
|  |       int index=-1; | ||||||
|  |       for(int i=0;i<_cb_s_i_s_s_i_bitmap.size();i++){ | ||||||
|  |         if(_cb_s_i_s_s_i_bitmap[i]==0){ | ||||||
|  |           _cb_s_i_s_s_i_bitmap[i]=1; | ||||||
|  |           index=i; | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return index; | ||||||
|  |     } | ||||||
|  |     // release a available cb_s function index
 | ||||||
|  |     int release_cb_s_index(int index){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_s_mutex); | ||||||
|  |       if(index<0||index>=_cb_s_bitmap.size()){ | ||||||
|  |         return -1; | ||||||
|  |       } | ||||||
|  |       _cpp_function_cb_s[index]=nullptr; | ||||||
|  |       _cb_s_bitmap[index]=0; | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     // release a available cb_i_s function index
 | ||||||
|  |     int release_cb_i_s_index(int index){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_i_s_mutex); | ||||||
|  |       if(index<0||index>=_cb_i_s_bitmap.size()){ | ||||||
|  |         return -1; | ||||||
|  |       } | ||||||
|  |       _cpp_function_cb_i_s[index]=nullptr; | ||||||
|  |       _cb_i_s_bitmap[index]=0; | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     // release a available cb_s_i_s_s function index
 | ||||||
|  |     int release_cb_s_i_s_s_index(int index){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_s_i_s_s_mutex); | ||||||
|  |       if(index<0||index>=_cb_s_i_s_s_bitmap.size()){ | ||||||
|  |         return -1; | ||||||
|  |       } | ||||||
|  |       _cpp_function_cb_s_i_s_s[index]=nullptr; | ||||||
|  |       _cb_s_i_s_s_bitmap[index]=0; | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     // release a available cb_s_i_s_s_i function index
 | ||||||
|  |     int release_cb_s_i_s_s_i_index(int index){ | ||||||
|  |       std::lock_guard<std::mutex> lock(_cb_s_i_s_s_i_mutex); | ||||||
|  |       if(index<0||index>=_cb_s_i_s_s_i_bitmap.size()){ | ||||||
|  |         return -1; | ||||||
|  |       } | ||||||
|  |       _cpp_function_cb_s_i_s_s_i[index]=nullptr; | ||||||
|  |       _cb_s_i_s_s_i_bitmap[index]=0; | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |   FuncPoolManager& instance=FuncPoolManager::get_instance(); | ||||||
|  | 
 | ||||||
|  |   // wrapper persistent function
 | ||||||
|  |   // wrapp CB_S,if function pool is full,return nullptr
 | ||||||
|  |   CB_S _wrapper_cpp_function(const std::function<void(const std::string&)>& cpp_function) { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_s_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_s_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_s[index]=cpp_function; | ||||||
|  |     return _fps_cb_s[index]; | ||||||
|  |   } | ||||||
|  |   // wrapp CB_I_S
 | ||||||
|  |   CB_I_S _wrapper_cpp_function(const std::function<void(int,const std::string&)>& cpp_function) | ||||||
|  |   { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_i_s_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_i_s_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_i_s[index]=cpp_function; | ||||||
|  |     return _fps_cb_i_s[index]; | ||||||
|  |   } | ||||||
|  |   // wrapp CB_S_I_S_S
 | ||||||
|  |   CB_S_I_S_S _wrapper_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&)>& cpp_function) | ||||||
|  |   { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_s_i_s_s[index]=cpp_function; | ||||||
|  |     return _fps_cb_s_i_s_s[index]; | ||||||
|  |   } | ||||||
|  |   // wrapp CB_S_I_S_S_I
 | ||||||
|  |   CB_S_I_S_S_I _wrapper_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&,int)>& cpp_function) | ||||||
|  |   { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_s_i_s_s_i[index]=cpp_function; | ||||||
|  |     return _fps_cb_s_i_s_s_i[index]; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // wrapp function to onetime function
 | ||||||
|  |   CB_S _wrapper_callonce_cpp_function(const std::function<void(const std::string&)>& cpp_function) { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_s_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_s_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_s[index]=[cpp_function,index](const std::string& str)->void { | ||||||
|  |       cpp_function(str); | ||||||
|  |       FuncPoolManager::get_instance().release_cb_s_index(index); | ||||||
|  |     }; | ||||||
|  |     return _fps_cb_s[index]; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   CB_I_S _wrapper_callonce_cpp_function(const std::function<void(int,const std::string&)>& cpp_function) | ||||||
|  |   { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_i_s_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_i_s_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_i_s[index]=[cpp_function,index](int code,const std::string& str)->void { | ||||||
|  |       cpp_function(code,str); | ||||||
|  |       FuncPoolManager::get_instance().release_cb_i_s_index(index); | ||||||
|  |     }; | ||||||
|  |     return _fps_cb_i_s[index]; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   CB_S_I_S_S _wrapper_callonce_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&)>& cpp_function) | ||||||
|  |   { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index(); | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_s_i_s_s[index]=[cpp_function,index](const std::string& operationID,int code,const std::string& str,const std::string& str2)->void { | ||||||
|  |       cpp_function(operationID,code,str,str2); | ||||||
|  |       FuncPoolManager::get_instance().release_cb_s_i_s_s_index(index); | ||||||
|  |     }; | ||||||
|  |     return _fps_cb_s_i_s_s[index]; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   CB_S_I_S_S_I _wrapper_callonce_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&,int)>& cpp_function) | ||||||
|  |   { | ||||||
|  |     int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index(); | ||||||
|  |     // while loop util get a available index
 | ||||||
|  |     while(index<0){ | ||||||
|  |       std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX)); | ||||||
|  |       index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index(); | ||||||
|  |     } | ||||||
|  |     _cpp_function_cb_s_i_s_s_i[index]=[cpp_function,index](const std::string& operationID,int code,const std::string& str,const std::string& str2,int c_int)->void { | ||||||
|  |       cpp_function(operationID,code,str,str2,c_int); | ||||||
|  |       FuncPoolManager::get_instance().release_cb_s_i_s_s_i_index(index); | ||||||
|  |     }; | ||||||
|  |     return _fps_cb_s_i_s_s_i[index]; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										40
									
								
								windows/src/common/stable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								windows/src/common/stable.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef STABLE_H | ||||||
|  | #define STABLE_H | ||||||
|  | 
 | ||||||
|  | #if defined __cplusplus | ||||||
|  | 
 | ||||||
|  | // std
 | ||||||
|  | #include <any> | ||||||
|  | #include <filesystem> | ||||||
|  | #include <functional> | ||||||
|  | #include <iostream> | ||||||
|  | #include <list> | ||||||
|  | #include <map> | ||||||
|  | #include <memory> | ||||||
|  | #include <mutex> | ||||||
|  | #include <optional> | ||||||
|  | #include <sstream> | ||||||
|  | #include <string> | ||||||
|  | #include <unordered_map> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef _WIN32 | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | #include "utils/singleton.h" | ||||||
|  | #include "utils/stringHash.hpp" | ||||||
|  | 
 | ||||||
|  | // third parties
 | ||||||
|  | #include "alog.h" | ||||||
|  | #define YXLOGEnd ALOGEnd | ||||||
|  | #define YXLOG(level) ALOG_DIY("nim_core_plugin", LogNormal, level) | ||||||
|  | #define YXLOG_API(level) ALOG_DIY("nim_core_plugin", LogApi, level) | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif  // STABLE_H
 | ||||||
							
								
								
									
										54
									
								
								windows/src/common/utils/singleton.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								windows/src/common/utils/singleton.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef BASE_SINGLETON_H_ | ||||||
|  | #define BASE_SINGLETON_H_ | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <mutex> | ||||||
|  | namespace utils { | ||||||
|  | template <typename T> | ||||||
|  | class Singleton { | ||||||
|  |  public: | ||||||
|  |   static T* getInstance(); | ||||||
|  | 
 | ||||||
|  |   Singleton(const Singleton& other) = delete; | ||||||
|  |   Singleton<T>& operator=(const Singleton& other) = delete; | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   static std::mutex mutex; | ||||||
|  |   static T* instance; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | std::mutex Singleton<T>::mutex; | ||||||
|  | template <typename T> | ||||||
|  | T* Singleton<T>::instance; | ||||||
|  | template <typename T> | ||||||
|  | T* Singleton<T>::getInstance() { | ||||||
|  |   if (instance == nullptr) { | ||||||
|  |     std::lock_guard<std::mutex> locker(mutex); | ||||||
|  |     if (instance == nullptr) { | ||||||
|  |       instance = new T(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return instance; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define SINGLETONG(Class)               \ | ||||||
|  |  private:                               \ | ||||||
|  |   friend class utils::Singleton<Class>; \ | ||||||
|  |                                         \ | ||||||
|  |  public:                                \ | ||||||
|  |   static Class* getInstance() { return utils::Singleton<Class>::getInstance(); } | ||||||
|  | 
 | ||||||
|  | #define HIDE_CONSTRUCTOR(Class)                  \ | ||||||
|  |  private:                                        \ | ||||||
|  |   Class() = default;                             \ | ||||||
|  |   Class(const Class& other) = delete;            \ | ||||||
|  |   Class& operator=(const Class& other) = delete; \ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | #endif  // BASE_SINGLETON_H_
 | ||||||
							
								
								
									
										35
									
								
								windows/src/common/utils/stringHash.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								windows/src/common/utils/stringHash.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef BASE_STRINGHASH_H_ | ||||||
|  | #define BASE_STRINGHASH_H_ | ||||||
|  | 
 | ||||||
|  | namespace utils { | ||||||
|  | typedef std::uint64_t hash_t; | ||||||
|  | 
 | ||||||
|  | constexpr hash_t prime = 0x100000001B3ull; | ||||||
|  | constexpr hash_t basis = 0xCBF29CE484222325ull; | ||||||
|  | 
 | ||||||
|  | inline hash_t hash_(char const* str) { | ||||||
|  |     hash_t ret{basis}; | ||||||
|  |     while (*str) { | ||||||
|  |         ret ^= *str; | ||||||
|  |         ret *= prime; | ||||||
|  |         str++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis) { | ||||||
|  |     return *str ? hash_compile_time(str + 1, (*str ^ last_value) * prime) : last_value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | }  // namespace utils
 | ||||||
|  | 
 | ||||||
|  | constexpr unsigned long long operator"" _hash(char const* p, size_t) { | ||||||
|  |     return utils::hash_compile_time(p); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif  // BASE_STRINGHASH_H_
 | ||||||
							
								
								
									
										87
									
								
								windows/third_party/alog/include/alog.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								windows/third_party/alog/include/alog.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef ALOGINSTANCE_H | ||||||
|  | #define ALOGINSTANCE_H | ||||||
|  | 
 | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) | ||||||
|  | #define API_EXPORT | ||||||
|  | #else | ||||||
|  | #ifdef ALOG_API | ||||||
|  | #define API_EXPORT __attribute__((visibility("default"))) | ||||||
|  | #else | ||||||
|  | #define API_EXPORT | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef enum { Debug = 1, Info, Warn, Error, Fatal } ALogLevel; | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |   LogNormal = 0, /**< 正常日志打印 */ | ||||||
|  |   LogApi         /**< API接口打印 */ | ||||||
|  | } ALogType; | ||||||
|  | 
 | ||||||
|  | #define ALOGEnd ALog::ALogEnd() | ||||||
|  | #define ALOG(level) ALog().Init("", __FILE__, __LINE__, LogNormal, level) | ||||||
|  | #define ALOG_DIY(moduleName, type, level) \ | ||||||
|  |   ALog().Init(moduleName, __FILE__, __LINE__, type, level) | ||||||
|  | 
 | ||||||
|  | class API_EXPORT ALog { | ||||||
|  |  public: | ||||||
|  |   class ALogEnd {}; | ||||||
|  | 
 | ||||||
|  |  public: | ||||||
|  |   ALog& Init(const char* module, const char* file, long line, ALogType type, | ||||||
|  |              ALogLevel level); | ||||||
|  |   ALog& operator<<(int value); | ||||||
|  |   ALog& operator<<(unsigned int value); | ||||||
|  |   ALog& operator<<(const std::string& value); | ||||||
|  |   ALog& operator<<(const char* value); | ||||||
|  |   ALog& operator<<(long long value); | ||||||
|  |   ALog& operator<<(unsigned long long value); | ||||||
|  |   ALog& operator<<(unsigned long value); | ||||||
|  |   ALog& operator<<(float value); | ||||||
|  |   ALog& operator<<(const unsigned char* value); | ||||||
|  |   ALog& operator<<(void* value); | ||||||
|  |   template <typename T> | ||||||
|  |   ALog& operator<<(T* value) { | ||||||
|  |     if (m_level >= m_minLevel) { | ||||||
|  |       char strTmp[128] = {0}; | ||||||
|  |       sprintf(strTmp, "%p", value); | ||||||
|  |       m_strLog.append(strTmp); | ||||||
|  |     } | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |   void operator<<(const ALog::ALogEnd& value); | ||||||
|  | 
 | ||||||
|  |  public: | ||||||
|  |   static ALog* CreateInstance(const std::string& filePath, | ||||||
|  |                               const std::string& fileName, ALogLevel minLevel); | ||||||
|  |   static ALog* GetInstance(); | ||||||
|  |   static void DestoryInstance(); | ||||||
|  |   ALog(); | ||||||
|  |   ~ALog(); | ||||||
|  |   void setShortFileName(bool shortFileName = false); | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   explicit ALog(const std::string& file, const std::string& fileName, | ||||||
|  |                 ALogLevel minLevel); | ||||||
|  |   void write(); | ||||||
|  | 
 | ||||||
|  |  private: | ||||||
|  |   static std::unique_ptr<ALog> m_log; | ||||||
|  |   static ALogLevel m_minLevel; | ||||||
|  |   static bool m_shortFileName; | ||||||
|  |   std::string m_strLog; | ||||||
|  |   std::string m_strModule; | ||||||
|  |   std::string m_strFile; | ||||||
|  |   long m_line = 0; | ||||||
|  |   ALogLevel m_level = Info; | ||||||
|  |   ALogType m_type = LogNormal; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif  // ALOGINSTANCE_H
 | ||||||
							
								
								
									
										14
									
								
								windows/third_party/alog/include/verinfo.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								windows/third_party/alog/include/verinfo.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | // Copyright (c) 2022 NetEase, Inc. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT license that can be
 | ||||||
|  | // found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | #ifndef ALog_verinfo_h | ||||||
|  | #define ALog_verinfo_h | ||||||
|  | 
 | ||||||
|  | #define ALOG_REVISION "cfe9ad8" | ||||||
|  | #define ALOG_PATH "wjzh/feature/cpp" | ||||||
|  | #define ALOG_URL "" | ||||||
|  | #define ALOG_BUILD_TIME "2021-09-30 13:22:13" | ||||||
|  | #define ALOG_TAG "" | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user