5 Commits 146049558c ... 29e9b17203

Author SHA1 Message Date
  Michael Buesch 29e9b17203 sources: On duplication also duplicate the hash, if it was enforced. 5 years ago
  Michael Buesch 00de8266e7 sources: Don't let the filename contribute to the hash 5 years ago
  Michael Buesch f26607884d gui/editwidget: Always make sure the hash is up to date 5 years ago
  Michael Buesch e6ade7da25 coreserver/msg: Integrate sources before sending 5 years ago
  Michael Buesch fea3549d7c coreclient: Do not reduce user timeout 5 years ago
4 changed files with 40 additions and 29 deletions
  1. 15 12
      awlsim/common/sources.py
  2. 14 8
      awlsim/coreclient/client.py
  3. 7 5
      awlsim/coreserver/messages.py
  4. 4 4
      awlsim/gui/editwidget.py

+ 15 - 12
awlsim/common/sources.py

@@ -193,6 +193,7 @@ class GenericSource(object):
 		self.volatile = volatile
 
 		self.__identHash = None
+		self.__identHashForced = False
 
 	@property
 	def name(self):
@@ -202,6 +203,7 @@ class GenericSource(object):
 	def name(self, newName):
 		self.__name = newName
 		self.__identHash = None
+		self.__identHashForced = False
 
 	@property
 	def enabled(self):
@@ -211,6 +213,7 @@ class GenericSource(object):
 	def enabled(self, enabled):
 		self.__enabled = bool(enabled)
 		self.__identHash = None
+		self.__identHashForced = False
 
 	@property
 	def volatile(self):
@@ -227,7 +230,6 @@ class GenericSource(object):
 	@filepath.setter
 	def filepath(self, newFilepath):
 		self.__filepath = newFilepath
-		self.__identHash = None
 
 	@property
 	def sourceBytes(self):
@@ -242,6 +244,7 @@ class GenericSource(object):
 		"""
 		self.__sourceBytes = newSourceBytes
 		self.__identHash = None
+		self.__identHashForced = False
 
 	@property
 	def compatSourceBytes(self):
@@ -287,11 +290,6 @@ class GenericSource(object):
 				bd.append(b'1')
 				bd.append(self.name.encode(self.ENCODING, "ignore"))
 			bd.append(b'1' if self.enabled else b'0')
-			if self.filepath:
-				bd.append(b'1')
-				bd.append(self.filepath.encode(self.ENCODING, "ignore"))
-			else:
-				bd.append(b'0')
 			bd.append(self.sourceBytes)
 			identHash = self.__identHash = self.IDENT_HASH(b'|'.join(bd)).digest()
 		return identHash
@@ -300,6 +298,7 @@ class GenericSource(object):
 	def identHash(self, identHash):
 		# Force the ident hash.
 		self.__identHash = identHash
+		self.__identHashForced = True
 
 	@property
 	def identHashStr(self):
@@ -373,12 +372,16 @@ class GenericSource(object):
 	def dup(self):
 		"""Duplicate this source. Returns a copy.
 		"""
-		return self.__class__(name=self.name,
-				      enabled=self.enabled,
-				      filepath=self.filepath,
-				      sourceBytes=self.sourceBytes[:],
-				      userData=self.userData,
-				      volatile=self.volatile)
+		new = self.__class__(name=self.name,
+				     enabled=self.enabled,
+				     filepath=self.filepath,
+				     sourceBytes=self.sourceBytes[:],
+				     userData=self.userData,
+				     volatile=self.volatile)
+		if self.__identHashForced:
+			# identHash has been forced. Copy that, too.
+			new.identHash = self.identHash
+		return new
 
 	def copyFrom(self, other,
 		     copyName=True,

+ 14 - 8
awlsim/coreclient/client.py

@@ -429,14 +429,16 @@ class AwlSimClient(object):
 				 str(e), str(e.errno)))
 
 	def __sendAndWait(self, txMsg, checkRxMsg,
-			  waitTimeout=None,
+			  minTimeout=None,
 			  ignoreMaintenanceRequests=False):
 		waiter = MsgWaiter(checkRxMsg)
 		self.__msgWaiters.append(waiter)
 		try:
 			self.__send(txMsg)
 			now = monotonic_time()
-			timeout = self.__defaultTimeout if waitTimeout is None else waitTimeout
+			timeout = self.__defaultTimeout
+			if minTimeout is not None:
+				timeout = max(timeout, minTimeout)
 			timeout *= self.__timeoutFactor
 			end = now + timeout
 			while now < end:
@@ -452,13 +454,17 @@ class AwlSimClient(object):
 		finally:
 			self.__msgWaiters.remove(waiter)
 
-	def __sendAndWaitFor_REPLY(self, msg, timeout=None,
+	def __sendAndWaitFor_REPLY(self, msg,
+				   minTimeout=None,
 				   ignoreMaintenanceRequests=False):
 		def checkRxMsg(rxMsg):
 			return (rxMsg.msgId == AwlSimMessage.MSG_ID_REPLY and
 				rxMsg.isReplyTo(msg))
-		return self.__sendAndWait(msg, checkRxMsg, timeout,
-					  ignoreMaintenanceRequests).status
+		waiter = self.__sendAndWait(txMsg=msg,
+					    checkRxMsg=checkRxMsg,
+					    minTimeout=minTimeout,
+					    ignoreMaintenanceRequests=ignoreMaintenanceRequests)
+		return waiter.status
 
 	def reset(self):
 		if not self.__transceiver:
@@ -514,7 +520,7 @@ class AwlSimClient(object):
 		msg = AwlSimMessage_AWLSRC(awlSource)
 		self.__transceiver.txCork(True)
 		try:
-			status = self.__sendAndWaitFor_REPLY(msg, 10.0)
+			status = self.__sendAndWaitFor_REPLY(msg, minTimeout=10.0)
 		finally:
 			self.__transceiver.txCork(False)
 		if status != AwlSimMessage_REPLY.STAT_OK:
@@ -527,7 +533,7 @@ class AwlSimClient(object):
 		msg = AwlSimMessage_FUPSRC(fupSource)
 		self.__transceiver.txCork(True)
 		try:
-			status = self.__sendAndWaitFor_REPLY(msg, 10.0)
+			status = self.__sendAndWaitFor_REPLY(msg, minTimeout=10.0)
 		finally:
 			self.__transceiver.txCork(False)
 		if status != AwlSimMessage_REPLY.STAT_OK:
@@ -540,7 +546,7 @@ class AwlSimClient(object):
 		msg = AwlSimMessage_KOPSRC(kopSource)
 		self.__transceiver.txCork(True)
 		try:
-			status = self.__sendAndWaitFor_REPLY(msg, 10.0)
+			status = self.__sendAndWaitFor_REPLY(msg, minTimeout=10.0)
 		finally:
 			self.__transceiver.txCork(False)
 		if status != AwlSimMessage_REPLY.STAT_OK:

+ 7 - 5
awlsim/coreserver/messages.py

@@ -428,7 +428,6 @@ class _AwlSimMessage_source(AwlSimMessage):
 	#	reserved (32 bit)
 	#	reserved (32 bit)
 	#	sourceName (string)
-	#	sourceFilePath (string)
 	#	sourceBytes (bytes)
 	plStruct = struct.Struct(str(">IIIIIIII"))
 
@@ -438,6 +437,13 @@ class _AwlSimMessage_source(AwlSimMessage):
 	def __init__(self, source):
 		if not source:
 			source = self.sourceClass()
+		# If the source it file-backed, integrate it.
+		# Otherwise the source data will not be sent.
+		if source.isFileBacked():
+			source = source.dup()
+			source.forceNonFileBacked(source.name)
+		else:
+			source = source.dup()
 		self.source = source
 
 	def toBytes(self):
@@ -449,7 +455,6 @@ class _AwlSimMessage_source(AwlSimMessage):
 				flags |= self.FLAG_VOLATILE
 			pl = self.plStruct.pack(flags, 0, 0, 0, 0, 0, 0, 0) +\
 				self.packString(self.source.name) +\
-				self.packString(self.source.filepath) +\
 				self.packBytes(self.source.sourceBytes)
 			return AwlSimMessage.toBytes(self, len(pl)) + pl
 		except ValueError:
@@ -464,15 +469,12 @@ class _AwlSimMessage_source(AwlSimMessage):
 			offset += cls.plStruct.size
 			name, cnt = cls.unpackString(payload, offset)
 			offset += cnt
-			filepath, cnt = cls.unpackString(payload, offset)
-			offset += cnt
 			sourceBytes, cnt = cls.unpackBytes(payload, offset)
 		except (ValueError, struct.error) as e:
 			raise TransferError("SOURCE: Data format error")
 		return cls(cls.sourceClass(name=name,
 					   enabled=(flags & cls.FLAG_ENABLED),
 					   volatile=(flags & cls.FLAG_VOLATILE),
-					   filepath=filepath,
 					   sourceBytes=sourceBytes))
 
 class AwlSimMessage_GET_SYMTABSRC(_AwlSimMessage_GET_source):

+ 4 - 4
awlsim/gui/editwidget.py

@@ -433,9 +433,6 @@ class EditWidget(SourceCodeEdit):
 			"Did you know\n" + random.choice(self.__didYouKnow)
 		)
 
-	def getSourceId(self):
-		return self.__source.identHash
-
 	def shutdown(self):
 		pass
 
@@ -481,6 +478,9 @@ class EditWidget(SourceCodeEdit):
 			self.__updateSource()
 		return self.__source
 
+	def getSourceId(self):
+		return self.getSource().identHash
+
 	def setSettings(self, guiSettings):
 		self.enableAutoIndent(guiSettings.getEditorAutoIndentEn())
 		self.enablePasteIndent(guiSettings.getEditorPasteIndentEn())
@@ -646,7 +646,7 @@ class EditWidget(SourceCodeEdit):
 		if self.__runState == RunState.STATE_RUN:
 			cpuHashes = [ s.identHash for s in identsMsg.awlSources ]
 			self.__setSourceMatchesCpuSource(
-				self.getSource().identHash in cpuHashes)
+				self.getSourceId() in cpuHashes)
 		else:
 			# The CPU is not in RUN state.
 			# We don't make a big deal out of code mismatch.