你有种再说一遍 发表于 2024-4-10 04:49:49

魔改系统-7角色扮演实现协同办公

本帖最后由 你有种再说一遍 于 2024-4-12 07:10 编辑


继前几篇铺垫之后,大家已经了解了多线程读写dwg了,今天就用之前的知识实现一个难度极低的角色协同功能.Revit的角色设定能够让不同的人修改同一份模型,起码原理上面没有问题.


有人想问:"为什么要一起改一份图啊,分开画不就好了?"其实这没有什么原因,就是喜欢在画图时候看到全局修改,并且能够实现管线和结构的冲突检测这类功能.


我们需要把自己切换到一次开发者思维上面,这样任何绕不过的坎都可以绕过,并且要绕到一个实现最简单和性能最佳的方法上面.
我不否认以下方案令你失望,因为这毕竟非常适合浩辰,中望,梦想,天正公司的实现,它不是二次开发希望的简而美.
为什么要引入如此复杂的行为呢?
因为我要充分利用现代多核心CPU的发展方向上面,而不是仅仅利用CPU的IPC.单线程数据库通过读写分离可以解决读取瓶颈,而写入瓶颈就是多人分别写入实现.并且可能的话,全部命令都需要改为MapReduce方式.


方案一:
大家一起修改同一个dwg好不好?
答案是不好.先不说cad单线程写入让你插入容易回滚难,光是插着插着引起致命错误你就受不了了.虽然消息队列是可以保存不至于丢失其他角色输入,但是dwg始终不是多线程事务,为了撤回图元(实际上就是删除图元)还得自己做一套事务规则,有点得不偿失.


方案二:
用外部参照代替好不好?
答案是虽然可以但不做,更新时候需要反复载入,这个操作会阻塞用户,它太慢了,无助于我们优化性能.


方案三:
如果用一个多线程数据库,字段里面含有权限,这样并发读写你就只会进入特定角色的索引控制上面.
这样操控性比dwg自由太多了,cad仅仅是提供数据转换的功能,数据库还可以实现增量备份,数据回放等等.缺点是这样不光要完全重构一份显示,还得重构一份数据库.




实现:
既然方案三才是最好的,但是它实现过于复杂了,我们可以仅仅需要显示异步,而不是再构造数据库.
那有什么很快的呢?那就是绕过数据库,直接显示在屏幕上面,所以我们需要利用GDI重绘全部图元,自行实现缓存...(觉得复杂?那就对了,毕竟你低估了我对解决方案的完整性和高性能追求,如果常规二次开发解决不了,那就造火箭,改成系统化工程)
这样我们才能保存dwg文件的时候,通过多线程异步分析增量部分并发送修改部分给其他角色,其他角色可以异步自动刷新(也可以配置关闭).
分析增量只需要订阅数据库图元添加和图元修改事件,并过滤非绘制部分.
那么怎么实现GDI画图呢?万能的OpenGL呀.
系统学习的完整流程:
https://zhuanlan.zhihu.com/p/56693625
c#相关的库:
https://www.cnblogs.com/bitzhuwei/p/CSharpGL-an-easy-to-learn-and-easy-to-use-OpenGL-library-in-csharp.html
其核心就是用一层透明叠层的form画图展示,你还需要实现同步鼠标滚动,shift+中键进行三维摄像机切换等等,我不觉得是什么难事,只是需要庞大的测试.


缺点是c#无法支持自定义图元显示.


多个角色想必每个图元都具备角色权限标记,这个太麻烦了,需要大量xdata,并且每个命令都要拦截命令进行角色判断(当然自定义图元没有这个苦恼).
所以我们反其道而行之,通过在项目文件夹下面创建不同的文件夹表示各种角色,然后每个文件夹内放多个dwg,也就是每份图纸打开都会载入非本图的剩余模型进行虚拟显示.这样每个dwg内都是最高权限,减少图元数据,还实现了分布式储存.


跨角色权限修改图元并发送通知:
说实话这个才是最难的,需要利用长事务的方式进行.
因为我们显示缓存区是不具备原始信息的,例如组块的块表记录信息,这说明修改时候还得全量载入,这样会卡一下...(为了解决卡,可能考虑后台异步开启只读图纸,编辑时候切换,毕竟内存没有那么值钱了)
模拟在位编辑,实现编辑保存:跨角色编辑的时候,全部图元载入到一个集合中,并且打开一个标记控制数据库添加事件,事件将用户任何画图元都会加入这个集合,在保存退出时,和原始对比差异之后,选择差异部分发送修改给原始角色...删除本角色这个集合图元,关闭标记,更新虚拟显示.
发送给原始角色需要通过消息队列进行,因为这是一个异步操作,你无需关心对方是否接受你的修改,只需要更新自己的当前显示.被对方角色否决的话,说明存在冲突,对方会连同修改意见一同回复,此时你仅需更新显示.


图元捕捉功能:
因为显示缓存区(载入的虚拟显示)虽然不在dwg数据库,但是可以通过构造四叉树获取鼠标最近图元,计算图元夹点/圆心/切点等等实现捕捉.


这是一种最简化的概念还有很多不完善的地方.
缺少权限隔离,没有做到临时显示,重复载入的缓冲复用,版本控制等等.核心就是重绘图元,这个时候就有很多优化策略了,例如定点数优化文字渲染...

panliang9 发表于 2024-4-10 09:41:45

很多人同时画一份图,我以前和同事尝试过很简单,使用插入的办法。
就是需要时不时刷新一下。
以前的讨论贴:
http://bbs.mjtd.com/thread-86378-1-1.html

如果能很多人同时开工,配合讨论组,就象玩游戏一样的,应该不难实现。

liuhe 发表于 2024-4-10 14:06:20

panliang9 发表于 2024-4-10 09:41
很多人同时画一份图,我以前和同事尝试过很简单,使用插入的办法。
就是需要时不时刷新一下。
以前的讨论 ...

游戏角色可以相互干扰的道具类型不多吧
页: [1]
查看完整版本: 魔改系统-7角色扮演实现协同办公