you probably don’t understand the idea. you don’t have to stop the timer (i stop it just for the sample).
allocate some common memory for write and read (executable buffer)
backgroundworker listens a socket, reads data, makes executable string, and when the buffer can be overwritten puts the string there
timer runs all the time and waits for some flag that says the new data was received, sets flag – do not write (or temporally stops the worker), executes the buffer, resets flags.
that’s a scenario. but of course there might be a smarter solution
What do you suggest, I should use timer or background worker.
Besides, socket, is there any other way of sending MXS externally.
i don’t know what your external program does do in max, and how busy it makes. where does this external program run (same or other than max machine)?
maybe it’s easy to read and write some common file using the FileSystemWatcher for synchronization for example.
I have attached the source files in my 4th post (exe, exe source, ms)
http://forums.cgsociety.org/showpost.php?p=7475446&postcount=4
It runs on same machine and it just sends MXS commands to 3dsmax.
When I can create a box and delete it also with this profram, then it should open rollouts/dialogs too. It freezes as soon as any custom rollout pops up. But if I send destroydialog, then the max ui comes back.
you don’t answer my question. what the program will do? is the only thing that you want is to type mxs scripts in an external program and to run it in max? i didn’t run your EXE file and probably will not. so try to explain your idea a little clear.
Actually we’ve built a program for Maya few years back and still using it in our production env. This program automates most of the tasks and generate reports for various depts. It has multiple modules and its a great tracker. It also provides realtime status of any project, any file. It also controls Maya interface and sends mel scripts to it for specific tasks like doing playblast(preview) in a specified format, baking exporting camera, so on and so forth. It also controls naming convention as all the naming tasks are done by our program.
This program connects to maya through its inbuilt port (command port).
There is nothing like this in 3dsmax.
I want to automate 3dsmax functions just like we do with maya. Inside 3dsmax, we can run mxs, no issues, but we need to run mxs externally.
tt = dotnetobject "System.Windows.Forms.Timer"
tt.Interval = 1000
fn makeRollout s e =
(
rollout rol "From Timer" width:200
(
button bt "Button" pos:[4,4] width:190
)
createDialog rol
s.Stop()
)
dotnet.addEventHandler tt "Tick" makeRollout
tt.Start()
fn DoWork =
(
tt.Start()
)
BackgroundWorker = dotnetobject "CSharpUtilities.SynchronizingBackgroundWorker"
BackgroundWorker.WorkerSupportsCancellation = on
dotNet.addEventHandler BackgroundWorker "DoWork" DoWork
if not BackgroundWorker.isBusy do BackgroundWorker.RunWorkerAsync()
BackgroundWorker.Dispose()
global theString=""
Fn BackgroundTcpListenerDoWork theSender theEvent =
(
IPAddress = DotNetClass "System.Net.IPAddress"
theIPAddress = IPAddress.Parse "127.0.0.1"
theTcpListener = DotNetObject "System.Net.Sockets.TcpListener" theIPAddress 7500
theTcpListener.Start()
theSocket = theTcpListener.AcceptSocket()
while theString!="exit" do
(
theByteStream = DotNetObject "System.Byte[]" 10000
theSocket.Receive theByteStream
Encoding = DotnetClass "System.Text.Encoding"
theString = trimright (Encoding.UTF8.GetString(theByteStream))
)
theTcpListener.Stop()
theSocket.Close()
tt.stop()
)
BackgroundWorker = DotNetObject "System.ComponentModel.BackgroundWorker"
DotNet.AddEventHandler BackgroundWorker "DoWork" BackgroundTcpListenerDoWork
BackgroundWorker.WorkerSupportsCancellation = true
BackgroundWorker.RunWorkerAsync()
tt = dotnetobject "System.Windows.Forms.Timer"
tt.Interval = 1000
fn makeRollout s e =
(
if theString!="" do (try(execute theString;theString="" )catch(print "Error Occured!") )
)
dotnet.addEventHandler tt "Tick" makeRollout
tt.Start()
Wrote this, seems to work, at least no freezing max UI.
I’ll check your code also.
that’s exactly my plan #A. but my last sample is better. it doesn’t need all time running timer.
global theString=""
tt = dotnetobject "System.Windows.Forms.Timer"
tt.Interval = 1000
Fn BackgroundTcpListenerDoWork s e =
(
IPAddress = DotNetClass "System.Net.IPAddress"
theIPAddress = IPAddress.Parse "127.0.0.1"
theTcpListener = DotNetObject "System.Net.Sockets.TcpListener" theIPAddress 7500
theTcpListener.Start()
theSocket = theTcpListener.AcceptSocket()
while theString!="exit" do
(
theByteStream = DotNetObject "System.Byte[]" 10000
theSocket.Receive theByteStream
Encoding = DotnetClass "System.Text.Encoding"
theString = trimright (Encoding.UTF8.GetString(theByteStream))
if theString!="" do (try(execute theString;theString="" )catch(print "Error Occured!") )
)
theTcpListener.Stop()
theSocket.Close()
s.stop()
)
dotnet.addEventHandler tt "Tick" BackgroundTcpListenerDoWork
tt.Start()
fn DoWork =
(
tt.Start()
)
BackgroundWorker = dotnetobject "CSharpUtilities.SynchronizingBackgroundWorker"
BackgroundWorker.WorkerSupportsCancellation = on
dotNet.addEventHandler BackgroundWorker "DoWork" DoWork
if not BackgroundWorker.isBusy do BackgroundWorker.RunWorkerAsync()
BackgroundWorker.Dispose()
Again Freezing!
I’ll study what you posted today and will reply once I make something out of it for me.